本文承接上文《玩转SpringMVC之响应视图方法类型案例以及使用注意点》访问链接为:https://blog.csdn.net/xtho62/article/details/109111712
JSON简介:
JSON:JavaScript 对象表示法(JavaScript Object Notation)。
JSON 是存储和交换文本信息的语法。类似 XML。
JSON 比 XML 更小、更快,更易解析,和JavaScript 结合使用起来更好更方便,以键值对方式存储,是现在非常主流的响应数据方式。
下面是一段简单的JSON:
{
"Name":"calmtho",
"sex":"男",
"Birthday":"xxxx/xx/xx"
}
ResponseBody注解作用:
该注解用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的
数据如:json,xml 等,通过 Response 响应给客户端
需求:
使用@ResponseBody 注解实现将 controller 方法返回对象转换为 json 响应给客户端。
注意前置知识点:
Springmvc 默认用 MappingJacksonHttpMessageConverter 对 json 数据进行转换,需要加入jackson 的包。
注意导的jar版本要和使用的springmvc兼容。
在此前的学习中,我们学习了SpringMVC的执行流程,可知道, DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。
解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置:
mvc:resources标签配置不过滤
<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/>
<!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/>
<!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
我们可以使用引入jq,使用简单的请求,按下按钮,弹出一个提醒窗口,测试jq使用。
首先在web-app下面创建一个js文件夹,复制进准备好的jq.min.js
代码简单,可以确定没问题!运行项目,访问response.jsp页面,点击按钮
说明被拦截了。在springmvc中,配置放行js之后尝试一下:
注意:如果还不行,看看是不是js目录放错了,是在web-app下,不是WEB-INF下
,还有保证springmvc里面的配置正确,还不行清理浏览器缓存!ctrl+shift+Del
清理缓存一般就能解决,本人在测试的时候也出现了这个情况,配置正确后,运行清理缓存就可以了。
所以css,images都放在web-app根目录下,然后照着上面配就没问题啦!
先小小的解释一下,AJAX译为异步编程,即早期AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),但现在AJAX已经不仅仅是and xml,很多js库都对其有了封装,现在的的AJAX更多指的是前端的异步请求。基本上都是配合JSON进行使用。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
下面我们使用jq中AJAX请求来响应JSON数据,前端修改response.jsp,书写Ajax请求:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script>
//页面加载,绑定单击事件
$(function (){
$("#btn").click(function () {
//alert("hello btn")
//发送AJAX请求
$.ajax({
//编写json格式,设置属性和值
url:"user/testAjax",
contentType:"application/json;charset=UTF-8",
data:'{"username":"Ajax","password":"123","age":23}',
dataType:"json",
type:"post",
success:function (data) {
//请求发送成功回调data服务器响应json数据,进行解析
}
});
});
});
</script>
</head>
<body>
<a href="user/testString">testString</a>
<a href="user/testVoid">testVoid</a>
<a href="user/testModelAndView">testModelAndView</a>
<a href="user/testForwardorRedirect">testForwardorRedirect</a>
<br>
<button id="btn">发送异步请求</button>
</body>
</html>
接下来编写后端,首先要接送前端发送的请求,其实请求和响应往往是伴随着的,当然是先测试是否能接收到前端的异步请求,UserController增加方法:
/*/
模拟异步请求响应
*/
@PostMapping("testAjax")
public void testAjax(@RequestBody String requestBody){
System.out.println("testAjax执行了。。。");
//控制台获取请求体
System.out.println(requestBody);
}
注意这里常见错误,请求和方法不一致,会出现405错误,而我们这里使用的是void方法,默认会按照spring.xml配置的路径去找testAjax页面,我们没编写,所以404其实不是问题。运行测试一下!
如我们所料在浏览器的控制台404出现了,因为此时响应的还是页面,不要紧,我们先看看后台的控制台打印情况:
确实是我们Ajax的请求。如果一开始写错Mapping的注解,改为指定post后注解后注意清浏览器缓存。
那接下来就是正式做响应JSON数据的处理啦,我们想返回JavaBean的对象,即使用@ResponseBody注解把JavaBean对象转换成json字符串,直接响应,还有有前提的springmvc帮我们做了处理转换,但是需要对象的数据和请求的key一致,同时需要json解析器解析,才能返回给前端。这里我们用上面说的jackson,spring boot也默认继承了jackson,所以我们就使用这个演示,当然也可以使用fastjson。
先使用导入依赖,在本项目的pom.xml下增加以下依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
注意版本2.7.0以下用不了
那实际中一般我们请求的值是发给后台从数据获取匹对或者是操作修改等操作,然后再返回字符串对象给回前台,尤其在现在前后端分离的时代这个ResponeBody显得尤为重要!
现在就改造我们的方法,就使用User类型,返回对象以JSON的方式给到前。
端
修改UserController类=》复制原方法,粘贴上去,进行修改,同时原方法注释掉:
/*
@ResponseBody使用返回Json对象给前端
*/
@PostMapping("testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
System.out.println("testAjax执行了。。。");
System.out.println("前端获取到的对象: "+user);
user.setUsername("lisi");
user.setAge(18);
System.out.println("返回给前端的的对象: "+user);
return user;
}
前端response.jsp回调函数,函数方法新增弹出对话框返回对象以及各属性!
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script>
//页面加载,绑定单击事件
$(function (){
$("#btn").click(function () {
//alert("hello btn")
//发送AJAX请求
$.ajax({
//编写json格式,设置属性和值
url:"user/testAjax",
contentType:"application/json;charset=UTF-8",
data:'{"username":"Ajax","password":"123","age":23}',
dataType:"json",
type:"post",
success:function (data) {
//请求发送成功回调data服务器响应json数据,进行解析
alert(data)
alert(data.username)
alert(data.password)
alert(data.age)
}
});
});
});
</script>
</head>
<body>
<a href="user/testString">testString</a>
<a href="user/testVoid">testVoid</a>
<a href="user/testModelAndView">testModelAndView</a>
<a href="user/testForwardorRedirect">testForwardorRedirect</a>
<br>
<button id="btn">发送异步请求</button>
</body>
</html>
运行测试:
按下按钮开始弹框:
看后台控制台输出:
至此你已经学习了非常重要的知识点响应Json数据啦,而在现在前后端分离更多使用的是RestController注解,看看源码,即整合了@Controller和@ResponseBody放在类上面使用返回对象,在前后端分离时代,一般会把请求的状态和返回信息封装给前端然后做一个交互。
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Controller;
/**
* A convenience annotation that is itself annotated with
* {@link Controller @Controller} and {@link ResponseBody @ResponseBody}.
*
* Types that carry this annotation are treated as controllers where
* {@link RequestMapping @RequestMapping} methods assume
* {@link ResponseBody @ResponseBody} semantics by default.
*
*
NOTE: {@code @RestController} is processed if an appropriate
* {@code HandlerMapping}-{@code HandlerAdapter} pair is configured such as the
* {@code RequestMappingHandlerMapping}-{@code RequestMappingHandlerAdapter}
* pair which are the default in the MVC Java config and the MVC namespace.
*
* @author Rossen Stoyanchev
* @author Sam Brannen
* @since 4.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}
至此响应也告一段落,之后的文章则会是关于SpringMVC的文件上传下载,以及异常处理以及有可能也会出国际化这方面,不过国际化还是要看需求,所以看情况而定吧。觉得不错就点个赞吧!
本系列代码托管在gitee,地址为:https://gitee.com/calmtho/springmvcdemo