Spring MVC数据绑定和响应——复杂数据绑定(四)JSON数据绑定

一、消息转换器—HttpMessageConverter接口

        客户端不同的请求,HttpServletRequest中数据的MediaType可能会不同,如果想将HttpServletRequest中的数据转换成指定对象,或者将对象转换成指定格式的数据,就需要使用对应的消息转换器来实现。Spring中提供了一个HttpMessageConverter接口作为消息转换器。因为数据的类型有多种,所以Spring中提供了多个HttpMessageConverter接口的实现类,其中MappingJackson2HttpMessageConverter是HttpMessageConverter接口的实现类之一,在处理请求时,可以将请求的JSON报文绑定到处理器的形参对象,在响应请求时,将处理器的返回值转换成JSON报文。

二、HttpMessageConverter与Converter类型转换器的区别

        需要注意的是,HttpMessageConverter消息转换器和之前所学习的Converter类型转换器是有区别的。HttpMessageConverter消息转换器用于将请求消息中的报文数据转换成指定对象,或者将对象转换成指定格式的报文进行响应;Converter类型转换器用于对象之间的类型转换。

        接下来通过一个异步提交商品信息案例,演示Spring MVC中的JSON数据绑定,案例具体实现步骤如下。 

1、在项目的pom.xml文件中导入Jackson的依赖。

    <!--Jackson转换核心包依赖--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.2</version></dependency><!--Jackson转换的数据绑定包依赖--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.2</version></dependency><!--Jackson JSON转换注解包--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.0</version></dependency>

        2、在项目中导入jQuery文件

        由于本次演示的是异步数据提交,需要使用jQuery,所以需要将jQuery文件导入到项目中,以便发送ajax请求。在项目的/webapp文件夹下创建名称为js的文件夹,在js文件夹中导入jQuery文件。 

        3、创建一个商品信息页面product.jsp,在product.jsp中创建一个表单用于填写商品信息,表单提交时,表单发送异步请求将表单的商品信息发送到处理器。product.jsp的部分代码如下所示。

