Spring 学习小记(十四)

本文介绍了 Spring MVC 中的数据绑定技术,包括如何将请求参数绑定到模型对象及使用表单标签库简化表单创建过程。同时,还探讨了 JSON 数据在浏览器与服务器间的交互方式,展示了如何通过 Spring MVC 支持 JSON 数据的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring MVC 数据绑定与表单标签库
 
本小记学习目标
  1. 数据绑定介绍
  2. 表单标签库介绍
  3. 数据绑定的相关应用介绍
  4. JSON数据交互
 
一、数据绑定
Spring MVC所谓的数据绑定主要是从如下几个方面来体现:
1.绑定请求参数输入值到领域模型
2.模型数据到视图的绑定
3.模型数据到表单元素的绑定
 
 
二、表单标签库
表单标签库中包含了可以用在JSP页面中渲染HTML元素的标签。在JSP页面使用Spring表单标库时,需要使用taglib把相应的标签库引入
相应的指令如下:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
相关标签介绍
 
标签
说明
form
渲染表单元素
input
渲染<input type="text">元素
password
渲染<input type="password">元素
hidden
渲染<input type="hidden">元素
textarea
渲染textarea元素
checkbox
渲染一个<input type="checkbox">元素
checkboxes
渲染多个<input type="checkbox">元素
radiobutton
渲染一个<input type="radiobutton">元素
radiobuttons
渲染多个<input type="radiobutton">元素
select
渲染一个选择元素
option
渲染一个选项元素
options
渲染多个选项元素
errors
在span元素中渲错误
表单标签的语法格式
<form:form modelAttribute="xxx" method="post" action="xxx">
    ……
</form:form>
表单元素除了HTML表单元素外还可以有如下的属性:
acceptCharset:定义服务器接受字符编码列表
commandName:暴露表单对象的模型属性名称,默认为command
cssClass:定义应用到form元素的CSS类
cssStyle:定义应用到form元素的CSS样式
htmlEscape:表示是否进行HTML转义,可以为true、false
modelAttribute:暴露form backing object的模型属性名称,默认为command
 
input标签:
语法格式: <form:input path="xxx"/>
这个标签除了cssClass、cssStyle、htmlEscape属性外,还有一个重要的属性path
path属性,它用来把文本框中输入的值绑定到form backing object的一个属性
 
password标签
语法格式: <form:password path="xxx">
这个标签与input标签类似
 
hidden标签
语法格式: <form:hidden path="xxx">
这个标签也与input标签类似,但是它是不显示的因而也就是不支持cssClass和cssStyle属性的
 
textarea标签
语法格式: <form:textarea path="xxx">
这个标签本质上就是一个支持多行输入的input,它也类似于input
 
checkbox标签
语法格式:<form:checkbox path="xxx" value="xxx">
当多个checkbox的path相同的时候表示它们是一组checkbox,支持多选,这个标签的值绑定到一个数组属性
 
checkboxes标签
语法格式:<form:checkboxes items="xxx" path="xxx">
checkboxes标签渲染多个复选框,是一个选项组,也就是多个path相同的checkbox
它有如下三个重要的属性items,itemLabel,itemValue
items:用来生成input元素的Collention,Map或Array
itmeLabel:items属性中指定的集合对象的属性,为每个input元素提供label
itemValue:items属性中指定的集合对象的属性,为每个input元素提供value
 
radiobutton标签
语法格式:<form:radiobutton path="xxx" value="xxx">
多个path相同的radiobutton标签,归于同一组选项,只允许单选
 
radiobuttons标签
语法格式:<form:radiobuttons items="xxx" path="xxx">
这个标签用来渲染多个radio标签,是一个选项组,等价于多个path相同的radiobutton标签
 
select标签
语法格式:
<form:select path="xxx" items="xxx">
 
<form:select path="xxx" items="xxx">
    <option value="xxx">xxx</options>
</form:select>
 
<form:select path="xxx">
    <form:options items=“xxx">
