HandlerInterceptorAdapter, JSON encoding and response post-processing

Previous construction

I had a Spring controller built like this:

@RequestMapping(value = "/rest/funf/{datatype}", method = RequestMethod.GET)
public ModelAndView getFunfData(@PathVariable("datatype") String dataType,
        WebRequest request) throws HttpException {

      

I also had HandlerInterceptorAdapter

one that did pre and post-processing (changing the returned model as per policy). The signature for the handler after processing is as follows

@Override
public void postHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {

      

It really worked. The REST API returned a non-well-structured JSON payload, but at least the interceptor (policy point) was able to anonymize (strip the user's personal data) from the model and replace it.

Thing is, with the old design, I managed to get the answer before it was sent out, change it and put it back in the instance ModelAndView

. No need to post code for brevity.

New design

I have now discovered a new design that helps me overcome my lack of response structure.

When I had it return new ModelAndView(jacksonView_instance, "data", dataToConvertToJson)

, it was structured as

{
    "data": {
        "myAttr1":"myVal1"
     }
}

      

which is bad when the receiving program wants to convert the payload to JSON. So I found

@RequestMapping(value = "/rest/funf/{datatype}", method = RequestMethod.GET, produces = { "application/json" })
    public @ResponseBody
    Object[] getFunfData(@PathVariable("datatype") String dataType,
            WebRequest request) throws HttpException {

      

This simplified code is a bit, and most importantly made a well structured answer , for example

{
    "myAttr1":"myVal1"
}

      

This is ok with a REST design project, but

Problem

Now the HandlerInterceptor will no longer be able to retrieve the model and hence the object that I am returning from my API (this is a FUNF related API that handles personal data, even sensitive data written on mobile devices).

So, if I need to anonymize the records, I cannot do it in the interceptor like before

Workaround

I am aware that I can kill the interceptor and enforce enforcement rights in the API, but this is not a very good design even if the PEP that does authorization in preHandle

and the compliance obligation postHandle

is currently a Spring bean automatically created. Copying and pasting code into an API is a bad idea when dealing with multiple APIs and an opportunity to change / extend the PEP implementation in the medium term.

Anyway, formulate a direct question, explaining the context well

Question:

Given a generic Spring MVC API that returns an object to be handled by the content broker

@RequestMapping(value = "/path/{variable}", method = RequestMethod.GET)
public @ResponseBody Object api() {

      

how can I intercept that returned object in the outer class to perform modifications to it? (e.g. replace with a new instance of an object that will be returned to the client)

+3


source to share


1 answer


It looks like this might not be possible in Spring MVC. I just saw the code in a debug session.

When you use ModelAndView

, Spring MVC stores the MaV in a variable that lives before postHandle

and then writes it to the response body.

Instead, when you use @ResponseBody

and return a value, the value of which is processed directly in the call loop, using MessageConverter

to write to the response.



Since the response is a unidirectional network flow, it is too late to intercept it.

The solution should be based on a different approach than handlers such as AOP interceptors applied directly to controller methods.

+2


source







All Articles