<script type="text/javascript">function sumbmitProduct() {var proId = $(“#proId").val();  var proName = $("#proName").val();$.ajax({ url: "${pageContext.request.contextPath }/getProduct",type: "post",data: JSON.stringify({proId: proId, proName: proName}),contentType: "application/json;charset=UTF-8",dataType: "json",success: function (response) {alert(response);}  });		}
</script>

4、修改ProductController.java类,在ProductController类中新增getProduct()方法和getProductList()方法,分别用于获取客户端提交的单个商品信息和多个商品信息。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head><title>异步提交商品</title><script type="text/javascript"src="${pageContext.request.contextPath }/js/jquery-3.6.0.js"></script>
</head>
<body>
<form id="products"><table border="1"><tr><th>商品id</th><th>商品名称</th><th>提交</th></tr><tr><td><input name="proId" value="1" id="proId" type="text"></td><td><input name="proName" value="三文鱼"id="proName" type="text"></td><td><input type="button" value="提交单个商品"onclick="sumbmitProduct()"></td></tr><tr><td><input name="proId" value="2" id="proId2"type="text"></td><td><input name="proName" value="红牛"id="proName2" type="text"></td><td><input type="button" value="提交多个商品"onclick="submitProducts()"></td></tr></table>
</form>
<script type="text/javascript">function sumbmitProduct() {var proId = $("#proId").val();var proName = $("#proName").val();$.ajax({url: "${pageContext.request.contextPath }/getProduct",type: "post",data: JSON.stringify({proId: proId, proName: proName}),contentType: "application/json;charset=UTF-8",dataType: "json",success: function (response) {alert(response);}});}function submitProducts() {var pro1 = {proId: $("#proId").val(), proName: $("#proName").val()}var pro2 = {proId: $("#proId2").val(), proName: $("#proName2").val()}$.ajax({url: "${pageContext.request.contextPath }/getProductList",type: "post",data: JSON.stringify([pro1, pro2]),contentType: "application/json;charset=UTF-8",dataType: "json",success: function (response) {alert(response);}});}
</script>
</body>
</html>

5、在项目的web.xml文件中配置的DispatcherServlet会拦截所有URL,导致项目中的静态资源(如css、jsp、js等)也被DispatcherServlet拦截。如果想放行静态资源,可以在Spring MVC的配置文件中进行静态资源配置。Spring MVC配置文件的部分配置代码如下所示。

<!-- 配置要扫描的包 --><context:component-scan base-package="com.test.controller"/><!-- 配置视图解析器 --><bean class= “org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/pages/"/><property name="suffix" value=".jsp"/></bean><!-- 配置注解驱动 --><mvc:annotation-driven /><!--配置静态资源的访问映射,此配置中的文件,将不被前端控制器拦截 --><mvc:resources mapping="/js/**" location="/js/" />

三、<mvc:resources …/>的两个重要属性

属性说明

location

用于定位需要访问的本地静态资源文件路径,具体到某个文件夹

mapping

匹配静态资源全路径,其中“/**”表示文件夹及其子文件夹下的某个具体文件

        6、启动chapter12项目,在浏览器中访问商品信息页面product.jsp,访问地址为http://localhost:8080/chapter12/product.jsp。

        7、在product.jsp的显示效果图所示的页面中,单击右侧“提交单个商品”按钮,product.jsp表单中的单个商品信息以JSON格式异步发送到服务器端getProduct()方法中。提交单个商品时控制台打印信息如图所示。

获取到的Id为1名称为三文鱼的商品

        从图中所示的打印信息可以得出,客户端异步提交的JSON数据,按照形参product属性的格式进行关联映射,并赋值给product对应的属性,完成了JSON数据的绑定。

        8、在product.jsp的显示效果图所示的页面中,单击“提交多个商品”按钮,product.jsp表单中的2个商品信息以JSON格式异步发送到服务器端getProductList()方法中。提交多个商品时控制台打印信息如图所示。

获取到的Id为1名称为三文鱼的商品
获取到的Id为2名称为红牛的商品

        从图中所示的打印信息可以得出,客户端异步提交的JSON数据,按照形参products的存储结构进行关联映射,并赋值给products中对象的对应属性,完成了JSON数据的绑定。

四、JSON转换器配置和静态资源访问配置

        JSON转换器配置和静态资源访问配置,除了之前讲解的配置方案之外,还可以通过其他方式完成,下面讲解两种配置方式,使用<bean>元素配置JSON转换器和静态资源访问的配置方式。

(一)使用<bean>元素配置JSON转换器

        在配置JSON转换器时,除了常用的<mvc:annotation-driven />元素,还可以使用<bean>元素进行显示的配置,<bean>元素配置JSON转换器方式具体如下所示。

<!-- 使用<bean>元素配置注解方式的处理器映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<!-- 使用<bean>元素配置注解方式的处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><!-- 配置JSON转换器 --><bean  class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/></list></property>
</bean>

(二)静态资源访问的配置方式

        除了使用<mvc:resources>元素实现对静态资源的访问外,Spring MVC还提供了另外2种静态资源访问的配置方式。

(1)使用<mvc:default-servlet-handler>配置静态资源

在Spring MVC的配置文件中,使用<mvc:default-servlet-handler>元素配置静态资源,也可以实现对静态资源的访问。配置静态资源的具体代码如下:

<mvc:default-servlet-handler />

        在Spring MVC的配置文件中配置<mvc:default-servlet-handler />后,Spring MVC会在Spring MVC上下文中定义一个默认的Servlet请求处理器DefaultServletHttpRequestHandler,该处理器会对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web服务器默认的Servlet处理,默认的Servlet会对静态资源放行;如果不是静态资源的请求,就由DispatcherServlet继续处理。

(2)激活Tomcat默认的Servlet来处理静态资源访问

在web.xml文件中激活Tomcat默认的Servlet去处理对应的静态资源,web.xml配置代码如下所示:

<servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.js</url-pattern>
</servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.css</url-pattern>
</servlet-mapping>	...

        在上述代码中, <servlet-mapping>元素可以激活Tomcat默认的Servlet来处理静态文件。在配置时,可以根据需要继续追加<servlet-mapping>。此种配置方式和第(1)种方式本质上是一样的,都是使用Web服务器默认的Servlet来处理静态资源文件的访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38134.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器硬件以及RAID配置

目录 一、RAID磁盘阵列原理&#xff08;嘎嘎重要&#xff09; 1、RAID的概述 2、常用的RAID 2.1、RAID 0 2.2、RAID 1 2.3、RAID 5 2.5、RAID 10 3、阵列卡介绍 二、建立软件RAID磁盘阵列 1、添加硬盘 2、使用fdisk分区&#xff0c;类型为fd 3、mdata命令使用参数 …

安全与加密常识(3)什么是数字签名和数字证书

文章目录 数字签名工作原理关键特点应用实例 数字证书数字证书和数字签名趣味实例 数字签名 数字签名是一种通过密码运算生成的数据&#xff0c;用于验证信息的完整性和来源&#xff0c;确保数据在传输过程中未被篡改&#xff0c;同时提供发送者的身份认证和防止抵赖的功能。它…

Qt: QPushButton 按钮实现 上图标下文字

效果如下&#xff1a; 实现有如下几种方式&#xff1a; 1. 使用 QPushButton 设置 setStyleSheet 例&#xff1a; ui->recorder->setStyleSheet("QPushButton{"\"border: 1px solid #00d2ff; "\"min-height: 60px; "\"col…

python多继承的3C算法

python多继承的3C算法 有很多地方都说python多继承的继承顺序&#xff0c;是按照深度遍历的方式&#xff0c;其实python多继承顺序的算法&#xff0c;不是严格意义上的深度遍历&#xff0c;而是基于深度遍历基础上优化出一种叫3C算法 python多继承的深度遍历 class C:def ru…

MySQL高级-MVCC-原理分析(RR级别)

文章目录 1、RR隔离级别下&#xff0c;仅在事务中第一次执行快照读时生成ReadView&#xff0c;后续复用该ReadView2、总结 1、RR隔离级别下&#xff0c;仅在事务中第一次执行快照读时生成ReadView&#xff0c;后续复用该ReadView 而RR 是可重复读&#xff0c;在一个事务中&…

Django 配置静态文件

1&#xff0c;DebugTrue 调试模式 Test/Test/settings.py DEBUG True...STATICFILES_DIRS [os.path.join(BASE_DIR, static),] STATIC_URL /static/ 1.1 创建静态文件 Test/static/6/images/Sni1.png 1.2 添加视图函数 Test/app6/views.py from django.shortcuts impor…

uniapp,uni-fab组件拖动属性,替代方案

文章目录 1. 背景2. 替代方案2.1 方案一2.2 方案二 参考 1. 背景 最近基于uniapp开发一款设备参数调试的APP软件&#xff0c;其中有使用到悬浮按钮&#xff0c;快速开发阶段&#xff0c;为了能尽快上线&#xff0c;直接使用了uni-ui的扩展组件uni-fab&#xff0c;参考【1】&am…

C++ 设计模式之迭代器模式

C 设计模式之迭代器模式 简介 1、迭代器模式&#xff08;Iterator&#xff09;是一种行为型设计模式&#xff0c;它允许我们顺序访问一个聚合对象中的各个元素&#xff0c;而又不暴露该对象的内部表示。迭代器模式提供了一种方法来遍历容器&#xff08;容器对象&#xff0c;如…

Configure C/C++ debugging

Configure C/C debugging launch.json 文件用于在 Visual Studio Code 中配置调试器。 Visual Studio Code 会生成一个 launch.json (位于项目的 .vscode 文件夹下),其中几乎包含了所有必需的信息。要开始调试,您需要填写 program 字段,指定要调试的可执行文件的路径。这必须…

如何通过流式渲染提升用户体验?

什么是流式渲染&#xff1f; 流式渲染的核心理念是将 HTML 文档分割成小块&#xff08;chunk&#xff09;&#xff0c;并逐步地发送给客户端&#xff0c;而非等待整个页面完整生成后再进行传输。这种方式能够极大地提升用户的初始加载体验&#xff0c;特别是在网络条件不佳或者…

【从零开始学架构 架构基础】四 架构设计的复杂度来源:可扩展性复杂度来源

架构设计的复杂度来源其实就是架构设计要解决的问题&#xff0c;主要有如下几个&#xff1a;高性能、高可用、可扩展、低成本、安全、规模。复杂度的关键&#xff0c;就是新旧技术之间不是完全的替代关系&#xff0c;有交叉&#xff0c;有各自的特点&#xff0c;所以才需要具体…

新书速览|Linux C与C++一线开发实践

《Linux C与C一线开发实践》 本书内容 Linux C/C编程在Linux应用程序开发中占有重要的地位&#xff0c;掌握这项技术将在就业竞争中立于不败之地。《Linux C与C一线开发实践》内容针对初中级读者&#xff0c;贴近软件公司一线开发实践。全书厚达620多页&#xff0c;知识点丰富…

Java中String和StringBuilder的区别

当然可以&#xff0c;我们可以通过面试问答的形式来探讨String和StringBuilder的区别。 面试官&#xff1a;请解释一下Java中String和StringBuilder的区别。 面试回答&#xff1a; 1. 不可变性&#xff08;Immutability&#xff09; String&#xff1a;String对象是不可变的…

微信小程序添加点击事件

在微信小程序中&#xff0c;给<view>组件添加点击事件非常直接&#xff0c;你可以使用bindtap属性来绑定一个事件处理函数。下面是添加点击事件的基本步骤和示例代码&#xff1a; 步骤&#xff1a; 在WXML文件中&#xff1a;给需要添加点击事件的<view>标签添加bi…

第六周周报

摘要 本周重点跟着网课学习了pytorch框架下张量的各种常用操作API&#xff0c;为后面跑模型做准备&#xff0c;因为看的视频比较偏向原理&#xff0c;现在对张量有了一个新的认识。其次在时序的研究上&#xff0c;最近我在看图神经网络跟时序结合的方向&#xff0c;所以本周学…

Qt自定义类型

概述 在使用Qt创建用户界面时&#xff0c;特别是那些具有特殊控件和特性的界面时&#xff0c;开发人员有时需要创建新的数据类型&#xff0c;以便与Qt现有的值类型集一起使用或代替它们。 QSize、QColor和QString等标准类型都可以存储在QVariant对象中&#xff0c;作为基于qo…

51单片机第6步_stdlib.h库函数

本章重点学习stdlib.h库函数。 #include <REG51.h> //包含头文件REG51.h,使能51内部寄存器; #include <stdlib.h> //float atof (char *s1); //参数s1字符串可包含正负号,小数点或E(e)来表示指数部分,如123.456或123e-2; //若首字符是非数据字符,或为正负号…

es6语法复习一

es6语法 1.var 变量提升 2.let 不存在变量提升&#xff0c;只能定义一次 3.const 先定义再使用&#xff0c;定义好来不能修改 4.解构赋值 [a,b,c][1,2,3],{a,b,c}{a:1,b:2,c:3} 5.模版字符串 let aaa; ${a} is ok 6.对象简化写法 const school{ name, change, improve(){ cons…

力扣2438.二的幂数组中查询范围内的乘积

力扣2438.二的幂数组中查询范围内的乘积 lowbit求所有2的幂 accumulate函数(begin,end,start,way)求和/积的方式求积并取模 const int N 1e9 7;class Solution {public:int lowbit(int x){return x & -x;}vector<int> productQueries(int n, vector<vector&l…

[NSSCTF]-Reverse:[SWPUCTF 2021 新生赛]easyapp(安卓逆向,异或)

无壳 把后缀名改为zip&#xff0c;找到apk 查看jadx 这里调用了MainActivity的lambda$onCreate$0$MainActivity&#xff0c;然后又调用了Encoder进行异或。 exp&#xff1a; result棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌 key987654321 flag for i in range(len(result)):flagchr(…