</form:select>
select标签的选项可能来自其属性items指定的集合,或来自一个嵌套option标签或options标签
 
options标签
它用来生成一个select标签的选项列表,它是需要与select标签一起使用的
 
errors标签
语法格式:
<form:errors path="*">
 
<form:errors path="xxx">
渲染一个或者多个span元素,每个span元素包含一个错误消息,它可以用于显示一个特定的错误消息,也可以显示所有错误消息
当path指定为*时表示显示所有错误信息;指定为xxx表示由xxx指定的特定错误消息
 
三、数据绑定实例应用
新增一个Maven的war工程,如果在Eclipse中在生成中如果未自动生成WebContent,这个时候项目会带上一个红叉,可以点击工程右键--->Properties--->Project Facets,把Dynamic Web Module取消掉后重新选中并应用
 
Web工程需要把运行环境添加进来
 
pom.xml中添加如下jar包的依赖
< dependencies >
       <!-- context -->
       < dependency >
             < groupId >org.springframework </ groupId >
             < artifactId >spring-context </ artifactId >
             < version >5.0.2.RELEASE </ version >
       </ dependency >
    <!-- Spring MVC -->
    < dependency >
       < groupId >org.springframework </ groupId >
       < artifactId >spring- webmvc </ artifactId >
       < version >5.0.2.RELEASE </ version >
    </ dependency >
   
    <!-- Spring web -->
    < dependency >
       < groupId >org.springframework </ groupId >
       < artifactId >spring-web </ artifactId >
       < version >5.0.2.RELEASE </ version >
       </ dependency >
   
    <!-- commons-logging -->
    < dependency >
       < groupId >commons-logging </ groupId >
       < artifactId >commons-logging </ artifactId >
       < version >1.2 </ version >
    </ dependency >
   
    <!-- spring- aop -->
    < dependency >
       < groupId >org.springframework </ groupId >
       < artifactId >spring- aop </ artifactId >
       < version >5.0.2.RELEASE </ version >
    </ dependency >
   
       < dependency >
       < groupId >javax.servlet </ groupId >
       < artifactId > jstl </ artifactId >
       < version >1.2 </ version >
       </ dependency >
</ dependencies >
 
在classpath路径下新增一个spring的配置文件springmvc.xml
 
配置web工程的web.xml(1.DispatcherServlet;2:设置编码防止中文乱码)
<? xml version= "1.0" encoding= "UTF-8" ?>
       <!-- 前端核心 servlet 的配置(DispatcherServlet) -->
       < servlet >
             < servlet-name >springDispatcherServlet </ servlet-name >
             < servlet-class >org.springframework.web.servlet.DispatcherServlet </ servlet-class >
             < init-param >
                   < param-name >contextConfigLocation </ param-name >
                   < param-value >classpath:springmvc.xml </ param-value >
             </ init-param >
             < load-on-startup >1 </ load-on-startup >
       </ servlet >
       <!-- Map all requests to the DispatcherServlet for handling -->
       < servlet-mapping >
             < servlet-name >springDispatcherServlet </ servlet-name >
             < url-pattern >/ </ url-pattern >
       </ servlet-mapping >
      
       <!-- 配置解决 psot 请求中文乱码问题 -->
       < filter >
             < filter-name >CharacterEncodingFilter </ filter-name >
             < filter-class >org.springframework.web.filter.CharacterEncodingFilter </ filter-class >
             < init-param >
                   < param-name >encoding </ param-name >
                   < param-value > utf-8 </ param-value >
             </ init-param >
             < init-param >
                   < param-name >forceEncoding </ param-name >
                   < param-value >true </ param-value >
             </ init-param >
       </ filter >
       < filter-mapping >
             < filter-name >CharacterEncodingFilter </ filter-name >
             < url-pattern >/* </ url-pattern >
       </ filter-mapping >
</ web-app >
 
新增数据绑定中对应的数据模型实体类:com.xiaoxie.pojo.User
package com.xiaoxie.pojo;
public class User {
       private String userName;
       private String[] hobby//用户兴趣爱好
       private String sex;      //性别
       private String vocation;       //职业标签
       private String city;     //居住城市
       private String remark;   //备注
      
       /*setter getter方法*/
       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 getSex() {
             return sex;
      }
       public void setSex(String sex) {
             this. sex = sex;
      }
       public String getVocation() {
             return vocation;
      }
       public void setVocation(String vocation) {
             this. vocation = vocation;
      }
       public String getCity() {
             return city;
      }
       public void setCity(String city) {
             this. city = city;
      }
       public String getRemark() {
             return remark;
      }
       public void setRemark(String remark) {
             this. remark = remark;
      }
      
       @Override
       public String toString() {
             return "User[userName=" + userName + "]";
      }
}
 
