详解SpringBoot定制@ResponseBody注解返回的Json格式

作者:烟囱里一只猫、 时间:2023-07-26 13:47:02 

 1、引言

在SpringMVC的使用中,后端与前端的交互一般是使用Json格式进行数据传输,SpringMVC的@ResponseBody注解可以很好的帮助我们进行转换,但是后端返回数据给前端往往都有约定固定的格式,这时候我们在后端返回的时候都要组拼成固定的格式,每次重复的操作非常麻烦。

2、SpringMVC对@ResponseBody的处理

SpringMVC处理@ResponseBody注解声明的Controller是使用默认的.RequestResponseBodyMethodProcessor类来实现,RequestResponseBodyMethodProcessor类实现了HandlerMethodReturnValueHandler接口并实现了接口中的supportsReturnType()和handleReturnValue()方法。


/*
* 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.method.support;

import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.NativeWebRequest;

/**
* Strategy interface to handle the value returned from the invocation of a
* handler method .
*
* @author Arjen Poutsma
* @since 3.1
* @see HandlerMethodArgumentResolver
*/
public interface HandlerMethodReturnValueHandler {

/**
* Whether the given {@linkplain MethodParameter method return type} is
* supported by this handler.
* @param returnType the method return type to check
* @return {@code true} if this handler supports the supplied return type;
* {@code false} otherwise
*/
boolean supportsReturnType(MethodParameter returnType);

/**
* Handle the given return value by adding attributes to the model and
* setting a view or setting the
* {@link ModelAndViewContainer#setRequestHandled} flag to {@code true}
* to indicate the response has been handled directly.
* @param returnValue the value returned from the handler method
* @param returnType the type of the return value. This type must have
* previously been passed to {@link #supportsReturnType} which must
* have returned {@code true}.
* @param mavContainer the ModelAndViewContainer for the current request
* @param webRequest the current request
* @throws Exception if the return value handling results in an error
*/
void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
 ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;

}

3、实现思路

知道@ResponseBody是由RequestResponseBodyMethodProcessor进行处理的,这时候我们可以自己定义一个处理返回数据的Handler来实现我们的定制化Json格式数据返回,但是如果直接把我们定制的Handler加入到SpringMVC的ReturnValueHandlers中,因为我们定制的Handler在RequestResponseBodyMethodProcessor之后,所以我们定制的Handler还是不会生效,这时候我们可以想办法把RequestResponseBodyMethodProcessor替换成我们定制的Handler。

4、代码实现

4.1、定制Json返回格式实体


package com.autumn.template;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
* JSON信息交互对象模板
* @Author Autumn、
* @Date 2019/4/8 23:46
* @Description
*/
@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Result implements BaseBean {

......(这里只展示一些必要字段)
 /** 响应码 */
 private Integer code;
 /** 响应信息 */
 private String message;
 /** 数据 */
 private Object data;
 /** 请求地址 */
 private String url;

......
}

4.2、定义定制Json返回格式Handler


package com.autumn.component.handler;

import com.autumn.template.Result;

import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
* 统一处理ResponseBody数据格式
* @Author: Autumn、
* @Date: 2019/4/24 23:59
* @Description:
**/
public class ResultWarpReturnValueHandler implements HandlerMethodReturnValueHandler {

private final HandlerMethodReturnValueHandler delegate;

/** 委托 */
 public ResultWarpReturnValueHandler(HandlerMethodReturnValueHandler delegate) {
   this.delegate = delegate;
 }

/**
  * 判断返回类型是否需要转成字符串返回
  * @param returnType 方法返回类型
  * @return 需要转换返回true,否则返回false
  */
 @Override
 public boolean supportsReturnType(MethodParameter returnType) {
   return delegate.supportsReturnType(returnType);
 }

/**
  * 返回值转换
  */
 @Override
 public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
  // 委托SpringMVC默认的RequestResponseBodyMethodProcessor进行序列化
   delegate.handleReturnValue(returnValue instanceof Result ? returnValue : Result.succeed(returnValue), returnType, mavContainer, webRequest);
 }
}

