SpringMVC数据绑定与表单标签库

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC数据绑定与表单标签库相关的知识,希望对你有一定的参考价值。

SpringMVC数据绑定与表单标签库

数据绑定是将用户参数输入值绑定到领域模型的一种特性。
数据绑定的优点主要有两点:
第一,不再需要将HTTP请求中的String类型转换成模型所需的类型。
第二,当输入的验证失败时会重新生成一个html表单,无需重新填写输入字段。
在SpringMVC中,为了方便高效地使用数据绑定,还需使用表单标签库。
在SpringMVC中数据绑定有这样几层含义:绑定请求参数输入值到领域模型;模型数据到视图的绑定(输入验证失败时);模型数据到表单元素的绑定(如选项值被控制器初始化)

表单标签库包含了可以用在JSP页面渲染HTML元素的标签,在JSP页面使用Spring标签库时,必须在JSP页面开头处声明taglib指令。
在表单标签库有form,input,password,hidden,textarea,checkbox,checkboxes,radiobutton,radiobuttons,select,option,options,errors等标签。

数据绑定的应用,在应用中实现了User类属性和JSP页面中表单参数的绑定,同时在JSP页面分别展示了input,textarea,checkbox,checkboxs,select等标签。

1-在IDEA中创建名为ch12-1的web应用,在该web应用的WEB-INF下创建目录lib,在该目录中导入Spring的核心包和依赖包,SpringMVC的核心包,同时需要将Tomcat的Webapps\\examples\\WEB-INF\\lib目录下的JSTL相关的jar包复制到应用的WEB-INF/lib目录下。

2-在web.xml中部署dispatcherServlet,在该配置文件中配置CharacterEncodingFilter解决中文乱码问题。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         id = "WebApp_ID" version="4.0">
    <!--部署DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <!--表示容器启动时加载的servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--任意的请求都通过DispatcherServlet-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置 CharacterEncodingFilter解决中文乱码问题-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <!-- 配置编码格式为UTF-8 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

3-在WEB-INF目录下创建SpringMVC核心配置文件,在该配置文件中扫描指定的包,配置视图解析器,解析视图路径。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--使用扫描机制,扫描控制器类-->
    <context:component-scan base-package="controller"/>
    <context:component-scan base-package="service"/>
    <mvc:annotation-driven />
    <!--annotation-driven用于简化开发的配置,注解DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter-->
    <!--使用resources过滤掉不需要dispatcherservlet的资源,例如静态资源,在使用resources时必须使用annotation-driven,否则resources会阻止任意控制器被调用-->
    <mvc:default-servlet-handler/>
    <!--配置视图解析器-->
    <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" id = "internalResourceViewResolver">
        <!--前缀-->
        <property name = "prefix" value = "/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name = "suffix" value = ".jsp"/>
    </bean>
</beans>

4-应用中实现了User类属性和JSP页面中表单参数的绑定,User类包含了和表单参数名对应的属性,以及get和set方法.
在src目录下创建pojo包,在该包中创建User类

/**
 * 应用中实现了User类属性和JSP页面中表单参数的绑定
 * User类包含了和表单参数名对应的属性,以及属性的set和get方法
 */
public class User {
    private String userName ; //用户名
    private String [] hobby ; //爱好
    private String [] friends ; //朋友
    private String career ; //事业
    private String houseRegister ; //户籍
    private String remark ; //个人描述

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String[] getHobby() {
        return hobby;
    }

    public void setHobby(String[] hobby) {
        this.hobby = hobby;
    }

    public String[] getFriends() {
        return friends;
    }

    public void setFriends(String[] friends) {
        this.friends = friends;
    }

    public String getCareer() {
        return career;
    }

    public void setCareer(String career) {
        this.career = career;
    }

    public String getHouseRegister() {
        return houseRegister;
    }

    public void setHouseRegister(String houseRegister) {
        this.houseRegister = houseRegister;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }
}

5-该应用中使用Service层,在Service层使用静态集合变量users模拟数据库存储用户信息,包括添加用户和查询用户两个功能方法,在src目录下创建service包,并在该包中创建UserService接口和UserServiceImpl实现类。

UserService接口:

import pojo.User;

import java.util.ArrayList;

public interface UserService {
    boolean addUser(User user) ; //添加用户的方法
    ArrayList<User> getUsers() ; //查找用户的方法
}

UserServiceImpl类:


import org.springframework.stereotype.Service;
import pojo.User;

import java.util.ArrayList;
@Service
public class UserServiceImpl implements UserService {
    //使用静态集合变量模拟数据库存储用户信息
    private static ArrayList<User> users = new ArrayList<>() ;
    @Override
    public boolean addUser(User user) {
        if(!"IT民工".equals(user.getCareer())){ //不是IT民工则可以添加,否则不可以添加
            users.add(user) ;
            return true ;
        }
        return false;
    }

    @Override
    public ArrayList<User> getUsers() {
        return users;
    }
}

6-在Controller类UserConntroller中定义了请求处理方法,包括处理user/input请求的inputUser方法,处理user/save请求的addUser方法,其中addUser方法中用到了重定向,在UserController类中,通过@Autowired注解在UserController对象中注入UserService对象,实现对user对象的添加和查询操作,通过Model对象的addAttribute方法将各个类型的对象传递给View。
在src目录下创建controller包,在该包中创建控制器类UserController.

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import pojo.User;
import service.UserService;

import java.util.HashMap;
import java.util.List;

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService ;
    //得到一个用来记录日志记录的对象,这样在打印信息时候就能标记是打哪个类的信息
    private static final Log logger = LogFactory.getLog(UserController.class) ;
    @RequestMapping("/input")
    public String inputUser(Model model){
        HashMap<String,String> hobbys = new HashMap<>() ;
        hobbys.put("篮球","篮球") ;
        hobbys.put("羽毛球","羽毛球") ;
        hobbys.put("乒乓球","乒乓球") ;
        hobbys.put("游泳","游泳") ;
        model.addAttribute("user", new User()) ;
        model.addAttribute("hobbys", hobbys) ;
        model.addAttribute("careers" , new String [] {"教师", "学生", "码农", "IT民工", "医生","其它"}) ;
        model.addAttribute("houseRegisters", new String [] {"北京", "上海", "南京", "南昌", "其它"}) ;
        return "userAdd" ;
    }
    //使用ModelAttribute接收请求参数
    @RequestMapping("/save")
     public String addUser(@ModelAttribute User user, Model model){
        if(userService.addUser(user)){
            logger.info("添加成功") ;
            return "redirect:/user/list" ;
        }else{
            logger.info("添加失败") ;
            HashMap<String,String> hobbys = new HashMap<String,String>() ;
            hobbys.put("篮球","篮球") ;
            hobbys.put("羽毛球","羽毛球") ;
            hobbys.put("乒乓球","乒乓球") ;
            hobbys.put("游泳","游泳") ;
            //这里不需要 model.addAttribute("user", new User()) ;因为@ModelAttribute指定表单返回对象
            model.addAttribute("hobbys", hobbys) ;
            model.addAttribute("careers" , new String [] {"教师", "学生", "码农", "IT民工", "医生","其它"}) ;
            model.addAttribute("houseRegisters", new String [] {"北京", "上海", "南京", "南昌", "其它"}) ;
            return "userAdd" ;
        }
     }
     @RequestMapping("/list")
     public String listUsers(Model model){
         List<User> users = userService.getUsers() ;
         model.addAttribute("users", users) ;
         return "userList" ;
     }
}

7-View层有2个JSP页面,一个信息输入页面userAdd.jsp,一个信息显示页面userList.jsp。在WEB-INF目录下创建jsp目录,在jsp目录下创建两个页面。

userAdd.jsp:

<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/8/9
  Time: 11:21
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=utf-8"
         pageEncoding="utf-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Insert title here</title>
</head>
<body>
<form:form modelAttribute = "user" method = "post" action = "${pageContext.request.contextPath}/user/save">
    <fieldset>
        <legend>添加一个用户</legend>
        <p>
            <label>用户名:</label>
            <form:input path = "userName"/>
        </p>
        <p>
            <label>爱好:</label>
            <form:checkboxes items = "${hobbys}" path = "hobby"/>
        </p>
        <p>
            <label>朋友:</label>
            <form:checkbox path = "friends" value = "张珂珂"/>张珂珂
            <form:checkbox path = "friends" value = "崔丽华"/>崔丽华
            <form:checkbox path = "friends" value = "张燕娜"/>张燕那
            <form:checkbox path = "friends" value = "齐超"/>齐超
        </p>
        <p>
            <label>职业:</label>
            <form:select path = "career">
                <option/>请选择职业
                <form:options items = "${careers}"/>
            </form:select> >
        </p>
        <p>
            <label>户籍:</label>
            <form:select path = "houseRegister">
                <options/>请选择户籍信息
                <form:options items = "${houseRegisters}"/>
            </form:select>
        </以上是关于SpringMVC数据绑定与表单标签库的主要内容,如果未能解决你的问题,请参考以下文章

spring表单标签

Form标签表单回显与提交

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20

SpringMVC表单标签&处理静态资源

关于SpringMVC的几件小事

弹簧数据绑定标签形式没有必要吗?