新增一个Service(M层)主要是与Dao进行交互,com.xiaoxie.service.UserService、com.xiaoxie.service.impl.UserServiceImpl
userService:
package com.xiaoxie.service;
import java.util.ArrayList;
import com.xiaoxie.pojo.User;
/*service的接口,定义了关于用户新增与用户查询的两个接口方法*/
public interface UserService {
       boolean addUser(User user);
      ArrayList<User> getUsers();
}
userServiceImpl:
package com.xiaoxie.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.xiaoxie.pojo.User;
import com.xiaoxie.service.UserService;
@Service
public class UserServiceImpl implements UserService {
       //这里定义一个关于用户的ArrayList集合
       private List<User> users = new ArrayList<User>();
      
       @ Override
       public boolean addUser(User user) {
             if( user!= null && ! "".equals( user.getUserName()) && ! user.getUserName().contains( "@")) {
                   users.add( user);
                   return true;
            } else {
                   return false;
            }
      }
       @ Override
       public ArrayList<User> getUsers() {
             return (ArrayList<User>) users;
      }
}
 
新增Controller层,com.xiaoxie.controller.UserController
package com.xiaoxie.controller;
import java.util.HashMap;
import java.util.List;
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 com.xiaoxie.pojo.User;
import com.xiaoxie.service.UserService;
@Controller
@RequestMapping( "/user")
public class UserController {
      
       //log记录日志
       private static final Log logger = LogFactory. getLog(UserController. class);
       //把service自动注入进来
       @Autowired
       private UserService userService;
      
       @RequestMapping( "/input")
       public String inputUser(Model model) {
            HashMap<String,String> hobbys = new HashMap<String,String>();
             hobbys.put( "旅游", "旅游");
             hobbys.put( "唱歌", "唱歌");
             hobbys.put( "看书", "看书");
             hobbys.put( "电竞", "电竟");
             model.addAttribute( "user", new User());
             model.addAttribute( "hobbys", hobbys);
             model.addAttribute( "vocation", new String[] { "学生一族", "职场白领", "程序猿", "其他"});
             model.addAttribute( "city", new String[] { "北京", "上海", "广州", "深圳", "其他"});
             model.addAttribute( "sex", new String[] { "男", "女"});
             return "userAdd";
      }
      
       @RequestMapping( "/save")
       public String addUser( @ModelAttribute User user,Model model) {
             if( userService.addUser( user)) {
                   logger.info( "新增人员信息成功!");
                   return "redirect:/user/list";
            } else {
                   logger.info( "新增人员信息失败!");
                   //直到转发到input页面
                   return inputUser( model);
            }
      }
      
       @RequestMapping( "/list")
       public String listUser(Model model) {
            List<User> users = userService.getUsers();
             model.addAttribute( "users", users);
             return "listUser";
      }
}
 
在Spring的配置文件springmvc.xml中添加如下内容
<? xml version= "1.0" encoding= "UTF-8" ?>
       xmlns:xsi= " http://www.w3.org/2001/XMLSchema-instance "
       xmlns:context= " http://www.springframework.org/schema/context "
      
       <!-- spring自动抛描的包 -->
       < context:component-scan base-package= "com.xiaoxie.controller" />
       < context:component-scan base-package= "com.xiaoxie.service" />
      
       <!-- 配置视图解析器 -->
       < bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver" id= "viewResolver" >
             <!-- 拼接前缀 -->
             < property name= " prefix" value= "/WEB-INF/jsp/" />
             <!-- 拼接后缀 -->
             < property name= " suffix" value= ".jsp" />
       </ bean >
