SpringMVC - 对Ajax的处理(包含 JSON 类型)

更新时间:2023-12-19 05:01:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

SpringMVC——对Ajax的处理(包含 JSON 类型)

一、首先要搞明白的一些事情。

1.从客户端来看,需要搞明白:

(1)要发送什么样格式的 JSON 数据才能被服务器端的 SpringMVC 很便捷的处理,怎么才能让我们写更少的代码,如何做好 JSON 数据和实体之间的对应。

(2)如何组织这些发送的数据。

2.从服务器端来看,需要搞明白:

(1)SpringMVC 如何返回 JSON 数据。

(2)SpringMVC 如何处理请求的复杂数据。

3.$.ajax 的几个参数:

(1)contentType:

contentType: 'application/json;charset=utf-8',作为请求头,用来告诉服务器消息的主体是序列化后的 JSON 字符串。除了低版本的 ie 浏览器外,各大浏览器都原生支持 JSON.stringify() 对对象进行序列化。

(2)dataType:预期服务器返回的数据类型。

4.SpringMVC 是如何处理 JSON 数据的

5.总体的思想:

(1)SpringMVC 能完成的,尽量借助于 SpringMVC,而不是我们手动的去解析。

(2)SpringMVC 解析不了的,尽量借助于第三方的 Jar 包来解析。

(3)SpringMVC 和 第三方 Jar 包解决不了的时候,我们再自己去解析。

二、想要搞明白第一个问题,前提是先要搞明白第一个问题:SpringMVC 是如何处理 JSON 数据的。

1.使用 HttpMessageConverter 来处理 JSON 数据的。

Spring 的 HttpMessageConverter 负责将请求信息转换为一个对象,将对象输出为响应信息。

2.API

(1)boolean canRead(Class clazz, MediaType mediaType);

转换器是否可将请求信息转换为 clazz 类型的对象,同时支持指定的 MIME 类型,如: text/html,application/json 等。

(2)boolean canWrite(Class clazz, MediaType mediaType);

转换器是否可以将 clazz 类型的对象写到响应中,响应支持的类型在 mediaType 中定义。

(3)List getSupportedMediaTypes();

改转换器支持的 MediaType 类型。

(4)T read(Class clazz, HttpInputMessage inputMessage);

将请求信息流转换为 clazz 类型的对象。

(5)void write(T t, MediaType contentType, HttpOutputMessage outputMessage)。

将 T 类型的对象写到响应输出流中,同时指定 MediaType。 3.实现类

3.从上图可以看出,Spring 默认支持使用 Jackson来处理 JSON 问题。添加 Jackson Jar 包后,来看 RequestMappingHadlerAdapter 装配的 HttpMessageConverter:

导入的 Jackson Jar 包:

4.具体的处理方法:

(1)使用 @RequestBody 和 HttpEntity 对请求进行处理。

(2)使用 @ResponseBody 和 ResponseEntity 对响应进行处理。

(3)@RequestBody 对处理方法的入参进行标注。

(4)@ResponseBody 对处理方法的签名进行标注。

(5)HttpEntity 和 ResponseEntity 作为处理方法的入参使用。

具体的使用方法会在下面例子中进行说明。

5.@RequestBody 和 @ResponseBody 是可以同时使用的。

三、上面简单介绍了 SpringMVC 是怎么处理 JSON 数据的,现在来看第二个问题:发送什么样格式的 JSON 数据才能被服务器端的 SpringMVC 很便捷的处理,这里主要指的是请求的 JSON 字符串和实体的映射。

以一个简单的实体为例:Person

Person.java

(1)对于简单的一个Person 对象来说,我们甚至都不需要借助于 JSON 就可以完成请求的数据与实体之间的映射。 请求: 复制代码

$(\ $.ajax({

url: \ type: \ data: {

name : \ age : \ },

success: function (result) { console.log(result); } }); }); 复制代码 handler 方法:

