当前位置:   article > 正文

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

SpringBoot定制@ResponseBody注解返回的Json格式
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;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
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;

  	......
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
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);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
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);
    }
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
5、总结

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/619862
推荐阅读
相关标签
  

闽ICP备14008679号