SpringMVC 04 SSM框架扩展 JSON+多视图解析器

13 篇文章 0 订阅
10 篇文章 0 订阅

SSM框架扩展

1.学习目标

1.1预习提问
  1. @ResponseBody注解的用法有哪些?
  2. 如何理解Spring MVC的ContentNegotiatingViewResolver视图解析器?
  3. Spring MVC中输出JSON数据,对于日期格式应该如何处理?
  4. Spring MVC+Spring+MyBatis框架整合的步骤有哪些?
1.2.学习目标
  1. 掌握Spring MVC框架中JSON对象处理方法
  2. 理解Spring MVC框架中数据转换和格式化功能
  3. 会搭建SSM框架,能基于此框架进行代码开发

2.JSON数据的传递处理

2.1JSON数据的传递处理5-1

需求说明

  • 在724系统用户管理功能中,新增用户时,对账号进行重复性校验

  • 使用JSON格式返回结果

  • 要求:使用Aajx异步请求进行判断

  • 如图所示:

    在这里插入图片描述

    在这里插入图片描述

2.2JSON数据的传递处理5-2

分析:

  1. 表单输入项

    • 账号
  2. Ajax异步判断

    • 控制器中增加一个验证账号是否重复的接口
    • 文本框失去焦点时候进行调用该接口
  3. 返回结果:JSON对象

  4. 根据返回结果,视图页面上进行相应的信息提示

    问题

  5. 在Spring MVC中如何处理JSON对象?

2.3JSON数据的传递处理5-3

实现步骤

  1. 修改控制层
    1. maven中引入fastjson依赖
    2. SysUserController中新增验证账号是否重复接口user/userExist
      1. 在方法上添加 @ResponseBody 注解
      2. return JSON.toJSONString(resultMap);
@ResponseBody注解的作用是将当前接口返回的数据直接写入HTTP Response Body中
JSON是FastJson提供的工具类,它提供了一些数据类型转换以及格式化数据的功能
  1. 修改视图层
    1. sysUser/add.js添加Ajax编码
  2. 测试
2.5演示示例1

新增用户-同名验证

  1. maven中添加fastjson依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
 	<groupId>com.alibaba</groupId>
 	<artifactId>fastjson</artifactId>
 	<version>1.2.78</version>
</dependency>
  1. SysUserController中新增验证账号是否重复接口/userExist
/**
 * 验证用户编号是否已存在
 * @param account
 * @return
*/
@ResponseBody
@RequestMapping(value="/userExist", method = RequestMethod.GET)
@GetMapping("/userExist")
public Object userExist(@RequestParam String account){
	logger.debug("验证用户名account="+account + "的用户是否存在");
	HashMap<String, Object> resultMap = new HashMap<String, Object>();
	if(StringUtils.isNullOrEmpty(account)){
		resultMap.put("exist", 1);
	}else{
		SysUser sysUser = sysUserService.getAccountExist(account);
		if(null != sysUser) {
			resultMap.put("exist", 1);
		}else {
			resultMap.put("exist", 0);
		}
	}
	return JSONArray.toJSONString(resultMap);
}
  1. ajax后台验证–account是否已存在
<input type="hidden" id="path" name="path" value="${pageContext.request.contextPath }"/>
<input type="hidden" id="referer" name="referer" value="<%=request.getHeader("Referer")%>"/>
/**
 * 提示信息显示
 * element:显示提示信息的元素(font)
 * css:提示样式
 * tipString:提示信息
 * status:true/false --验证是否通过
*/
function validateTip(element,css,tipString,status){
	element.css(css);
	element.html(tipString);
	element.prev().attr("validateStatus",status);
}
var referer = $("#referer").val();
let path = $("#path").val();//获取项目名部分的路径
let imgYes = "<img width='15px' src='"+path+"/statics/images/y.png' />";
let imgNo = "<img width='15px' src='"+path+"/statics/images/n.png' />";

var realName = null;
var account = null;
var password = null;
var rpassword = null;
var phone = null;
var birthday = null;
var roleList = null;
var addBtn = null;
var backBtn = null;
var idPic = null;
var errorinfo = null
var errorinfo_wp = null;
var workPic = null;

