Замените RequestResponseBodyMethodProcessor на CustomMethodProcessor, используя BeanPostProcessor - PullRequest
0 голосов
/ 14 сентября 2018

Как мне поменять RequestResponseBodyMethodProcessor с CustomRequestResponseBodyMethodProcessor в методе BeanPostProcessor postProcessAfterInitialization()?

Я скопировал весь код из RequestResponseBodyMethodProcessor и внес некоторые изменения в мой CustomRequestResponseBodyMethodProcessor.

Теперь я хочу, чтобы Spring использовал мой CustomRequestResponseBodyMethodProcessor, а не встроенный.

Итак, попытался перезаписать в postProcessAfterInitialization(), внедрив BeanPostProcessor.

На форуме ниже, где написано«создайте новый список, замените обычный RequestResponseBodyMethodProcessor вашей пользовательской реализацией», как я могу получить дескриптор для этого?

Для справки:

http://forum.spring.io/forum/spring-projects/web/130803-how-to-extend-requestresponsebodymethodprocessor-and-configure-it-in-webmvc-config-xm

Псевдокод:

class BaseInsert {
    commonattribute1;
    commonattribute1;
}

class ChildInsert extends BaseInsert {
    childattribute1;
    childattribute2;
}

@PostMapping("/abc")
public Resource<?> insert(@RequestBody BaseInsert baseInsert){
...
}

Я изменил код в CustomRequestResponseBodyMethodProcessor, чтобы присвоить ChildInsert в BaseInsert.

1 Ответ

0 голосов
/ 06 октября 2018

Решение 1: Я буду рекомендовать это решение чаще всего

@Configuration
@EnableWebMvc
public class AdapterConfig extends WebMvcConfigurerAdapter {
    private final ApplicationContext applicationContext;
    @Autowired
    public TrackingAdapterConfig(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver>reso) {
        super.addArgumentResolvers(reso);
        reso.add( new CustomRequestBodyMethodProcessor(); }
}

public class CustomProcessor extends RequestResponseBodyMethodProcessor {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
    return (parameter.getNestedGenericParameterType().getTypeName()
        .equalsIgnoreCase(BaseInsert.class.getName()));
    }

    @Override protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter,Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {                                               
        BaseInsert request = childInsert;
        return super.readWithMessageConverters(webRequest, parameter, request.getClass());
    }
}

Решение 2: Это также хорошее решение, но менее производительное, поскольку интерфейс BeanPostProcessor имеет 2методы 'postProcessBeforeInitialization ()' и 'postProcessAfterInitialization ()'.

Поэтому, когда вы предоставляете свою реализацию этого интерфейса BeanPostProcessor с классом, аннотированным как'@Configuration'.

postProcessBeforeInitialization () - Thisметод вызывается каждый раз перед созданием bean-компонентов

postProcessAfterInitialization () - этот метод вызывается каждый раз после создания bean-компонентов. Это место, где CustomResolver можно добавить в список распознавателей

@Configuration
public class TestBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equalsIgnoreCase("requestMappingHandlerAdapter")) {
            RequestMappingHandlerAdapter requestMappingHandlerAdapter = (RequestMappingHandlerAdapter) bean;
            List<HandlerMethodArgumentResolver> argumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers();
            List<HandlerMethodArgumentResolver> modifiedArgumentResolvers = new ArrayList<>(argumentResolvers.size());                
            for(int i =1; i< argumentResolvers.size();i++){
                modifiedArgumentResolvers.add(argumentResolvers.get(i));
            }
            modifiedArgumentResolvers.add(new TestRequestBodyMethodProcessor(requestMappingHandlerAdapter.getMessageConverters(), new ArrayList<Object>()));
            ((RequestMappingHandlerAdapter) bean).setArgumentResolvers(null);
            ((RequestMappingHandlerAdapter) bean).setArgumentResolvers(modifiedArgumentResolvers);
        }
        return bean;
    }
}

public class TestRequestBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {

    public TestRequestBodyMethodProcessor(List<HttpMessageConverter<?>> converters) {
        super(converters);
    }

    public TestRequestBodyMethodProcessor(List<HttpMessageConverter<?>> converters, ContentNegotiationManager manager) {
        super(converters, manager);
    }

    public TestRequestBodyMethodProcessor(List<HttpMessageConverter<?>> converters, List<Object> requestResponseBodyAdvice) {
        super(converters, null, requestResponseBodyAdvice);
    }

    public TestRequestBodyMethodProcessor(List<HttpMessageConverter<?>> converters,
                                          ContentNegotiationManager manager, List<Object> requestResponseBodyAdvice) {
        super(converters, manager, requestResponseBodyAdvice);
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(RequestBody.class);
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) ||
                returnType.hasMethodAnnotation(ResponseBody.class));
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

        parameter = parameter.nestedIfOptional();
        BaseInsert trans_type_code = ;
        Object arg = readWithMessageConverters(webRequest, parameter,
                Test.getModelClassObject().getClass());
        String name = Conventions.getVariableNameForParameter(parameter);

        WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
        if (arg != null) {
            validateIfApplicable(binder, parameter);
            if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
                throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
            }
        }
        mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());

        return adaptArgumentIfNecessary(arg, parameter);
    }

    @Override
    protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter,
                                                   Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {

        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);
        Object arg = readWithMessageConverters(inputMessage, parameter, paramType);
        if (arg == null) {
            if (checkRequired(parameter)) {
                throw new HttpMessageNotReadableException("Required request body is missing: " +
                        parameter.getMethod().toGenericString());
            }
        }
        return arg;
    }

    protected boolean checkRequired(MethodParameter parameter) {
        return (parameter.getParameterAnnotation(RequestBody.class).required() && !parameter.isOptional());
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
            throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {

        mavContainer.setRequestHandled(true);
        ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
        ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
        // Try even with null return value. ResponseBodyAdvice could get involved.
        writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...