</ beans >
 
View图层jsp页面的添加
首页:index.jsp:它的目的是提供一个链接跳转到/user/input请求,这个请求直接把封装好的model数据带入到userAdd.jsp
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
    pageEncoding= "UTF-8" %>
<! 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 >
       < h1 >< a href= "${pageContext.request.contextPath } /user/input" >添加用户 </ a ></ h1 >
</ body >
</ html >
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 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:radiobuttons path= "sex" items= "${sex } " />
                         </ P >
                         < p >
                               < label >爱好: </ label >
                               < form:checkboxes items= "${hobbys } " path= "hobby" />
                         </ p >
                         < p >
                               < label >职业: </ label >
                               < form:select path= "vocation" >
                                     < form:options items= "${vocation } " />
                               </ form:select >
                         </ p >
                         < p >
                               < label >所在城市: </ label >
                               < form:select path= "city" >
                                     < form:options items= "${city } " />
                               </ 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 >
listUser.jsp页面:展示用户信息
<%@ page language= "java" contentType= "text/html; charset=UTF-8" pageEncoding= "UTF-8" %>
<%@ taglib prefix= "c" uri= " http://java.sun.com/jsp/jstl/core " %>
<! 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 >
       < h1 >用户列表 </ h1 >
       < a href= " < c:url value= "/user/input" /> " >继续添加 </ a >
       < table border= "1" cellspacing= "0" >
             < tr >
                   < th >姓名 </ th >
                   < th >性别 </ th >
                   < th >爱好 </ th >
                   < th >职业 </ th >
                   < th >所在城市 </ th >
                   < th >描述 </ th >
             </ tr >
             <!-- 遍历信息 -->
             < c:forEach items= "${users } " var= "user" >
                   < tr >
                         < td >${user.userName } </ td >
                         < td >${user.sex } </ td >
                         < td >
                               < c:forEach items= "${user.hobby } " var= "hobby" >
                                    ${hobby } &nbsp;
                               </ c:forEach >
                         </ td >
                         < td >${user.vocation } </ td >
                         < td >${user.city } </ td >
                         < td >${user.remark } </ td >
                   </ tr >
             </ c:forEach >
       </ table >
</ body >
</ html >
 
四、JSON数据交互
 
JSON的认识
JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式。与xml一样,json也是基于纯文本的数据格式。它有对象结构和数组结构两种数据结构。
1.对象结构
以“{”开头,以“}”结尾
中间部分以0个或多个以“,”分隔的key/value对构成,key与value之间以":"分隔
对象结构示例
{
    key1:value1,
    key2:value2,
    ……
}
注意:key必须是String类型,value的类型可以为:String,Number,Object,Array……
如下所示表示person的JSON对象结构
{
    "name":"张飞",
    "address":"汉中",
    "age":35
}
2.数组结构
以"["开头,以"]"结尾
中间由0个或多个以","分隔的值的列表组成
数组结构示例
[
    value1,
    value2,
    ……
]
上面说了两种数结构,也可以由两种结构组合成为复杂的结构。
如下所示student的json表示形式:
{
    "sno":"202012210001",
    "sname":"张三",
    "hobby":["唱歌","看书"],
    "college":{
        "cname":"西安交通大学",
        "city":"西安"
    }
}
 
JSON数据转换
Spring MVC中为了实现浏览器与控制器类之间JSON数据交互,提供了MappingJackson2HttpMessageConverter实现类来默认处理JSON格式请求响应。
它使用的是Jackson开源包来读写JSON数据,这个开源包的主要作用是实现JSON对象与Java对象之间的转换。
在使用注解开发时需要使用到两个重要的JSON格式转换注解
@RequestBody
把请求体中的数据绑定到方法的形参中,这个注解应用到方法的形参上
@ResponseBody
用于直接返回return对象,这个注解应用在方法上
 