$(function(){
	realName = $("#realName");
	account = $("#account");
	password = $("#password");
	rpassword = $("#rpassword");
	phone = $("#phone");
	birthday = $("#birthday");
	roleList = $("#roleList");
 	idPic = $("#idPic");
 	errorinfo = $("#errorinfo");
 	workPic = $("#workPic");
 	
    errorinfo_wp = $("#errorinfo_wp");
	addBtn = $("#add");
	backBtn = $("#back");
	//初始化的时候,要把所有的提示信息变为:* 以提示必填项,更灵活,不要写在页面上
	realName.next().html("*");
	account.next().html("*");
	password.next().html("*");
	rpassword.next().html("*");
	phone.next().html("*");
	birthday.next().html("*");
	roleList.next().html("*");
 if(errorinfo.val() == null || errorinfo.val() == ""){
     idPic.next().html("* 上传大小不能超过500K * 上传文件类型必须为:jpg、jpeg、png、pneg");
 }else{
     idPic.next().html(errorinfo.val());
 }
 if(errorinfo_wp.val() == null || errorinfo_wp.val() == ""){
     workPic.next().html("* 上传大小不能超过500K * 上传文件类型必须为:jpg、jpeg、png、pneg");
 }else{
     workPic.next().html(errorinfo_wp.val());
 }

	/*
	 * 验证
	 * 失焦\获焦
	 * jquery的方法传递
	 */
	account.bind("blur",function(){
		//ajax后台验证--account是否已存在
		//user.do?method=ucexist&account=**
		$.ajax({
			type:"GET",//请求类型
			url:path+"/user/userExist",//请求的url
			data:{account:account.val()},//请求参数
			dataType:"json",//ajax接口(请求url)返回的数据类型
			success:function(data){//data:返回数据(json对象)
				if(data.exist == 1){//账号已存在,错误提示
					validateTip(account.next(),{"color":"red"},imgNo + " 该用户账号已存在",false);
				}else{//账号可用,正确提示
					validateTip(account.next(),{"color":"green"},imgYes+" 该账号可以使用",true);
				}
			},
			error:function(data){//当访问时候,404,500 等非200的错误状态码
				validateTip(account.next(),{"color":"red"},imgNo+" 您访问的页面不存在",false);
			}
		});
	}).bind("focus",function(){
		//显示友情提示
		validateTip(account.next(),{"color":"#666666"},"* 用户编码是您登录系统的账号",false);
	}).focus();

	realName.bind("focus",function(){
		validateTip(realName.next(),{"color":"#666666"},"* 用户名长度必须是大于1小于10的字符",false);
	}).bind("blur",function(){
		if(realName.val() != null && realName.val().length > 1
				&& realName.val().length < 10){
			validateTip(realName.next(),{"color":"green"},imgYes,true);
		}else{
			validateTip(realName.next(),{"color":"red"},imgNo+" 用户名输入的不符合规范,请重新输入",false);
		}

	});

	password.bind("focus",function(){
		validateTip(password.next(),{"color":"#666666"},"* 密码长度必须是大于6小于20",false);
	}).bind("blur",function(){
		if(password.val() != null && password.val().length > 6
				&& password.val().length < 20 ){
			validateTip(password.next(),{"color":"green"},imgYes,true);
		}else{
			validateTip(password.next(),{"color":"red"},imgNo + " 密码输入不符合规范,请重新输入",false);
		}
	});

	rpassword.bind("focus",function(){
		validateTip(rpassword.next(),{"color":"#666666"},"* 请输入与上面一只的密码",false);
	}).bind("blur",function(){
		if(rpassword.val() != null && rpassword.val().length > 6
				&& rpassword.val().length < 20 && password.val() == rpassword.val()){
			validateTip(rpassword.next(),{"color":"green"},imgYes,true);
		}else{
			validateTip(rpassword.next(),{"color":"red"},imgNo + " 两次密码输入不一致,请重新输入",false);
		}
	});


	birthday.bind("focus",function(){
		validateTip(birthday.next(),{"color":"#666666"},"* 点击输入框,选择日期",false);
	}).bind("blur",function(){
		if(birthday.val() != null && birthday.val() != ""){
			validateTip(birthday.next(),{"color":"green"},imgYes,true);
		}else{
			validateTip(birthday.next(),{"color":"red"},imgNo + " 选择的日期不正确,请重新输入",false);
		}
	});

	phone.bind("focus",function(){
		validateTip(phone.next(),{"color":"#666666"},"* 请输入手机号",false);
	}).bind("blur",function(){
		var patrn=/^(13[0-9]|15[0-9]|18[0-9])\d{8}$/;
		if(phone.val().match(patrn)){
			validateTip(phone.next(),{"color":"green"},imgYes,true);
		}else{
			validateTip(phone.next(),{"color":"red"},imgNo + " 您输入的手机号格式不正确",false);
		}
	});

	roleList.bind("focus",function(){
		validateTip(roleList.next(),{"color":"#666666"},"* 请选择角色",false);
	}).bind("blur",function(){
		if(roleList.val() != null && roleList.val() > 0){
			validateTip(roleList.next(),{"color":"green"},imgYes,true);
		}else{
			validateTip(roleList.next(),{"color":"red"},imgNo + " 请重新选择角色",false);
		}
	});

	addBtn.bind("click",function(){
		/*if(account.attr("validateStatus") != "true"){
			account.blur();
		}else */if(realName.attr("validateStatus") != "true"){
			realName.blur();
		}else if(password.attr("validateStatus") != "true"){
			password.blur();
		}else if(rpassword.attr("validateStatus") != "true"){
			rpassword.blur();
		}else if(birthday.attr("validateStatus") != "true"){
			birthday.blur();
		}else if(phone.attr("validateStatus") != "true"){
			phone.blur();
		/*}else if(roleList.attr("validateStatus") != "true"){
			roleList.blur();*/
		}else{
			if(confirm("是否确认提交数据")){
				$("#userForm").submit();
			}
		}
	});

	backBtn.on("click",function(){
		if(referer != undefined
			&& null != referer
			&& "" != referer
			&& "null" != referer
			&& referer.length > 4){
		 window.location.href = referer;
		}else{
			history.back(-1);
		}
	});
});
  1. dao/service
