简体   繁体   中英

Setting up a mixed configuration for annotation-based Spring MVC controllers

I have a number of controllers with various request handlers in my Spring 3.x project (all annotation-based, using @Controller and @RequestMapping ).

Currently, the application context just defines DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter beans. If I understand it correctly, these could also be replaced with <mvc:annotation-driven/> .
The existing controllers mostly fill a model that is passed in via the parameters and then return a view name as a string. The mapping is done by standard DefaultRequestToViewNameTranslator and InternalResourceViewResolver beans.

Now I would like to introduce a new controller, which needs an HttpMessageConverter (it will be a MappingJacksonHttpMessageConverter ) and a HandlerExceptionResolver specific to this controller.

The existing controllers should not be affected in any way. Neither should their requests and responses be converted by the message converter, nor should any exceptions be handled by the exception resolver.


Is there a way to do this without dropping annotation-based configuration for the new controller? Is there a way to set the message converter and the exception resolver specifically for one controller, without giving up the URL routing based on @RequestMapping ?

Or is there maybe a way to choose a converter/resolver configuration using an annotation on the controller?

If not, what's the next best approach to do this?

If you annotate your method with @ExceptionHandler as it is stated here it will only handle the exceptions thrown by the methods of the controller where it is placed. So it won't affect the other ones.

Regarding HttpMessageConverter, I'm not sure if what I'm going to say can be applied to HttpMessageConverter (because I have never used it and I'm not sure if it can be treated as other converters), but if you can create a conversionService with it you could do something like this in the controller:

@Autowired
private ConversionService conversionService;

@InitBinder
public void initBinder(WebDataBinder binder){
    binder.setConversionService(conversionService);
}

and the conversionService will only be applied to the controller method of this initBinder.

In the special case that there's no overlapping of media types between your controllers (eg one accepts and responds only with JSON, all others receive/respond with XML), you can rely on the Content-Type and Accept header matching of Spring to do the mapping to the corresponding HttpMessageConverter for you.

This does not resolve the original question, though. It is just a workaround if you're lucky enough to be in this special situation. You also can't prevent one controller to unterstand/respond with a media type it wasn't supposed to support this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM