詳解SpringBoot定制@ResponseBody注解返回的Json格式
1、引言
在SpringMVC的使用中,后端與前端的交互一般是使用Json格式進(jìn)行數(shù)據(jù)傳輸,SpringMVC的@ResponseBody注解可以很好的幫助我們進(jìn)行轉(zhuǎn)換,但是后端返回?cái)?shù)據(jù)給前端往往都有約定固定的格式,這時(shí)候我們在后端返回的時(shí)候都要組拼成固定的格式,每次重復(fù)的操作非常麻煩。
2、SpringMVC對@ResponseBody的處理
SpringMVC處理@ResponseBody注解聲明的Controller是使用默認(rèn)的.RequestResponseBodyMethodProcessor類來實(shí)現(xiàn),RequestResponseBodyMethodProcessor類實(shí)現(xiàn)了HandlerMethodReturnValueHandler接口并實(shí)現(xiàn)了接口中的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、實(shí)現(xiàn)思路
知道@ResponseBody是由RequestResponseBodyMethodProcessor進(jìn)行處理的,這時(shí)候我們可以自己定義一個(gè)處理返回?cái)?shù)據(jù)的Handler來實(shí)現(xiàn)我們的定制化Json格式數(shù)據(jù)返回,但是如果直接把我們定制的Handler加入到SpringMVC的ReturnValueHandlers中,因?yàn)槲覀兌ㄖ频腍andler在RequestResponseBodyMethodProcessor之后,所以我們定制的Handler還是不會生效,這時(shí)候我們可以想辦法把RequestResponseBodyMethodProcessor替換成我們定制的Handler。
4、代碼實(shí)現(xiàn)
4.1、定制Json返回格式實(shí)體
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 {
......(這里只展示一些必要字段)
/** 響應(yīng)碼 */
private Integer code;
/** 響應(yīng)信息 */
private String message;
/** 數(shù)據(jù) */
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;
/**
* 統(tǒng)一處理ResponseBody數(shù)據(jù)格式
* @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;
}
/**
* 判斷返回類型是否需要轉(zhuǎn)成字符串返回
* @param returnType 方法返回類型
* @return 需要轉(zhuǎn)換返回true,否則返回false
*/
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return delegate.supportsReturnType(returnType);
}
/**
* 返回值轉(zhuǎn)換
*/
@Override
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
// 委托SpringMVC默認(rèn)的RequestResponseBodyMethodProcessor進(jìn)行序列化
delegate.handleReturnValue(returnValue instanceof Result ? returnValue : Result.succeed(returnValue), returnType, mavContainer, webRequest);
}
}
4.3、替換默認(rèn)的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;
/**
* 替換默認(rèn)的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();
// 新建一個(gè)List來保存替換后的Handler的List
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(returnValueHandlers);
// 循環(huán)遍歷找出RequestResponseBodyMethodProcessor
for (HandlerMethodReturnValueHandler handler : handlers) {
if (handler instanceof RequestResponseBodyMethodProcessor) {
// 創(chuàng)建定制的Json格式處理Handler
ResultWarpReturnValueHandler decorator = new ResultWarpReturnValueHandler(handler);
// 使用定制的Json格式處理Handler替換原有的RequestResponseBodyMethodProcessor
int index = handlers.indexOf(handler);
handlers.set(index, decorator);
break;
}
}
// 重新設(shè)置SpringMVC的ReturnValueHandlers
adapter.setReturnValueHandlers(handlers);
}
}
5、總結(jié)
至此完成了定制@ResponseBody注解返回的Json格式,在Controller中返回任何的字符串都可以定制成為我們想要的Json格式。此外SpringMVC還提供了非常多的Handler接口來進(jìn)行Controller的增強(qiáng),可以使用此思路對參數(shù)等進(jìn)行定制化。
到此這篇關(guān)于詳解SpringBoot定制@ResponseBody注解返回的Json格式的文章就介紹到這了,更多相關(guān)SpringBoot @ResponseBody返回Json內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java設(shè)計(jì)模式之原型模式詳細(xì)解析
這篇文章主要介紹了Java設(shè)計(jì)模式之原型模式詳細(xì)解析,原型模式就是用一個(gè)已經(jīng)創(chuàng)建的實(shí)例作為原型,通過復(fù)制該原型對象來創(chuàng)建一個(gè)和原型對象相同的新對象,需要的朋友可以參考下2023-11-11
聊聊springmvc中controller的方法的參數(shù)注解方式
本篇文章主要介紹了聊聊springmvc中controller的方法的參數(shù)注解方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
如何使用Spring+redis實(shí)現(xiàn)對session的分布式管理
本篇文章主要介紹了如何使用Spring+redis實(shí)現(xiàn)對session的分布式管理,本文主要是在Spring中實(shí)現(xiàn)分布式session,采用redis對session進(jìn)行持久化管理,感興趣的小伙伴們可以參考一下2018-06-06