/**
 * dao实现:根据用户编码查询用信息
*/
@Override
public SysUser getLoginUser(Connection connection, String account)
		throws Exception {
	PreparedStatement pstm = null;
	ResultSet resultSet = null;
	SysUser user = null;
	if(null != connection){
		String sql = "select * from t_sys_user where account=?";
		Object[] params = {account};
		resultSet = BaseDao.execute(connection, pstm, resultSet, sql, params);
		if(resultSet.next()){
			user = createUserByResultSet(resultSet);
			user.setPassword(resultSet.getString("password"));
			user.setAddress(resultSet.getString("address"));
			user.setCreatedUserId(resultSet.getInt("createdUserId"));
			user.setCreatedTime(resultSet.getTimestamp("createdTime"));
			user.setUpdatedUserId(resultSet.getInt("updatedUserId"));
			user.setUpdatedTime(resultSet.getTimestamp("updatedTime"));
		}
		BaseDao.closeResource(null, pstm, resultSet);
	}
	return user;
}

/**
 * service实现验证账号是否存在
*/
@Override
public SysUser getAccountExist(String userCode) {
	Connection connection = null;
	SysUser user = null;
	try {
		connection = BaseDao.getConnection();
		user = userDao.getLoginUser(connection, userCode);
	} catch (Exception e) {
		e.printStackTrace();
	}finally{
		BaseDao.closeResource(connection, null, null);
	}
	return user;
}
2.6JSON数据的传递处理5-4

需求说明

  1. 在用户列表页面,当点击"查看详情"按钮时,在不刷新页面的情况下将用户信息显示在页面下方
  2. 使用JSON格式返回结果
  3. 要求:使用Aajx异步请求接口来获取用户信息
    在这里插入图片描述
2.7JSON数据的传递处理5-5

