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 也会在内部将 ...
随机推荐
- PAT 乙级 1086 就不告诉你 (15 分)
1086 就不告诉你 (15 分) 做作业的时候,邻座的小盆友问你:“五乘以七等于多少?”你应该不失礼貌地围笑着告诉他:“五十三.”本题就要求你,对任何一对给定的正整数,倒着输出它们的乘积. 输入格式 ...
- JVM学习总结(一):Java内存区域
一.JVM运行时数据区 1.程序计数器: (1)一块较小的线程私有的内存空间. (2)JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(或一个内核) ...
- Chapter3 复杂度分析(上):如何分析,统计算法的执行效率和资源消耗
数据结构解决的问题:“快” + “省”,即为时间,空间复杂度分析 1:为什么需要复杂度分析? 因为通过统计手段分析的结果受到两个因素的影响,一:测试结果非常依赖测试环境,二:测试结果受数据规模的影响很 ...
- tp5 (layui )excel导入
1.composer安装PHPExcel 下载安装composer 其次 cmd切换到项目根目录 运行命令:composer require phpoffice/phpexcel 注意: 1.运行可能 ...
- 如何使用jQuery从字符串中删除最后一个字符
如何使用jQuery从字符串中删除最后一个字符 1.string.slice(0,-1) 2.str.substring(0,str.length-1)
- java中异常处理
看到一篇异常处理的好文章: Java异常处理机制主要依赖于try,catch,finally,throw,throws五个关键字. try 关键字后紧跟一个花括号括起来的代码块,简称try块.同理:下 ...
- css实现文本超出部分省略号显示
一般超出文本显示分为两种:单行超出文本和多行超出文本省略号显示,实现方式使用纯css实现: div { // 单行 white-space: nowrap; overflow: hidden; tex ...
- ABAP-表中数据的横向累加
GLT0 等表中数据的横向累加 ——塞依SAP培训 在 ABAP 的 GLT0.FAGLFLEXT 等余额表中,用诸如 TSL01.TSL02 …… TSL16 等字段记录了 16 个期间的发生额 ...
- ABAP-FTP-执行
1.界面 2.程序 ZFID0004_FTP_EXEC 主程序: *&------------------------------------------------------------- ...
- python中subprocess模块
subprocess 模块 subprocess称之为子进程,进程是一个正在进行的程序 子进程是由另一个正在运行的程序启动的程序,例如QQ聊天点击一个链接,打开了浏览器,那么浏览器称之为QQ的子进程 ...