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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
public class ControllessMethodArgumentReturnValueHandler implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {
private final List<HandlerMethodReturnValueHandler> returnValueHandlers; private final List<HandlerMethodArgumentResolver> argumentResolvers; private final ServiceRequestResponseBodyMethodProcessor serviceRequestResponseBodyMethodProcessor;
private final ApplicationContext applicationContext;
public ControllessMethodArgumentReturnValueHandler(RequestMappingHandlerAdapter requestMappingHandlerAdapter, ApplicationContext applicationContext) { this.returnValueHandlers = requestMappingHandlerAdapter.getReturnValueHandlers(); this.argumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers(); this.serviceRequestResponseBodyMethodProcessor = new ServiceRequestResponseBodyMethodProcessor(requestMappingHandlerAdapter.getMessageConverters()); this.applicationContext = applicationContext; }
@Override public boolean supportsParameter(MethodParameter parameter) { return isService(parameter.getExecutable()) || argumentResolvers.stream().anyMatch(handlerMethodArgumentResolver -> handlerMethodArgumentResolver.supportsParameter(parameter)); }
@Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { if (isService(parameter.getExecutable())) { if (BeanUtils.isSimpleProperty(parameter.getNestedParameterType())) { return argumentResolvers.stream() .filter(handlerMethodArgumentResolver -> handlerMethodArgumentResolver instanceof RequestParamMethodArgumentResolver) .findFirst() .map(handlerMethodArgumentResolver -> resolveArgument(handlerMethodArgumentResolver, parameter, mavContainer, webRequest, binderFactory)) .orElse(null);
} return resolveArgument(serviceRequestResponseBodyMethodProcessor, parameter, mavContainer, webRequest, binderFactory); } return argumentResolvers.stream() .filter(handlerMethodArgumentResolver -> handlerMethodArgumentResolver.supportsParameter(parameter)) .findFirst() .map(handlerMethodArgumentResolver -> resolveArgument(handlerMethodArgumentResolver, parameter, mavContainer, webRequest, binderFactory)) .orElse(null); }
@Override public boolean supportsReturnType(MethodParameter returnType) { return isService(returnType.getExecutable()) || returnValueHandlers.stream().anyMatch(returnValueHandler -> returnValueHandler.supportsReturnType(returnType)); }
@Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { if (isService(returnType.getExecutable())) { handleReturnValue(serviceRequestResponseBodyMethodProcessor, returnValue, returnType, mavContainer, webRequest); } else { returnValueHandlers.stream() .filter(returnValueHandler -> returnValueHandler.supportsReturnType(returnType)) .findFirst() .ifPresent(returnValueHandler -> handleReturnValue(returnValueHandler, returnValue, returnType, mavContainer, webRequest)); } }
private boolean isService(Executable executable) { Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Service.class); Class<?> declaringClass = executable.getDeclaringClass(); Map<String, ?> beansOfType = applicationContext.getBeansOfType(declaringClass); HashSet<?> objects = new HashSet<>(beansOfType.values()); return beans.values().stream() .anyMatch(objects::contains); }
private Object resolveArgument(HandlerMethodArgumentResolver handlerMethodArgumentResolver, MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { try { return handlerMethodArgumentResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); } catch (Exception e) { throw new RuntimeException(e); } }
private void handleReturnValue(HandlerMethodReturnValueHandler returnValueHandler, Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) { try { returnValueHandler.handleReturnValue(returnValue, returnType, mavContainer, webRequest); } catch (Exception e) { throw new RuntimeException(e); } }
static class ServiceRequestResponseBodyMethodProcessor extends RequestResponseBodyMethodProcessor {
public ServiceRequestResponseBodyMethodProcessor(List<HttpMessageConverter<?>> converters) { super(converters); }
@Override protected boolean checkRequired(MethodParameter parameter) { return true; } }
}
|