数据绑定是将用户参数输入值绑定到领域模型的一种特性。在Spring MVC的Controller和View参数数据传递中,所有HTTP请求参数的类型均为字符串。如果模型需要绑定的类型为double或int,则需要手动进行类型转换。而有了数据绑定后,就不再需要手动将HTTP请求中String类型转换为模型需要的类型。数据绑定的另一个好处是,当输入验证失败时,会重新生成一个HTML表单,无需重新填入输入字段
在Spring MVC中,为了方便 高效的使用数据绑定,还需要学习表单标签库
表单标签库中包含可以用在JSP页面中渲染HTML元素的标签,JSP页面使用Spring表单标签库时,必须在JSP页面开头处声明taglib指令 代码如下
<%taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
表单包含元素如下

在src目录下创建名为config的包 并创建WebConfig和SpringMVCConfig配置类
Webconfig代码如下
- package config;
- import javax.servlet.ServletContext;
- import javax.servlet.ServletException;
- import org.springframework.web.WebApplicationInitializer;
- import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
- import org.springframework.web.filter.CharacterEncodingFilter;
- import org.springframework.web.servlet.DispatcherServlet;
- public class WebConfig implements WebApplicationInitializer{
- @Override
- public void onStartup(ServletContext arg0) throws ServletException {
- AnnotationConfigWebApplicationContext ctx
- = new AnnotationConfigWebApplicationContext();
- ctx.register(SpringMVCConfig.class);//注册Spring MVC的Java配置类SpringMVCConfig
- ctx.setServletContext(arg0);//和当前ServletContext关联
- /**
- * 注册Spring MVC的DispatcherServlet
- */
- javax.servlet.ServletRegistration.Dynamic servlet =
- arg0.addServlet("dispatcher", new DispatcherServlet(ctx));
- servlet.addMapping("/");
- servlet.setLoadOnStartup(1);
- /**
- * 注册字符编码过滤器
- */
- javax.servlet.FilterRegistration.Dynamic filter =
- arg0.addFilter("characterEncodingFilter", CharacterEncodingFilter.class);
- filter.setInitParameter("encoding", "UTF-8");
- filter.addMappingForUrlPatterns(null, false, "/*");
- }
- }
SpringMVCConfig代码如下
- package config;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.ComponentScan;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.servlet.config.annotation.EnableWebMvc;
- import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
- import org.springframework.web.servlet.view.InternalResourceViewResolver;
- @Configuration
- @EnableWebMvc
- @ComponentScan(basePackages = {"controller","service"})
- public class SpringMVCConfig implements WebMvcConfigurer {
- /**
- * 配置视图解析器
- */
- @Bean
- public InternalResourceViewResolver getViewResolver() {
- InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
- viewResolver.setPrefix("/WEB-INF/jsp/");
- viewResolver.setSuffix(".jsp");
- return viewResolver;
- }
- /**
- * 配置静态资源
- */
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/html/**").addResourceLocations("/html/");
- //addResourceHandler指的是对外暴露的访问路径
- //addResourceLocations指的是静态资源存放的位置
- }
- }
包含两个JSP页面 一个是信息输入页面userAdd.jsp 一个是信息显示页面userList.jsp
userAdd.jsp代码如下
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
- <!DOCTYPE html>
- <html>
- <head>
- <meta 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="carrer">
- <option/>请选择职业
- <form:options items="${carrers }"/>
- </form:select>
- </p>
- <p>
- <label>户籍:</label>
- <form:select path="houseRegister">
- <option/>请选择户籍
- <form:options items="${houseRegisters }"/>
- </form:select>
- </p>
- <p>
- <label>个人描述:</label>
- <form:textarea path="remark" rows="5"/>
- </p>
- <p id="buttons">
- <input id="reset" type="reset">
- <input id="submit" type="submit" value="添加">
- </p>
- </fieldset>
- </form:form>
- </body>
- </html>
userList.jsp代码如下
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>Insert title here</title>
- </head>
- <body>
- <h1>用户列表</h1>
- <a href="
/ user/input"/>">继续添加</a> - <table>
- <tr>
- <th>用户名</th>
- <th>兴趣爱好</th>
- <th>朋友</th>
- <th>职业</th>
- <th>户籍</th>
- <th>个人描述</th>
- </tr>
- <!-- JSTL标签,请参考本书的相关内容 -->
- <c:forEach items="${users}" var="user">
- <tr>
- <td>${user.userName }</td>
- <td>
- <c:forEach items="${user.hobby }" var="hobby">
- ${hobby }
- </c:forEach>
- </td>
- <td>
- <c:forEach items="${user.friends }" var="friend">
- ${friend }
- </c:forEach>
- </td>
- <td>${user.carrer }</td>
- <td>${user.houseRegister }</td>
- <td>${user.remark }</td>
- </tr>
- </c:forEach>
- </table>
- </body>
- </html>
在src目录下创建pojo包 并创建User类
- package pojo;
-
- public class User {
- private String userName;
- private String[] hobby;//兴趣爱好
- private String[] friends;//朋友
- private String carrer;
- 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 getCarrer() {
- return carrer;
- }
- public void setCarrer(String carrer) {
- this.carrer = carrer;
- }
- 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;
- }
- }
Service层使用静态集合变量users模拟数据库存储用户信息,包括添加用户和查询用户两个功能
UserService接口类代码如下
- package service;
- import java.util.ArrayList;
- import pojo.User;
- public interface UserService {
- boolean addUser(User u);
- ArrayList
getUsers(); - }
UserServiceImpl实现类代码如下
- package service;
- import java.util.ArrayList;
- import org.springframework.stereotype.Service;
- import pojo.User;
- @Service
- public class UserServiceImpl implements UserService{
- //使用静态集合变量users模拟数据库
- private static ArrayList
users = new ArrayList(); - @Override
- public boolean addUser(User u) {
- if(!"IT民工".equals(u.getCarrer())){//不允许添加IT民工
- users.add(u);
- return true;
- }
- return false;
- }
- @Override
- public ArrayList
getUsers() { - return users;
- }
- }
在Controller类的UserController中定义了请求处理方法 代码如下
- package controller;
- import java.util.HashMap;
- import java.util.List;
- 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;
- @Controller
- @RequestMapping("/user")
- public class UserController {
- // 得到一个用来记录日志的对象,这样打印信息的时候能够标记打印的是那个类的信息
- private static final Log logger = LogFactory.getLog(UserController.class);
- @Autowired
- private UserService userService;
- @RequestMapping(value = "/input")
- public String inputUser(Model model) {
- HashMap<String, String> hobbys = new HashMap<String, String>();
- hobbys.put("篮球", "篮球");
- hobbys.put("乒乓球", "乒乓球");
- hobbys.put("电玩", "电玩");
- hobbys.put("游泳", "游泳");
- // 如果model中没有user属性,userAdd.jsp会抛出异常,因为表单标签无法找到
- // modelAttribute属性指定的form backing object
- model.addAttribute("user", new User());
- model.addAttribute("hobbys", hobbys);
- model.addAttribute("carrers", new String[] { "教师", "学生", "coding搬运工", "IT民工", "其它" });
- model.addAttribute("houseRegisters", new String[] { "北京", "上海", "广州", "深圳", "其它" });
- return "userAdd";
- }
- @RequestMapping(value = "/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指定form backing object
- model.addAttribute("hobbys", hobbys);
- model.addAttribute("carrers", new String[] { "教师", "学生", "coding搬运工", "IT民工", "其它" });
- model.addAttribute("houseRegisters", new String[] { "北京", "上海", "广州", "深圳", "其它" });
- return "userAdd";
- }
- }
- @RequestMapping(value = "/list")
- public String listUsers(Model model) {
- List<User> users = userService.getUsers();
- model.addAttribute("users", users);
- return "userList";
- }
- }
http://localhost:8080/ch2_4/user/input测试应用接口
测试效果如下