4.3、替换默认的RequestResponseBodyMethodProcessor


package com.autumn.config;

import com.autumn.component.handler.ResultWarpReturnValueHandler;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import java.util.ArrayList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;

/**
* 替换默认的RequestResponseBodyMethodProcessor
* @Author Autumn、
* @Date 2019/4/8 23:46
* @Description
*/
@Slf4j
@Configuration
@EnableCaching
public class ApplicationContext implements WebMvcConfigurer, InitializingBean {

@Autowired(required = false)
 private RequestMappingHandlerAdapter adapter;

@Override
 public void afterPropertiesSet() throws Exception {
   // 获取SpringMvc的ReturnValueHandlers
   List<HandlerMethodReturnValueHandler> returnValueHandlers = adapter.getReturnValueHandlers();
   // 新建一个List来保存替换后的Handler的List
   List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(returnValueHandlers);
   // 循环遍历找出RequestResponseBodyMethodProcessor
   for (HandlerMethodReturnValueHandler handler : handlers) {
     if (handler instanceof RequestResponseBodyMethodProcessor) {
      // 创建定制的Json格式处理Handler
       ResultWarpReturnValueHandler decorator = new ResultWarpReturnValueHandler(handler);
       // 使用定制的Json格式处理Handler替换原有的RequestResponseBodyMethodProcessor
       int index = handlers.indexOf(handler);
       handlers.set(index, decorator);
       break;
     }
   }
   // 重新设置SpringMVC的ReturnValueHandlers
   adapter.setReturnValueHandlers(handlers);
 }
}

5、总结

至此完成了定制@ResponseBody注解返回的Json格式,在Controller中返回任何的字符串都可以定制成为我们想要的Json格式。此外SpringMVC还提供了非常多的Handler接口来进行Controller的增强,可以使用此思路对参数等进行定制化。

来源:https://blog.csdn.net/qq_33328356/article/details/89856823

标签:SpringBoot,@ResponseBody,Json
0
投稿

猜你喜欢

  • Java GZip 基于内存实现压缩和解压的方法

    2023-05-24 12:47:29
  • Java看完秒懂版熔断和降级的关系

    2023-11-06 01:12:13
  • java实现简易外卖订餐系统

    2021-11-04 16:01:25
  • MybatisPlus多表连接查询的问题及解决方案

    2023-11-25 22:09:06
  • myBatis实现三 级嵌套复杂对象的赋值问题

    2023-11-23 06:42:26
  • URLConnection发送HTTP请求的方法_动力节点Java学院整理

    2023-09-20 16:08:17
  • C#控件闪烁的解决方法

    2023-02-27 07:30:41
  • c#简单读取文本的实例方法

    2022-02-16 14:51:52
  • springcloud微服务基于redis集群的单点登录实现解析

    2023-05-27 17:10:32
  • C#实现的微信网页授权操作逻辑封装示例

    2022-08-31 04:30:05
  • Mybatis执行流程、缓存原理及相关面试题汇总

    2022-10-15 23:30:28
  • C++类与对象深入之构造函数与析构函数详解

    2021-06-29 13:44:44
  • 详解java8在Collection中新增加的方法removeIf

    2022-06-04 20:51:45
  • Spring Boot web项目的TDD流程

    2023-07-06 16:10:10
  • SpringBoot整合freemarker实现代码生成器

    2023-07-17 20:31:08
  • Android自定义控件简单实现侧滑菜单效果

    2023-10-30 16:56:57
  • Android实现热门标签的流式布局

    2023-01-29 02:32:36
  • Kotlin协程到底是如何切换线程的

    2022-03-03 13:52:39
  • C#微信公众号开发之接收事件推送与消息排重的方法

    2022-01-31 08:44:46
  • C#中的IEnumerable简介及简单实现实例

    2023-07-15 22:27:07
  • asp之家 软件编程 m.aspxhome.com