Spring Boot中Spring MVC的表单标签库与数据绑定讲解与实战(附源码 超详细必看)

简介: Spring Boot中Spring MVC的表单标签库与数据绑定讲解与实战(附源码 超详细必看)

简介

数据绑定是将用户参数输入值绑定到领域模型的一种特性。在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"%>

表单包含元素如下

数据绑定

1:创建ch2_4应用并导入相关的JAR包

2:创建Web和Spring MVC配置类

在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指的是静态资源存放的位置
  }
}

3:创建View层

包含两个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="<c:url value="${pageContext.request.contextPath }/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 }&nbsp;
                  </c:forEach>
                </td>
                <td>
                  <c:forEach items="${user.friends }" var="friend">
                    ${friend }&nbsp;
                  </c:forEach>
                </td>
                <td>${user.carrer }</td>
                <td>${user.houseRegister }</td>
                <td>${user.remark }</td>
            </tr>
        </c:forEach>
    </table>
</body>
</html>

4:创建领域模型

在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;
  }
}

5:创建Service层

Service层使用静态集合变量users模拟数据库存储用户信息,包括添加用户和查询用户两个功能

UserService接口类代码如下

package service;
import java.util.ArrayList;
import pojo.User;
public interface UserService {
  boolean addUser(User u);
  ArrayList<User> 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<User> users = new ArrayList<User>();
  @Override
  public boolean addUser(User u) {
    if(!"IT民工".equals(u.getCarrer())){//不允许添加IT民工
      users.add(u);
      return true;
    }
    return false;
  }
  @Override
  public ArrayList<User> getUsers() {
    return users;
  }
}

6:创建Controller层

在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";
  }
}

7:测试应用 启动主类后 通过地址

http://localhost:8080/ch2_4/user/input测试应用接口

测试效果如下

相关文章
|
9月前
|
负载均衡 监控 Java
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
本文详细介绍了 Spring Cloud Gateway 的核心功能与实践配置。首先讲解了网关模块的创建流程,包括依赖引入(gateway、nacos 服务发现、负载均衡)、端口与服务发现配置,以及路由规则的设置(需注意路径前缀重复与优先级 order)。接着深入解析路由断言,涵盖 After、Before、Path 等 12 种内置断言的参数、作用及配置示例,并说明了自定义断言的实现方法。随后重点阐述过滤器机制,区分路由过滤器(如 AddRequestHeader、RewritePath、RequestRateLimiter 等)与全局过滤器的作用范围与配置方式,提
Spring Cloud Gateway 全解析:路由配置、断言规则与过滤器实战指南
|
10月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1436 3
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
819 7
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
1209 1
|
8月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1326 2
Spring Boot 3.x 微服务架构实战指南
|
8月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
8月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
人工智能 Java API
Spring AI 实战|Spring AI入门之DeepSeek调用
本文介绍了Spring AI框架如何帮助Java开发者轻松集成和使用大模型API。文章从Spring AI的初探开始,探讨了其核心能力及应用场景,包括手动与自动发起请求、流式响应实现打字机效果,以及兼容不同AI服务(如DeepSeek、通义千问)的方法。同时,还详细讲解了如何在生产环境中添加监控以优化性能和成本管理。通过Spring AI,开发者可以简化大模型调用流程,降低复杂度,为企业智能应用开发提供强大支持。最后,文章展望了Spring AI在未来AI时代的重要作用,鼓励开发者积极拥抱这一技术变革。
4416 71
Spring AI 实战|Spring AI入门之DeepSeek调用
|
8月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
617 4