添加对json操作的开源包jackson,在pom.xml中加上如下依赖
<!-- jackson -core -->
       < dependency >
          < groupId >com.fasterxml.jackson.core </ groupId >
          < artifactId > jackson-core </ artifactId >
          < version >2.9.4 </ version >
       </ dependency >
       <!-- jackson - databind -->
       < dependency >
          < groupId >com.fasterxml.jackson.core </ groupId >
          < artifactId > jackson- databind </ artifactId >
          < version >2.9.4 </ version >
       </ dependency >
       <!-- jackson -annotations -->
       < dependency >
          < groupId >com.fasterxml.jackson.core </ groupId >
          < artifactId > jackson-annotations </ artifactId >
          < version >2.9.4 </ version >
       </ dependency >
 
在pojo中添加实体Pseron,com.xiaoxie.pojo.Person
package com.xiaoxie.pojo;
public class Person {
       private String name;
       private String address;
       private Integer age;
       public String getName() {
             return name;
      }
       public void setName(String name) {
             this. name = name;
      }
       public String getAddress() {
             return address;
      }
       public void setAddress(String address) {
             this. address = address;
      }
       public Integer getAge() {
             return age;
      }
       public void setAge(Integer age) {
             this. age = age;
      }
      
       @Override
       public String toString() {
             return "Person[name="+ name+ "]";
      }
}
 
在Spring的配置文件中添加如下信息,对静态资源的开放访问
< mvc:annotation-driven />
<!-- 配置静态资源,允许 js 目录下的文件可见 -->
< mvc:resources location= "/js/" mapping= "/js/**" />
 
修改index.jsp页面
<%@ page language= "java" contentType= "text/html; charset=UTF-8"
    pageEncoding= "UTF-8" %>
<! 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 >
< script type= "text/javascript" src= "${pageContext.request.contextPath } /js/jquery-3.2.1.min.js" ></ script >
< script type= "text/javascript" >
       function testJson(){
             var name = $( "#name").val();
             var address = $( "#address").val();
             var age = $( "#age").val();
            $.ajax({
                   //请求路径
                  url: "${pageContext.request.contextPath }/testJson",
                   //请求类型
                  type: "post",
                   //data表示发送的数据
                  data:JSON.stringify({name:name,address:address,age:age}),
                   //定义发送请求的格式为JSON字符串
                  contentType: "application/json;charset=utf-8",
                   //定义响应的数据格式为json字符串
                  dataType: "json",
                   //成功响应的结果
                  success: function(data){
                         if(data!= null){
                              alert( "输入的用户名:" + data.name + ",地址:" + data.address + ",年龄:" + data.age);
                        }
                  }
            });
      }
</ script >
</ head >
< body >
       < h1 >< a href= "${pageContext.request.contextPath } /user/input" >添加用户 </ a ></ h1 >< br >
       < hr />
       < form action= "" >
            姓名: < input type= "text" id= "name" name= "name" />< br />
            地址: < input type= "text" id= "address" name= "address" />< br />
            年龄: < input type= "text" id= "age" name= "age" />< br />
             < input type= "button" value= "提交" onclick= "testJson();" />
       </ form >
</ body >
</ html >
 
新增一个controller实现类 com.xiaoxie.controller.TestJsonController
package com.xiaoxie.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.xiaoxie.pojo.Person;
@Controller
public class TestJsonController {
       @RequestMapping( "/testJson")
       @ResponseBody
       public Person testJson( @RequestBody Person person) {
             //打印JSON数据
            System. out.println( "name=" + person.getName() + ",address=" + person.getAddress() + ",age=" + person.getAge());
             //返回JSON格式响应
             return person;
      }
}
 
访问应用,则可以看到录入信息后会在页面上alert出JSON的信息,在控制台也可以打印出转化为java对象后取出的信息
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值