实现步骤

  1. 修改控制层
    1. SysUserController中增加根据id获取用户详情接口
      • 在方法上添加@ResponseBody注解
      • 得到返回值:String sysUserJSON = JSON.toJSONString(sysUser);
  2. 修改视图层
    • 增加一个div区域用于展示用户明细信息
    • 调整"查看详情"按钮关联的JS代码
  3. 测试
2.8演示示例2

查看用户信息-Ajax异步获取

  1. controller
/**
 * 查询用户详情,返回JSON
 * @param id
 * @return
 */
@ResponseBody
@GetMapping("/{id}/view")
@GetMapping(value = "/{id}/view",produces = {"application/json;charset=UTF-8"} )
public Object view(@PathVariable String id){
	StringHttpMessageConverter s = null;
	logger.debug("根据id查询用户详情id:" + id);
	String sysUserJSON = "";
	if(null == id || "".equals(id)){
		return "nodata";
	}else{
		try {
			SysUser sysUser = sysUserService.getUserById(id);
			sysUserJSON = JSON.toJSONString(sysUser);
			logger.debug("用户信息转换为JSON:" + sysUserJSON);
		} catch (Exception e) {
			e.printStackTrace();
			return "failed";
		}
		return sysUserJSON;
	}
}
  1. jsp视图页面
<span><a class="viewUser" href="javascript:;" userid=${user.id } account=${user.account }><img src="${pageContext.request.contextPath }/statics/images/view.png" alt="查看" title="查看"/></a></span>
  1. js 脚本代码
$(".viewUser").on("click",function(){
    //将被绑定的元素(a)转换成jquery对象,可以使用jquery方法
    var obj = $(this);
    /*window.location.href=path+"/user/view/"+ obj.attr("userid");*/
    $.ajax({
        type:"GET",
        url:path+"/user/" + obj.attr("userid") + "/view",
        dataType:"json",
        success:function(result){
            if("failed" == result){
                alert("操作超时!");
            }else if("nodata" == result){
                alert("没有数据!");
            }else{
                $("#v_account").val(result.account);
                $("#v_realName").val(result.realName);
                if(result.sex == "1"){
                    $("#v_sex").val("女");
                }else if(result.sex == "2"){
                    $("#v_sex").val("男");
                }
                $("#v_birthday").val(result.birthday);
                $("#v_phone").val(result.phone);
                $("#v_address").val(result.address);
                $("#v_roleIdName").val(result.roleIdName);
            }
        },
        error:function(data){
            alert("error!");
        }
    });
});

jsp:查看详情页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@include file="/WEB-INF/jsp/common/head.jsp"%>
 <div class="right">
        <div class="location">
            <strong>当前位置:</strong>
            <span>用户管理页面 >> 用户查看详情页面</span>
        </div>
        <div class="supplierView">
            <p><strong>用户编号:</strong><span>${sysUser.account }</span></p>
            <p><strong>账号:</strong><span>${sysUser.realName }</span></p>
            <p><strong>性别:</strong>
            	<span>
            		<c:if test="${sysUser.sex == 1 }"></c:if>
					<c:if test="${sysUser.sex == 2 }"></c:if>
				</span>
			</p>
            <p><strong>出生日期:</strong><span>${sysUser.birthday }</span></p>
            <p><strong>手机号码:</strong><span>${sysUser.phone }</span></p>
            <p><strong>地址:</strong><span>${sysUser.address }</span></p>
            <p><strong>角色:</strong><span>${sysUser.roleIdName}</span></p>
			<div class="supplierAddBtn">
            	<input type="button" id="back" name="back" value="返回" >
            </div>
        </div>
    </div>
</section>
<%@include file="/WEB-INF/jsp/common/foot.jsp"%>
<script type="text/javascript" src="${pageContext.request.contextPath }/statics/js/sysUser/view.js"></script>

3.JSON数据乱码和日期问题

3.1中文乱码和日期问题6-1
  1. JSON中文乱码问题
  2. JSON日期格式问题
3.2中文乱码和日期问题6-2

