Custom ArgumentResolver SpringMVC implement a custom message type conversion

Part of the convert is based on RequestResponseBodyMethodProcessor, so the need to add parameters and return @RequestBodyand @ResponseBody
here I wrote a MyArgumentResolverto abandon @RequestBodyrestrictions

@PostMapping(value = "/properties2",
            consumes = "text/properties;charset=utf-8")
    public Properties properties2(Properties properties){
        return properties;
    }
public class MyArgumentResolver implements HandlerMethodArgumentResolver {


    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(Properties.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        String contentType = request.getContentType();
        MediaType mediaType = MediaType.parseMediaType(contentType);
        Charset charset = mediaType.getCharset()== null ? Charset.forName("utf-8") : mediaType.getCharset();

        InputStream inputStream = request.getInputStream();
        Reader reader = new InputStreamReader(inputStream,charset);
        Properties properties = new Properties();
        properties.load(reader);

        return properties;
    }
}

Our parser support all parameters into the parameters for the Propertiestype of resolution, the specific conversion logic is basically the same with the one of the convert, there can actually be delegated to convert the internal SpringMVC also commissioned the analysis, where convenience implemented directly here the
register after, but custom resolver is built when adding back the parser, as shown below NOTE:
Here Insert Picture Description
Thus a simple method using the following register is not feasible

@Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(0,new MyArgumentResolver());
    }

Register here does not make our custom parser parser all located in the top, but all of the custom parser first place, but still in the back of the built-in parser.
Since the properties belonging to the map type, map type parser parser is built, we can not be invoked to own parser as expected.
Another method used here parses

@Autowired
    private RequestMappingHandlerAdapter adapter;

    @PostConstruct
    public void init(){
        List<HandlerMethodArgumentResolver> old = adapter.getArgumentResolvers();
        List<HandlerMethodArgumentResolver> newList = new ArrayList<>(old.size()+1);
        newList.add(new MyArgumentResolver());
        newList.addAll(old);
        adapter.setArgumentResolvers(newList);
    }

Using the initialization method of the enrolled list parser coverage, due to the returned list can not be changed, so to achieve a new copy of an array of add

Here Insert Picture Description

PS Several recent articles about SpringMVC converters are reference SpringBoot of Ma Ying-jeou of course, learned a lot, thanks to big brother

Published 98 original articles · won praise 9 · views 10000 +

Guess you like

Origin blog.csdn.net/Mutou_ren/article/details/104083988
Recommended