From e5fd51761263bf4591f841ec322644c01254287f Mon Sep 17 00:00:00 2001 From: oyo Date: Thu, 29 Aug 2024 17:08:52 +0800 Subject: [PATCH] ResponseJsonMethodReturnValueHandler --- .../ResponseJsonMethodReturnValueHandler.java | 53 ++++++++++++++ .../ResponseJsonWebMvcConfiguration.java | 69 +++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 template/entrance/web/src/main/java/{{.packagePath}}/entrance/web/response/ResponseJsonMethodReturnValueHandler.java create mode 100644 template/entrance/web/src/main/java/{{.packagePath}}/entrance/web/response/ResponseJsonWebMvcConfiguration.java diff --git a/template/entrance/web/src/main/java/{{.packagePath}}/entrance/web/response/ResponseJsonMethodReturnValueHandler.java b/template/entrance/web/src/main/java/{{.packagePath}}/entrance/web/response/ResponseJsonMethodReturnValueHandler.java new file mode 100644 index 0000000..db46922 --- /dev/null +++ b/template/entrance/web/src/main/java/{{.packagePath}}/entrance/web/response/ResponseJsonMethodReturnValueHandler.java @@ -0,0 +1,53 @@ +package {{ .package }}.entrance.web.response; + +import com.libawall.framework.core.base.result.ResultDTO; +import com.vs.common.util.rpc.pub.PublicInterface; +import com.vs.ox.common.utils.ObjectMapperFactory; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.MethodParameter; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.server.ServletServerHttpResponse; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodReturnValueHandler; +import org.springframework.web.method.support.ModelAndViewContainer; + +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; +import java.util.Collections; + +/** + * 处理 Controller 里的返回值,从 Object 包装为 ResultDTO 类型 + */ +@Slf4j +public class ResponseJsonMethodReturnValueHandler implements HandlerMethodReturnValueHandler, InitializingBean { + private HttpMessageConverter messageConverter; + + public ResponseJsonMethodReturnValueHandler() { + } + + public void afterPropertiesSet() { + if (this.messageConverter == null) { + this.messageConverter = new MappingJackson2HttpMessageConverter(ObjectMapperFactory.getDefaultObjectMapper()); + } + + } + + public boolean supportsReturnType(MethodParameter returnType) { + return true; + } + + public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { + Method method = returnType.getMethod(); + //目前只处理自动生成接口 + PublicInterface annotation = method.getAnnotation(PublicInterface.class); + if (annotation != null) { + mavContainer.setRequestHandled(true); + Object result = returnValue == null ? ResultDTO.ok(Collections.emptyMap()) : ResultDTO.ok((returnValue)); + ServletServerHttpResponse response = new ServletServerHttpResponse(webRequest.getNativeResponse(HttpServletResponse.class)); + this.messageConverter.write(result, new MediaType(MediaType.APPLICATION_JSON, Collections.singletonMap("charset", "utf-8")), response); + } + } +} diff --git a/template/entrance/web/src/main/java/{{.packagePath}}/entrance/web/response/ResponseJsonWebMvcConfiguration.java b/template/entrance/web/src/main/java/{{.packagePath}}/entrance/web/response/ResponseJsonWebMvcConfiguration.java new file mode 100644 index 0000000..004a91d --- /dev/null +++ b/template/entrance/web/src/main/java/{{.packagePath}}/entrance/web/response/ResponseJsonWebMvcConfiguration.java @@ -0,0 +1,69 @@ +package {{ .package }}.entrance.web.response; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.annotation.MapMethodProcessor; +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.ViewNameMethodReturnValueHandler; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +@Configuration +public class ResponseJsonWebMvcConfiguration implements ApplicationContextAware, WebMvcConfigurer { + private RequestMappingHandlerAdapter requestMappingHandlerAdapter; + private ApplicationContext applicationContext; + + void init() { + List returnValueHandlers = this.requestMappingHandlerAdapter.getReturnValueHandlers(); + Iterator iterator = returnValueHandlers.iterator(); + List newProcessors = new ArrayList<>(); + while (iterator.hasNext()) { + HandlerMethodReturnValueHandler next = iterator.next(); + //在controller中直接返回map,不被默认的MapMethodProcessor拦截 + if (next instanceof MapMethodProcessor || + //在controller中直接返回String,不被默认的ViewNameMethodReturnValueHandler拦截 + next instanceof ViewNameMethodReturnValueHandler) { + } else { + newProcessors.add(next); + } + } + this.requestMappingHandlerAdapter.setReturnValueHandlers(newProcessors); + } + + @Override + public void addReturnValueHandlers(List returnValueHandlers) { + ResponseJsonMethodReturnValueHandler responseJsonMethodReturnValueHandler = new ResponseJsonMethodReturnValueHandler(); + responseJsonMethodReturnValueHandler.afterPropertiesSet(); + returnValueHandlers.add(responseJsonMethodReturnValueHandler); + } + + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Bean + ServletContextListener listener1() { + return new ServletContextListener() { + @Override + public void contextInitialized(ServletContextEvent sce) { + requestMappingHandlerAdapter = applicationContext.getBean(RequestMappingHandlerAdapter.class); + init(); + } + + @Override + public void contextDestroyed(ServletContextEvent sce) { + } + }; + } +}