解决JSON数据传递过程中出现的中文乱码问题

  1. 原因:Spring MVC框架中内置了一个处理String类型数据的消息转换器(org.springframework.http.converter.StringHttpMessageConverter),该消息转换器中固定了转换字符编码为"ISO-8859-1"
  2. 解决方案一:在控制器方法上设置编码格式
@ResponseBody
@GetMapping(value="/view/{id}",produces={"application/json;charset=UTF-8"})
public Object view(@PathVariable String id){
	//…….中间代码省略	
}
3.3演示示例3

解决json数据传递的中文乱码问题-produces

/**
 * 查询用户详情,返回JSON
 * @param id
 * @return
 */
@ResponseBody
@GetMapping("/{id}/view")
@GetMapping(value = "/{id}/view",produces = {"application/json;charset=UTF-8"} )
public Object view(@PathVariable String id){
	StringHttpMessageConverter s = null;
	logger.debug("根据id查询用户详情id:" + id);
	String sysUserJSON = "";
	if(null == id || "".equals(id)){
		return "nodata";
	}else{
		try {
			SysUser sysUser = sysUserService.getUserById(id);
			sysUserJSON = JSON.toJSONString(sysUser);
			logger.debug("用户信息转换为JSON:" + sysUserJSON);
		} catch (Exception e) {
			e.printStackTrace();
			return "failed";
		}
		return sysUserJSON;
	}
}
3.4中文乱码和日期问题6-3
  1. 解决JSON数据传递过程中出现的中文乱码问题
    • 解决方案二:装配消息转换器StringHttpMessageConverter
      • 在Spring MVC的配置文件中进行配置
3.5演示案例4

解决json数据传递的中文乱码问题-StringHttpMessageConverter

在Spring MVC的配置文件中进行配置

<mvc:annotation-driven>
	<mvc:message-converters>
		<bean class=
			"org.springframework.http.converter.StringHttpMessageConverter">
			<property name="supportedMediaTypes">
				<list>
					<value>application/json;charset=UTF-8</value>
				</list>
			</property>
		</bean>
	</mvc:message-converters>
</mvc:annotation-driven>
3.6中文乱码和日期问题6-4

解决JSON数据传递过程中出现的日期格式问题

  • 日期格式:时间戳形式(1077033600000) “yyyy-MM-dd”

  • 解决方案一:注解方式

    public class SysUser(){
    	@DateTimeFormat(pattern="yyyy-MM-dd")
    	@JSONField(format="yyyy-MM-dd")
    	private Date birthday;
    	// 省略其他属性及getter、setter方法
    }
    
3.7.演示示例5

解决json数据传递的日期格式问题-注解方式

 public class SysUser(){
	@DateTimeFormat(pattern="yyyy-MM-dd")
	@JSONField(format="yyyy-MM-dd")
	private Date birthday;
	// 省略其他属性及getter、setter方法
}
3.8中文乱码和日期问题6-5
  1. 解决JSON数据传递过程中出现的日期格式问题

    • 解决方案二:配置消息转换器

      <mvc:annotation-driven>
      	<mvc:message-converters>
      		// …省略代码
      		<bean class="com.alibaba.fastjson.support.spring
      						.FastJsonHttpMessageConverter">
      			<property name="supportedMediaTypes">
      				<list><value>text/html;charset=UTF-8</value>
      					<value>application/json</value>
      				</list>
      			</property>
      			<property name="features">
      				<list><value>WriteDateUseDateFormat</value></list>
      			</property>
      		</bean>
      	</mvc:message-converters>
      </mvc:annotation-driven>
      
      
3.9中文乱码和日期问题6-6
  1. FastJson规定了默认的日期类型为"yyyy-MM-dd HH:mm:ss",而我们希望用户出生日期格式为"yyyy-MM-dd",怎么实现?

    自定义FastJson的消息转换器+使用@JSONField注解单独处理

4.多视图解析器

4.1多视图解析器3-1

需求说明

  • 可以根据Accept值、扩展名等,把相同的数据内容以不同格式返回,呈现不同的视图效果
    查询用户详情接口中以JSON纯数据的格式返回数据

