使用@ResponseBody实现数据输出,进行Aajx异步验证
@RequestMapping(value="/ucexist.html")
@ResponseBody
public Object userCodeIsExit(@RequestParam String userCode){
logger.debug("userCodeIsExit userCode===================== "+userCode);
HashMap<String, String> resultMap = new HashMap<String, String>();
if(StringUtils.isNullOrEmpty(userCode)){
resultMap.put("userCode", "exist");
}else{
User user = userService.selectUserCodeExist(userCode);
if(null != user)
resultMap.put("userCode", "exist");
else
resultMap.put("userCode", "noexist");
}
//将其转换为JSON对象,进行返回输出
return JSONArray.toJSONString(resultMap);
}
在上述代码中,控制器的处理方法userCodelsExit(),通过前台传递过来的userCode进行入参,最后返回Object。在方法体内,调用后台的userService.selectUserCodeExist(userCode)进行同名验证,并返回结果user对象。对于验证结果,我们把他放在HashMap里,最后通过调用JSONArray.toJSONString(resultMap)方法,将其转化为JSON对象,进行返回输出。
这里的@ResponseBody注解的作用是将标注该注解的处理方法的返回结果直接写入HTTP ResponseBody(Response对象的body数据区)中。一般的情况下,@ResponseBody都会在异步获取数据时使用,被其标注的处理方法返回的数据将输出的响应流中,客户端获取并显示数据。
/*
* 验证
* 失焦\获焦
* jquery的方法传递
*/
userCode.bind("blur",function(){
//ajax后台验证--userCode是否已存在
$.ajax({
type:"GET",//请求类型
url:path+"/user/ucexist.html",//请求的url
data:{userCode:userCode.val()},//请求参数
dataType:"json",//ajax接口(请求url)返回的数据类型
success:function(data){//data:返回数据(json对象)
if(data.userCode == "exist"){//账号已存在,错误提示
validateTip(userCode.next(),{"color":"red"},imgNo+ " 该用户账号已存在",false);
}else{//账号可用,正确提示
validateTip(userCode.next(),{"color":"green"},imgYes+" 该账号可以使用",true);
}
},
error:function(data){//当访问时候,404,500 等非200的错误状态码
validateTip(userCode.next(),{"color":"red"},imgNo+" 您访问的页面不存在",false);
}
});
}).bind("focus",function(){
//显示友情提示
validateTip(userCode.next(),{"color":"#666666"},"* 用户编码是您登录系统的账号",false);
}).focus();
在上述代码中,当用户在新增用户页面完成用户编码(userCode)的输入之后,即用户编码输入框中鼠标失焦时,进行Aajx异步验证,请求URL"/user/ucexist.html",请求参数为用户输入的userCode的值。异步调用请求之后,返回的数据类型为JSON类型,若成功,则根据返回的JSON对象,对其进行相应的信息提示。
解决JSON数据传递的中文乱码问题
在Spring MVC中,控制器的处理方法使用@ResponseBody注解向前台页面以JSON格式进行数据传递的时候,若返回值是中文字符串,则回出现乱码。原因是消息转换器(org.springframework.http.converter.StringHttpMessageConverter)中固定了转换字符编码,即"ISO-8859-1".
下面介绍两种解决方案:
1.在控制器处理方法上的@RequestMapping注解中配置produces.
produces:指定返回的内容类型。produces={"application/json;charset=UTF-8"}:表示该处理方法将产生JSON格式的数据,此时会根据请求报文头中的Accept进行匹配,若请求报文头"Accept:application/json"时即可匹配,并且字符串的转换编码为"UTF-8"。如下例代码所示:
@RequestMapping(value="/view ",
method=RequestMethod.GET,
produces={"application/json;charset=UTF-8"})
public String view(@PathVariable String id,Model model){
logger.debug("view id===================== "+id);
User user = userService.getUserById(id);
model.addAttribute(user);
return "userview";
}
这里要注意,请求报文头的Accept:application/json是否与响应报文头中的Content-Type:text/html,类型是否一致。
2.装配消息转换器StringHttpMessageConverter,设置字符编码为UTF-8.
修改配置文件springmvc-servlet.xml,关键代码如下:
<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>
解决JSON数据传递的日期格式问题
简介:
Spring MVC框架中时间数据无法自动绑定,当form表单中出现时间字段需要跟POJO对象中的成员变量进行绑定时,便会出现BinExceptionyi异常。这是Spring MVC框架的问题,若不解决此问题,页面传递回来的时间类型的数据就无法再Controller中接收,也就无法完成新增用户的功能。解决的方式多种,下面简单的介绍三种解决方式。
方式一 在POJO中,时间类型的属性上标注格式化注解@DateTimeFormat
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday; //出生日期
在上述代码中,@DateTimeFormat(pattern="yyyy-MM-dd") 可以将形如1996-12-01的字符串转换为java.util.Date类型。
<mvc:annotation-driven />
注意的是需要在 在springmvc-servlet.xml配置<mvc:annotation-driver/>标签,此标签是Spring MVC的简化配置。默认情况下,他会创建并注册一个默认的DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter实例,并且还会注册一个默认的ConversionService实例:FormattingConversionServiceFactoryBean,那么Spring MVC对处理方法的入参绑定就可以支持注解驱动的功能,以满足大部分类型的转换需要。
方式二 编写自定义转换器
Spring在org.springframework.core.convert.converter包中定义了最简单的Converter转换接口,它仅包括一个接口方法,Converter<S, T>。Converter的作用就是将一种类型装换成另一种类型的对象。例如,用户输入的日期可能有多种形式,如“2018-07-18”、“18-07-2018”等,这些都表示同一个日期。若希望Spring在将输入的日期字符串绑定到Date时,使用不同的日期格式,则需要编写一个Converter,才能将字符串装换成日期。具体实现也很简单:首先需要创建一个实现org.springframework.core.convert.converter.Converter接口的Java类,然后将实现了Converter接口的自定义转换器注册到ConversionServiceFactoryBean中即可。
1)创建StringToDateConverter.java
定义一个负责将字符串转换成指定格式的时间对象Date的自定义转换器,关键示例代码如下:
package cn.smbms.tools;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
public class StringToDateConverter implements Converter<String, Date> {
private String datePattern;
public StringToDateConverter(String datePattern){
System.out.println("StringToDateConverter convert: "+datePattern);
this.datePattern=datePattern;
}
@Override
public Date convert(String s) {
// TODO Auto-generated method stub
Date date=null;
try {
date=new SimpleDateFormat(datePattern).parse(s);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return date;
}
}
在上述代码中,StringToDateConverter需要实现Converter接口的convert()方法,在方法体内完成字符串到java.util.Date类型指定格式的转换。
2)装配自定义的ConversionService
修改springmvc-servlet.xml,关键示例代码如下:
<mvc:annotation-driven conversion-service="myConversionService">
<!-- 中间配置代码省略 -->
</mvc:annotation-driven>
<!-- 装配自定义的ConversionService -->
<bean id="myConversionService" class="org.springframework.context.support.ConversionServiceFactory Bean">
<property name="converters">
<list>
<bean class="cn.smbms.tools.StringToDateConverter">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
</bean>
</list>
</property>
</bean>
在前面,我们提到过<mvc:annotation-driven/>标签会自动注册一个默认的ConversionService,现在由于我们需要注册一个自定义的SpringToDateConverter,因此需要显式定义一个ConversionService来覆盖<mvc:annotation-driven/>中的默认实现,通过配置<mvc:annotation-driven/>标签的conversion-service属性(本示例中Bean的名称为myConversionService)来完成。
装配完成StringToDateConverter之后,就可以在任何控制器的处理方法中使用这种转换器了,并且不需要在POJO中的时间属性上进行格式化注解的标注,注释掉@DateTimeFormat(pattern="yyyy-MM-dd")即可。
3)运行测试
最后,部署运行测试,增加用户信息时,正常保存,此处不再赘述。
方式三 使用@InitBinder装配自定义编辑器
对于数据装换,其实还有一种更加灵活的方式,就是通过自定义的编辑器去实现数据的装换和格式化处理。下面我们就通过@InitBinder添加自定义的编辑器,来解决Spring MVC日期类型无法绑定的问题。具体实现步骤如下。
(1)创建BaseController.java,并标注@InitBinder。
在Controller中抽象出一个父类对象BaseController.java,每个Controller都继承BaseController,而这个父类使用@InitBinder。关键示例代码如下:
package cn.smbms.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
public class BaseController {
/**
* 使用@InitBinder解决SpringMVC日期类型无法绑定问题
* @param dataBinder
*/
@InitBinder
public void initBinder(WebDataBinder dataBinder){
System.out.println("initBender=================================");
dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
}
}
标注了@InitBinder注解的方法会在控制器初始化时调用。在initBinder()方法体内,通过dateBinder的registerCustomEditor()方法注册一个自定义编辑器:第一个参数表示编辑器为日期类型(Date.class);第二个参数表示使用自定义的日期编辑器(CustomDateEditor),时间格式为yyyy-mm-dd,true表示允许为空(该参数表示是否允许为空)。
(2)修改UserController.java,继承BaseController,关键示例代码如下:
@Controller
@RequestMapping("/user")
public class UserController extends BaseController{\
//......中间代码省略
}
(3)部署运行测试,增加用户信息时,正常保存,此处不再赘述。
总结
在Spring MVC中,Bean中定义了Date、double等类型,如果没有做任何处理,日期、double都无法自动绑定。那么上述的后两种方案都可以解决SpringMVC的时间类型等绑定问题,当然也可以做更多业务上的需求,大家灵活掌握。