SpringMvc在返回数据之前进行统一处理
这里其实有多种解决方案
如果你不需要获取request对象 可以采用aop(环绕通知)的方式来统一修改
如果你需要获取request对象,那么就需要采用下面的方式
0自己定义一个注解,内容如下
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyResponseBody {
}
1继承org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
覆盖
supportsReturnType()方法
handleReturnValue() 方法
以上两个方法的意思就是如果返回值对应的方法或其所在的类打上了@ResponseBody注解, 则返回true, 即使用这个MethodProcessor进行处理. 具体处理过程在handleReturnValue()中
具体代码如下
import java.io.IOException;
import java.util.List; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor; import com.zhaoyao.zybb2b.annotation.MyResponseBody;
import com.zhaoyao.zybb2b.utils.ZybResult; public class MuliLanguageResponseBodyMethodProcessor extends RequestResponseBodyMethodProcessor {
private final Logger log = LoggerFactory.getLogger(getClass()); public MuliLanguageResponseBodyMethodProcessor(List<HttpMessageConverter<?>> messageConverters) {
super(messageConverters);
} // 打@MyResponseBody注解且返回类型为ZybResult的方法
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return (AnnotationUtils.findAnnotation(returnType.getContainingClass(), MyResponseBody.class) != null
|| returnType.getMethodAnnotation(MyResponseBody.class) != null)
&& ZybResult.class.equals(returnType.getParameterType()); } // 具体的处理过程
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) {
// 设置为true以后, 其他的MethodProcessor就不会再进行处理了
mavContainer.setRequestHandled(true);
ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
try {
writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
} catch (HttpMediaTypeNotAcceptableException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
2在SpringMvc中配置该bean(关于消息处理器,根据自己的需要灵活配置)
<mvc:annotation-driven>
<mvc:message-converters>
<ref bean="httpConverter" />
</mvc:message-converters>
<mvc:return-value-handlers>
<bean
class="com.zhaoyao.zybb2b.interceptor.MuliLanguageResponseBodyMethodProcessor">
<constructor-arg>
<list>
<ref bean="httpConverter" />
</list>
</constructor-arg>
</bean>
</mvc:return-value-handlers>
</mvc:annotation-driven> <bean id="httpConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<!-- 处理responseBody 里面日期类型 -->
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
<!-- 为null字段时不显示 -->
<property name="serializationInclusion">
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
</bean>
</property>
</bean>
3在方法上 打上MyResponseBody 注解,并且返回值是ZybResult 就会执行我们的处理器
原理解读:
通过阅读RequestMappingHandlerAdapter相关代码发现,HandlerMethodReturnValueHandler是对方法返回值进行处理的策略接口。
而RequestResponseBodyMethodProcessor(用于处理@RequestBody和@ResponseBody注解)继承了AbstractMessageConverterMethodProcessor。
AbstractMessageConverterMethodProcessor实现了HandlerMethodReturnValueHandler接口。
因为我当前的项目是响应json数据给客户端,所以直接继承了RequestResponseBodyMethodProcessor,并重写相关方法
为什么要自定义注解?
因为SpringMvc会优先执行系统的,再执行用户自定义的处理器。
在这里,顺便提一下SpringMvc的核心处理过程,后面遇到问题就可以找到特定的流程去处理
Spring工作流程描述
1. 用户向服务器发送请求,请求被SpringMvc 前端控制器DispatcherServlet(org.springframework.web.servlet.DispatcherServlet)捕获;
2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)
4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(这里可以简单的理解为Controller)。 在填充Handler的入参过程中,根据你的配置,SprinMvc将帮你做一些额外的工作:
adapter具体怎么处理的,请查看这篇文章(http://donald-draper.iteye.com/blog/2326185)
HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
5. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
6. 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
7. ViewResolver 结合Model和View,来渲染视图
8. 将渲染结果返回给客户端。
SpringMvc在返回数据之前进行统一处理的更多相关文章
- ajax 与springmvc交互返回数据
1.controller将数据封装成json格式返回页面 @RequestMapping("/dataList") public void datalist(CsoftCunsto ...
- ASP.NET API(MVC) 对APP接口(Json格式)接收数据与返回数据的统一管理
话不多说,直接进入主题. 需求:基于Http请求接收Json格式数据,返回Json格式的数据. 整理:对接收的数据与返回数据进行统一的封装整理,方便处理接收与返回数据,并对数据进行验证,通过C#的特性 ...
- 【springMVC 后台跳转前台】1.使用ajax访问的后台,后台正常执行,返回数据,但是不能进入前台的ajax回调函数中 ----2.前后台都没有报错,不能进入ajax回调函数
问题1: 使用ajax访问的后台,后台正常执行,并且正常返回数据,但是不能进入前台的ajax回调函数中 问题展示: 问题解决: 最后发现是因为后台的方法并未加注解:@ResponseBody,导致方 ...
- springMVC返回数据的四种方式
转自:https://blog.csdn.net/itcats_cn/article/details/82119673 springMVC返回数据的四种方式:第一种,通过request.setAttr ...
- Java封装接口统一返回数据模板
现在大多数都使用前后端分离开发模式,前端通过Ajax请求访问后台服务器,后台返回JSON数据供前端操作,这里编写一个统一返回数据模板类,方便日后操作 public class R extends Ha ...
- Java框架之SpringMVC 03-RequestMapping-请求数据-响应数据
SpringMVC SpringMVC是一种轻量级的.基于MVC的Web层应用框架. 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口. 采用了松散耦合可插拔组件结构,比 ...
- 【spring 后台跳转前台】使用ajax访问的后台,后台正常执行,返回数据,但是不能进入前台的ajax回调函数中
问题: 使用ajax访问的后台,后台正常执行,并且正常返回数据,但是不能进入前台的ajax回调函数中 问题展示: 问题解决: 最后发现是因为后台的方法并未加注解:@ResponseBody,导致方法 ...
- SpringMVC核心——返回值问题
一.SpringMVC 使用 ModelAndView 来处理返回值问题. 1.ModelAndView 官方描述: Holder for both Model and View in the web ...
- SpringMVC(三)-- 视图和视图解析器、数据格式化标签、数据类型转换、SpringMVC处理JSON数据、文件上传
1.视图和视图解析器 请求处理方法执行完成后,最终返回一个 ModelAndView 对象 对于那些返回 String,View 或 ModeMap 等类型的处理方法,SpringMVC 也会在内部将 ...
随机推荐
- Xamarin+Prism开发详解七:Plugin开发与打包测试
有了上章[Xamarin+Prism开发详解六:DependencyService与IPlatformInitializer的关系]的基础,现在来理解Plugin开发就简单了. 本文实例代码地址:ht ...
- C++Primer第五版——习题答案详解(五)
习题答案目录:https://www.cnblogs.com/Mered1th/p/10485695.html 第6章 函数 练习6.4 #include<iostream> using ...
- Java执行JavaScript代码
Java执行JavaScript代码 这篇文章主要为大家详细介绍了Java执行JavaScript代码的具体操作方法,感兴趣的小伙伴们可以参考一下 我们要在Java中执行JavaScriptMetho ...
- 转的,具体 https://www.cnblogs.com/icyJ/p/FreeShare.html
网络资源下载网址 屏幕录像.图像处理,汉化和破解版本很新.国内破解汉化:大眼仔旭 http://www.dayanzai.me/ 开发工具,系统,数据库 http://msdn.itellyou.cn ...
- is,as,类库
is和as运算符: 所有类型的基类 object类型 - 基类:所有类型的基类,就类似是整个生物圈的生物类,是个大的概念 object o1 = new Random(); //object可以承载R ...
- C语言 链表(VS2012版)
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdio.h> ...
- linux服务之ntp与dns篇
ntp复习: 简介:对于计算机时间的同步管理操作服务器 部署:(服务端和客户端或者说集群) 1.服务端下载ntp 2.打开配置文件/etc/ntp.conf: server 127.127.1.0 ...
- openwrt从18.0.1降级回到17.0.6遇到的问题
因为觉得openwrt的18的配置检查功能很费时,特别是遇到ar93xx慢的真可以,所以决定从18.0.1降回到17.0.6上 先把18.0.1的配置backup出来,然后刷17.0.6,再把back ...
- Android Studio2.0 教程从入门到精通Windows版 - 提高篇
第二篇我们开发了一个Hello World应用,并介绍Android Sutdio的界面和如何调试应用,接下来将介绍一些常用的快捷键和必备插件. 常用快捷键 代码跳转 描述:跳转是为了方便代码位置的定 ...
- 2017-09-16 ADB Shell+Putty
鼓捣电子词典的时候需要用到ADB Shell.一开始是用cmd.exe,结果发现它不能识别ANSI转义符,就换成了Putty,然后就可以正常使用了,还有彩色. 配置如下: Connection Typ ...