在这里插入图片描述

分析

  • 通过多视图解析器ContentNegotiatingViewResolver和多视图解析管理器ContentNegotiationManager进行灵活处理
4.2多视图解析器3-2
  1. 多视图解析管理器ContentNegotiationManager
    • 判断请求所要求的MIME类型,以决定所采用的视图
    • favorParameter
      • 表示支持参数匹配,可以根据请求参数值确定MIME类型,默认的请求参数为format,默认值为true(支持)
  2. favorPathExtension
    • 表示是否支持扩展名,扩展名指xxx.json、xxx.xml等形式,默认为true(支持)
  3. defaultContentType
    • 配置默认的ContentType类型
  4. mediaTypes
    • 根据请求参数的MIME类型决定接口返回数据的展示类型,MIME类型包括json=application/json、xml=application/xml、html=text/html等
4.3多视图解析器3-3
  1. 多视图解析器ContentNegotiatingViewResolver
    1. contentNegotiationManager
      • 注入自定义的多视图解析管理器
    2. defaultViews
      • 指定默认视图
    3. viewResolvers
      • 设置视图解析器
4.4演示示例6

多视图解析器-ContentNegotiatingViewResolver

<?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:mvc="http://www.springframework.org/schema/mvc"
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context
     http://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="cn.cvs.controller"/>
    
	<mvc:resources mapping="/statics/**" location="/statics/" />
    
     <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
         <mvc:message-converters>
			<bean class="org.springframework.http.converter.StringHttpMessageConverter">
				<property name="supportedMediaTypes">
					<list>
						<value>application/json;charset=UTF-8</value>
					</list>
				</property>
			</bean>
			<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
				<property name="supportedMediaTypes">
					<list>
						<value>text/html;charset=UTF-8</value>
						<value>application/json</value>
					</list>
				</property>
				<property name="features">
					<list>
						<!-- Date的日期转换器 -->
						<value>WriteDateUseDateFormat</value>
					</list>
				</property>
			</bean>
		</mvc:message-converters>
	</mvc:annotation-driven>

	<!-- 配置多视图解析器 -->
	<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
		<!-- 是否启用参数支持,默认为true(支持),即xxx?format=json、xml等形式。 -->
		<property name="favorParameter" value="true" />
		<!-- favorPathExtension:是否支持扩展名,默认为true(支持),扩展名指xxx.json、xxx.xml等形式 -->
		<property name="favorPathExtension" value="true" />
		<!-- 默认ContentType -->
		<property name="defaultContentType" value="application/json" />
		<!-- 配置映射关系 -->
		<!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用  -->
		<property name= "mediaTypes">
			<value>
				json=application/json
				xml=application/xml
				html=text/html
			</value>
		</property>
	</bean>
	<!-- VIEW解析定义。内容协商视图解析器;根据contentNegotiationManager使用的不同mediaTypes决定不同的 view进行响应  默认使用json-->
	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">

		<!-- 内容协商管理器 用于决定media type -->
		<property name="contentNegotiationManager" ref="contentNegotiationManager"/>
		<!-- 默认视图 解析 -->
		<property name="defaultViews">
			<list>
				<bean class="com.alibaba.fastjson.support.spring.FastJsonJsonView">
					<property name="charset" value="UTF-8"/>
				</bean>
			</list>
		</property>
		<property name="viewResolvers">
			<list>
				<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
					<property name="prefix" value="/WEB-INF/jsp/"/>
					<property name="suffix" value=".jsp"/>
				</bean>
			</list>
		</property>
	</bean>

	<!--<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />-->
	<!-- 对转向页面的路径解析。prefix:前缀, suffix:后缀 -->
	<!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
		&lt;!&ndash;<property name="order" value="0"/>&ndash;&gt;
		<property name="prefix" value="/WEB-INF/jsp/"/>
		<property name="suffix" value=".jsp"/>
	</bean>-->

	<!--  全局异常处理 -->
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<prop key="java.lang.RuntimeException">error</prop>
			</props>
		</property>
	</bean>

	<!-- 配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="5000000"/>
		<property name="defaultEncoding" value="UTF-8"/>
	</bean>
