作者:mobiledu2502853587 | 来源:互联网 | 2023-09-24 12:28
这篇博客是对过去博客的整理与总结,现在,以下的博客都可以认为过时了。使用Ajax向SpringMVC传递Json数据存在日期类型的JSON数据,进行SpringMVC参数绑定时存在
这篇博客是对过去博客的整理与总结,现在,以下的博客都可以认为过时了。
使用Ajax向SpringMVC传递Json数据
存在日期类型的JSON数据,进行SpringMVC参数绑定时存在的问题和解决方案
SpringMVC配置数据验证(JSR-303)
前端发送请求
var jsOnObj= {
'name' : '啊aaaa', // 乱码问题
'date' : '1905-01-02 14:23:59', // 时间转化问题
'money' : '10.333', // 小数
'no' : '9', // 数字
'serial' : '2147483999' // Long
};
$.ajax({
type : "post",
url : "/interaction",
dataType : "json",
contentType : 'application/json',
data : JSON.stringify(jsonObj),
success : function(data) {
alter(data);
},
error : function(data) {
// TODO
}
});
没什么问题。
后端绑定参数
1、首先需要指定SpringMVC参数绑定之前的JSON转化策略,选择Jackson。
2、其次需要自定义一个ObjectMapper类,目的是在Jackson的ObjectMapper上追加定制对于日期转化的策略。
3、最后,把这些策略反映在SpringMVC的配置文件中。
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.0version>
dependency>
public class JacksonObjectMapper extends ObjectMapper {
private static final long serialVersiOnUID= -8909209092708797621L;
public JacksonObjectMapper() {
super();
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
}
}
<mvc:annotation-driven>
<mvc:message-converters>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean
class="io.spldeolin.bestpractice.util.JacksonObjectMapper"/>
property>
bean>
mvc:message-converters>
mvc:annotation-driven>
通过写个请求方法和实体类来测试一下
@RequestMapping(value = "interaction", method = RequestMethod.POST)
@ResponseBody
public String interaction(@RequestBody InteractionInput input) {
LOG.info(input);
return "success";
}
package io.spldeolin.bestpractice.input;
import java.math.BigDecimal;
import java.util.Date;
public class InteractionInput {
private String name;
private Date date;
private BigDecimal money;
private Integer no;
private Long serial;
// getters and setters
}
结果
绑定失败时的处理
示例中,如果前端把jsonObj.date改成"1905-------01-------02 14爱上打是的:23ssssss:59"这样的非法格式,绑定就会失败,如图所示
这样的提示实际上不够友好(虽然发生的原因基本上是前端BUG),但最好还是捕获一下。
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public String processHttpMessageNotReadableException(HttpMessageNotReadableException e) {
return "请求不可读(可能原因:1.没有Request Body 2.Request Body格式有误)";
}
结果
参数校验
参数绑定成功了,但最好再加一层校验,比如年龄,用Integer类型绑定,虽然上万的数字也可以成功绑定,但显然是不合理的。所以应该引入JSR303的实现
<dependency>
<groupId>org.hibernategroupId>
<artifactId>hibernate-validatorartifactId>
<version>5.4.1.Finalversion>
dependency>
package io.spldeolin.bestpractice.input;
import java.math.BigDecimal;
import java.util.Date;
import javax.validation.constraints.Max;
public class InteractionInput {
private String name;
private Date date;
@Max(value = 10L, message = "钱太多")
private BigDecimal money;
private Integer no;
private Long serial;
// getters and setters
}
@RequestMapping(value = "interaction", method = RequestMethod.POST)
@ResponseBody
public String interaction(@RequestBody @Valid InteractionInput input, BindingResult checker) {
// 这里只是为了演示,实际上这段解析BindingResult对象的代码最好抽到共通类中
if (checker.hasFieldErrors()) {
for (FieldError error : checker.getFieldErrors()) {
String errmsg = error.getDefaultMessage();
LOG.error(errmsg);
return errmsg;
}
}
LOG.info(input);
return "success";
}
返回值
最好返回一个实体类对象,而不是一个具体的String什么的,比如
@RequestMapping(value = "interaction", method = RequestMethod.POST)
@ResponseBody
public RequestResult interaction(@RequestBody @Valid InteractionInput input, BindingResult checker) {
// 这里只是为了演示,实际上这段解析BindingResult对象的代码最好抽到共通类中
if (checker.hasFieldErrors()) {
for (FieldError error : checker.getFieldErrors()) {
String errmsg = error.getDefaultMessage();
LOG.error(errmsg);
return RequestResult.failure().errmsg(errmsg);
}
}
LOG.info(input);
return RequestResult.success().data("交互成功。(实际开发中data参数可以放各种想要传给前端的对象)");
}
function interaction() {
var jsOnObj= {
'name' : '啊aaaa', // 乱码问题
'date' : '1905-01-02 14:23:59', // 时间转化问题
'money' : '10.333', // 小数
'no' : '9', // 数字
'serial' : '2147483999' // Long
};
$.ajax({
type : "post",
url : "/interaction",
dataType : "json",
contentType : 'application/json',
data : JSON.stringify(jsonObj),
success : function(resp) {
if (resp.result) {
alert(resp.data);
// 或者解析这个resp.data
} else {
alert(resp.errmsg);
}
},
error : function(data) {
// TODO
}
});
}
public class RequestResult {
private boolean result;
private Object data;
private String errmsg;
public boolean isResult() {
return result;
}
private RequestResult() {}
public static RequestResult success() {
RequestResult instance = new RequestResult();
instance.setResult(true);
return instance;
}
public static RequestResult failure() {
RequestResult instance = new RequestResult();
instance.setResult(false);
return instance;
}
public RequestResult data(Object data) {
this.data = data;
return this;
}
public RequestResult errmsg(String errmsg) {
this.errmsg = errmsg;
return this;
}
}