这里其实有多种解决方案

如果你不需要获取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在返回数据之前进行统一处理的更多相关文章

  1. ajax 与springmvc交互返回数据

    1.controller将数据封装成json格式返回页面 @RequestMapping("/dataList") public void datalist(CsoftCunsto ...

  2. ASP.NET API(MVC) 对APP接口(Json格式)接收数据与返回数据的统一管理

    话不多说,直接进入主题. 需求:基于Http请求接收Json格式数据,返回Json格式的数据. 整理:对接收的数据与返回数据进行统一的封装整理,方便处理接收与返回数据,并对数据进行验证,通过C#的特性 ...

  3. 【springMVC 后台跳转前台】1.使用ajax访问的后台,后台正常执行,返回数据,但是不能进入前台的ajax回调函数中 ----2.前后台都没有报错,不能进入ajax回调函数

    问题1: 使用ajax访问的后台,后台正常执行,并且正常返回数据,但是不能进入前台的ajax回调函数中 问题展示:  问题解决: 最后发现是因为后台的方法并未加注解:@ResponseBody,导致方 ...

  4. springMVC返回数据的四种方式

    转自:https://blog.csdn.net/itcats_cn/article/details/82119673 springMVC返回数据的四种方式:第一种,通过request.setAttr ...

  5. Java封装接口统一返回数据模板

    现在大多数都使用前后端分离开发模式,前端通过Ajax请求访问后台服务器,后台返回JSON数据供前端操作,这里编写一个统一返回数据模板类,方便日后操作 public class R extends Ha ...

  6. Java框架之SpringMVC 03-RequestMapping-请求数据-响应数据

    SpringMVC SpringMVC是一种轻量级的.基于MVC的Web层应用框架. 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口. 采用了松散耦合可插拔组件结构,比 ...

  7. 【spring 后台跳转前台】使用ajax访问的后台,后台正常执行,返回数据,但是不能进入前台的ajax回调函数中

    问题: 使用ajax访问的后台,后台正常执行,并且正常返回数据,但是不能进入前台的ajax回调函数中 问题展示:  问题解决: 最后发现是因为后台的方法并未加注解:@ResponseBody,导致方法 ...

  8. SpringMVC核心——返回值问题

    一.SpringMVC 使用 ModelAndView 来处理返回值问题. 1.ModelAndView 官方描述: Holder for both Model and View in the web ...

  9. SpringMVC(三)-- 视图和视图解析器、数据格式化标签、数据类型转换、SpringMVC处理JSON数据、文件上传

    1.视图和视图解析器 请求处理方法执行完成后,最终返回一个 ModelAndView 对象 对于那些返回 String,View 或 ModeMap 等类型的处理方法,SpringMVC 也会在内部将 ...

随机推荐

  1. C#中Button.DialogResult属性

    窗体中的某个按钮,如果设置了DialogResult(不是设置为None),当窗体是通过ShowDialog方法显示的时候 则不必设置任何响应函数,单击按钮也可窗体.然后,该窗体的DialogResu ...

  2. select函数与I/O多路转接

    select函数与I/O多路转接 相作大家都写过读写IO操作的代码,例如从socket中读取数据可以使用如下的代码: while( (n = read(socketfd, buf, BUFSIZE) ...

  3. JavaScript中B继承A的方法

    js继承有5种实现方式:1.继承第一种方式:对象冒充  function Parent(username){    this.username = username;    this.hello = ...

  4. C++环境的配置( windows)

    方法一.——VS: 使用windows开发神器visio studio.这种方法比较简单,直接下载一个最新的vs安装就行.不单单是C++,C.C#.VB等都可以开发. 方法二.——只安装C++编译器: ...

  5. 解决spring-security session超时 Ajax 请求没有重定向的问题

    开始时, 代码是这样的: $.ajax({ type : "POST", url : sSource, cache : false, dataType : "json&q ...

  6. VMware 2017 v14.x 永久许可证激活密钥

    FF31K-AHZD1-H8ETZ-8WWEZ-WUUVA CV7T2-6WY5Q-48EWP-ZXY7X-QGUWD

  7. Android单元测试学习(一)

    什么是单元测试 首先总结一下什么是单元测试,单元测试中的单元在Android或Java中可以理解为某个类中的某一个方法,因此单元测试就是针对Android或Java中某个类中的某一个方法中的逻辑代码进 ...

  8. Matplotlib--基本使用

    基础应用 import matplotlib.pyplot as plt import numpy as np #使用np.linspace定义x:范围是(-1,1);个数是50. 仿真一维数据组(x ...

  9. spring-AOP之通知和顾问

    通知和顾问都是切面的实现形式,其中通知可以完成对目标对象方法简单的织入功能. 而顾问包装了通知,可以让我们对通知实现更加精细化的管理,让我们可以指定具体的切入点. 通知分为前置通知,环绕通知及后置通知 ...

  10. tomcat双击startup.bat启动时闪退

    tomcat之前用的好好地没有问题,今天重启一下就发现双击startup.bat一闪而过,接着就没有任何动静了,tomcat无法启动啦? 于是网上搜了一堆tomcat闪退的解决办法,其中有说是没有读取 ...