</beans>

5.Spring MVC框架中的数据格式转换3-1

5.1数据格式转换3-1

问题

  • 在添加用户功能中输入新增用户信息,点击保存之后系统报错
    400状态码:客户端发送的请求格式不正确
    控制台:BindException异常

在这里插入图片描述

分析

  • 在Spring MVC中时间数据无法实现自动转换绑定
  • 解决方案
    • 必须要手动配置自定义数据类型的绑定才能实现该功能
  • 数据转换和格式化		
    
5.2数据格式转换3-2

数据绑定流程图

在这里插入图片描述

5.3数据格式转换3-3
  1. DataBinder

    • 数据绑定的核心组件
    • 核心调度
  2. ConversionService

    • Spring类型转换体系的核心接口
    • 解决form表单中时间格式字符串转换为Date类型数据的问题
  3. Validator:数据校验

  4. BindingResult

    • 包含已完成数据绑定的入参对象和相应的校验错误对象

      配置<mvc:annotation-driven/>标签会注册一个默认的ConversionService实例,使得方法入参绑定能够支持注解驱动的功能,因此可以通过格式化注解来解决日期的转换问题

6.编写自定义转换器

6.1编写自定义转换器

需求说明

  1. 使用自定义的数据格式转换器实现日期类型数据绑定的功能

Converter转换器

  1. 作用:把数据从一种类型转换成另一种类型
  2. 方法:convert()

实现步骤

  1. 创建自定义数据格式转换器
  2. 装配自定义的ConversionService
6.2演示示例8

SpringMVC数据转换-自定义转换器

1.创建自定义数据格式转换器

package cn.cvs.web.converter;

import org.apache.log4j.Logger;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 自定义的字符串转日期转换器
 */
public class String2DateConverter implements Converter<String, Date> {
	private Logger logger = org.apache.log4j.Logger.getLogger(String2DateConverter.class);

	private String datePattern;

	/**
	 * 一个日期格式参数的构造函数
	 * @param datePattern 日期格式
	 */
	public String2DateConverter(String datePattern){
		logger.info("加载String2DateConverter");
		this.datePattern = datePattern;
	}

	/**
	 * 具体的字符串转日期功能方法
	 * @param s
	 * @return
	 */
	@Override
	public Date convert(String s) {
		Date date = null;
		try {
			date =  new SimpleDateFormat(datePattern).parse(s);
			logger.info("String2DateConverter convert date:" + date);
		} catch (ParseException e) {
			logger.error("日期转换失败:" + s );
			e.printStackTrace();
		}
		return date;
	}
}

2.装配自定义的ConversionService;spring-mvc.xml配置:

<bean id="myConversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
		<property name="converters">
			<list>
				<bean class="cn.cvs.web.converter.String2DateConverter">
					<constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
				</bean>
			</list>
		</property>
</bean>

7.使用@InitBinder装配自定义编辑器

7.1使用@InitBinder装配自定义编辑器

需求说明

  1. 通过自定义的编辑器实现数据的转换和格式化处理

实现步骤

  1. 创建BaseController.java,使用@InitBinder装配自定义编辑器

    package cn.cvs.controller;
    
    import org.apache.log4j.Logger;
    import org.springframework.beans.propertyeditors.CustomDateEditor;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.annotation.InitBinder;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class BaseController {
    	private Logger logger = Logger.getLogger(BaseController.class);
    	/**
    	 * 使用@InitBinder解决SpringMVC日期类型无法绑定的问题
    	 * @param dataBinder
    	 */
    	@InitBinder
    	public void initBinder(WebDataBinder dataBinder){
    		logger.info("进入BaseController的initBinder方法");
    		dataBinder.registerCustomEditor(Date.class, 
    				new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
    	}
    }
    
  2. 修改SysUserController.java,继承BaseController

public   class  SysUserController extends BaseController{
    
     
}

标注了@InitBinder注解的方法会在控制器初始化时被调用

8.本章总结

8.1思维导图总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

众生云海,一念初见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值