@RequestMapping(\public Person testJson(Person person) { System.out.println(\ return person; }

(2)对于Person数组来说,需要发送什么样的格式才能被 SpringMVC 直接处理?

请求: 复制代码

$(\ $.ajax({

url: \ type: \

data:'[{ \\\}, { \\\}, { \\\

contentType: \ success: function (result) { console.log(result); } }); }); 复制代码 handler 方法:

@RequestMapping(\

public String testJson6(@RequestBody List persons) { System.out.println(\ return \} 注意:

(1)需要指定 \,同时需要注意的是:发送的请求数据不在 Form data 中,而是在 Request Payload 中。关于 [Request Payload] ,在后面说明。

(2)必须要指定 @RequestBody ,否则无法解析。

四、第三个问题:如何组织这些数据以及SpringMVC 如何处理这些数据,做好映射。

(1)说明:

上面说的两个例子,仅仅是最简单的一种形式。现在对其进行扩展,在四里,所说的 SpringMVC 如何处理这些数据,不仅仅指的是SpringMVC,也包括SpringMVC处理不了,使用第三方来处理,或者第三方处理不了,我自己来处理。

同时这里的数据也不仅仅指的 JSON 类型的数据。

(2)对于非表单的 Ajax 提交,这里只提供比较简单的一种方式。还是以上面的 Person 为例。

e1:

数据的组织与请求的发送: 复制代码 var personList = [];

personList.push({name: \李四\personList.push({name: \张三\$(\ $.ajax({

type: \ url: \

data: JSON.stringify(personList),//将对象序列化成JSON字符串 contentType: 'application/json;charset=utf-8', //设置请求头信息 success: function (data) { },

error: function (res) { } }); }); 复制代码 handler 方法:

@RequestMapping(\

public String testJson5(@RequestBody List persons) { System.out.println(persons); return \}

(3)基于表单的 Ajax 提交。

提供一个序列化方法: 复制代码

$.fn.serializeObject = function() {

var o = {};

var a = this.serializeArray(); $.each(a, function() {

if (o[this.name] !== undefined) { if (!o[this.name].push) {

o[this.name] = [o[this.name]]; }

o[this.name].push(this.value || '');

} else {

o[this.name] = this.value || ''; } }); return o; }; 复制代码

还有一种序列化方式:

★单表单情况: 表单: 复制代码

复制代码 对应的实体:

Student.java

e1:使用 serializeObject()

序列化后的值:

JSON.stringify($('form').serializeObject()):

{\hello\ 请求: 复制代码 $(function() {

$('form').submit(function() { $.ajax({

url : \

data : JSON.stringify($('form').serializeObject()), contentType : \ type : \

success : function (result) { console.log(result); } });

return false; }); }); 复制代码

e11:SpringMVC自身进行处理

handler 方法:

@RequestMapping(\

public String testStudent(@RequestBody Student student) { System.out.println(student); return \}

e12:引入第三方 Jar 包进行处理。 准备:

导入 sl4j jar 包,同时添加 JsonUtil 工具类。

JsonUtil.java 后端处理:

@RequestMapping(\

public String testStudent(@RequestBody String inputBody) { Student student = JsonUtil.fromJson(inputBody, Student.class); System.out.println(student); return \}

都可以正常打印 Student 对象。

e2:使用 serialize()

序列化后的值:

$('form').serialize():

firstName=jack&lastName=lily&gender=1&foods=Pizza&foods=Chicken"e=hello+hello&education=Jr.High&tOfD=Day 请求: 复制代码 $(function() {

$('form').submit(function() { $.ajax({

url : \ data : $('form').serialize(), type : \

success : function (result) { console.log(result); } });

return false; }); }); 复制代码 handler 方法:

@RequestMapping(\public String testStudent(Student student) { System.out.println(student); return \}

可以正常打印 Student 对象。

e1 和 e2 对比说明:

e1提交的 JSON 数据,e2 提交的不是 JSON 格式的数据。e1 的请求参数存放在 [Request Payload] 中,而 e2 的请求参数存放在 Form Data 中。

★单表单复杂数据

表单还是上面的 Student 表单,但是在表单外增加了:

需求是:通过 Ajax 发送表单数据的同时,同时发送 \。

经过测试,我就直接说结论了,有兴趣的童鞋可以自行探索,有新的发现欢迎和我交流。 结论:

不能对这样的数据,指定 \,否则后端SpringMVC或者第三方的Jar 包 不能进行自动的解析,增加了解析的复杂度,所以将 json 串传入后台,在后台进行解析。

e1:serializeObject() 请求: 复制代码 $(function() {

$('form').submit(function() { $.ajax({

url : \ data : {

amount : $(\

student : JSON.stringify($('form').serializeObject()) },

type : \

success : function (result) { console.log(result); } });

return false; }); }); 复制代码

后端处理:使用第三方工具类进行解析 复制代码

@RequestMapping(\

public String testStudent(@RequestParam(\ Student student = JsonUtil.fromJson(studentStr, Student.class); System.out.println(\ System.out.println(\:\ return \} 复制代码 可以正常打印。

e2:serialize() 请求: 复制代码 $(function() {

$('form').submit(function() { $.ajax({

url : \ data : {

amount : $(\ student : $('form').serialize() },

type : \

success : function (result) { console.log(result); } });

return false; }); }); 复制代码 Handler 方法:

e1:尝试让 SpringMVC 来解析:

@RequestMapping(\

public String testStudent(@RequestParam(\ System.out.println(\ System.out.println(\:\ return \}

结果:请求无法到达 handler 方法

quote!\

\favorite quote!\

(2)$('form').serialize():

firstName[0]=aa&lastName[0]=bb&gender[0]=1&foods[0]=Pizza"e[0]=Enter+your+favorite+quote!&education[0]=Jr.High&tOfD[0]=Day&

firstName[1]=ds&lastName[1]=cc&gender[1]=1&foods[1]=Steak&foods[1]=Pizza"e[1]=Enter+your+favorite+quote!&education[1]=Jr.High&tOfD[1]=Day 说明:

第一种看着有规律可循,貌似可以进行解析,但是不是一个标准的 JSON 格式的数据。

第二种甚至都出现了乱码,没有想到解析的办法。

来看看第一种,同样这里提供一种思路,因为实现起来比较费劲。

思路:使用正则 like this : 复制代码

Gson gson = new Gson();

String jsonInString = \\\\quote!\\\\\\

\\\\\\

\\\

your

favorite

\\\

your

favorite

\\\

\\\

quote!\\\

your

[\\\\\\

String jsonWithoutArrayIndices = jsonInString.replaceAll(\String jsonAsCollection = \

String jsonAsValidCollection = jsonAsCollection.replaceAll(\System.out.println(jsonAswww.baiyuewang.netValidCollection);

Student[] students = gson.fromJson(jsonAsValidCollection, Student[].class); System.out.println(\System.out.println(students[0]);

System.out.println(\复制代码 说明:

在真实的生产环境下我也没有遇到过这样的情况,所以这里就不往深挖了,等什么时候遇到这样的情况,我再来进行补充这篇文章。 总结:

上面这部分,介绍了项目中遇到的绝大部分 SpringMVC 处理 Ajax 的问题,也提供了多种方案进行选择,对于不常见的问题,也给出了思路。是这篇文章最重要的部分。

五、服务器端的 SpringMVC 如何返回 JSON 类型的字符串。 请求: 复制代码

$(\ $.ajax({

url: \ type: \

success: function (result) { console.log(result); } }); }); 复制代码 1.返回单个对象

handler 方法: 复制代码 @ResponseBody

@RequestMapping(\public Person testReturnJsonValue() { Person person = new Person(); person.setName(\ person.setAge(23); return person; } 复制代码

在浏览器控制台正常打印了 Person 对象。

注意:这里没有指定 dataType。

2.返回多个对象

handler 方法: 复制代码 @ResponseBody

@RequestMapping(\public List testReturnJsonValue() { List personList = new ArrayList<>();

Person person = new Person(); person.setName(\ person.setAge(23);

Person person2 = new Person(); person2.setName(\ person2.setAge(33); personList.add(person); personList.add(person2);

return personList; } 复制代码

在浏览器控制条正常打印了 Person 数组。

3.返回 Map 复制代码 @ResponseBody

@RequestMapping(\public Map testReturnJsonValue() { Map map = new HashMap<>();

Person person = new Person(); person.setName(\ person.setAge(23);

Person person2 = new Person(); person2.setName(\ person2.setAge(33);

map.put(\ map.put(\

return map; } 复制代码

浏览器控制台输出:

4.在实际生产环境下的 Ajax 返回值。

封装一个返回值类型: 复制代码 /**

* @author solverpeng * @create 2016-08-30-17:58 */

public class AjaxResult implements Serializable {

public static final String RESULT_CODE_0000 = \ public static final String RESULT_CODE_0001 = \ private String code; private String message; private Object data;

public AjaxResult() { }

public String getCode() { return this.code; }

public void setCode(String code) { this.code = code; }

public String getMessage() { return this.message; }

public void setMessage(String message) { this.message = message; }

public Object getData() { return this.data; }

public void setData(Object data) {

this.data = data; } } 复制代码

实际使用: 复制代码 @ResponseBody

@RequestMapping(\public AjaxResult testReturnJsonValue() { AjaxResult ajaxResult = new AjaxResult(); try {

Map map = new HashMap<>();

Person person = new Person(); person.setName(\ person.setAge(23);

Person person2 = new Person(); person2.setName(\ person2.setAge(33);

map.put(\ map.put(\ ajaxResult.setData(map);

ajaxResult.setMessage(\

ajaxResult.setCode(AjaxResult.RESULT_CODE_0000); } catch(Excewww.wang027.comption e) { e.printStackTrace();

ajaxResult.setMessage(\

ajaxResult.setCode(AjaxResult.RESULT_CODE_0001); }

return ajaxResult; }

本文来源:https://www.bwwdw.com/article/bp55.html

Top