How can I hook into Spring's @RequestBody argument resolving to resolve my own argument using the body of the request

元气小坏坏 提交于 2021-01-28 01:15:29

问题


In the process of developing our app, we found ourselves doing something like this in our controller:

@RequestMapping(value = "foo", method = RequestMethod.POST)
@ResponseBody
public SimpleMasterWidget doStuff(@RequestBody ClientData clientData, ServerData serverData) throws Exception
{
        pushClientDataToServerData(clientData, serverData);
        //stuff specific to this operation on the serverData
        return whatever;
}

The pushClientDataToServerData(clientData, serverData); call gets duplicated in every POST request. Now, I understand that there really shouldn't be any need to push clientData to serverData, but there is legacy code that forces us to do this.

Currently we are implementing the HandlerMethodArgumentResolver interface to resolve the ServerData argument. To remove all the duplicated pushClientDataToServerData calls I want to be able to resolve the ServerData argument with the ClientData already pushed into it.

Now in the argument resolver, I have access to the NativeWebRequest so I could probably get the request body through there and deserialize it and all that. However, I don't want to have to reimplement what Spring is already doing with the @RequestBody annotation.

So my question boils down to this: Is there a way I can call into Spring's stuff in the argument resolver so that I can get the deserialized ClientData object and call pushClientDataToServerData right within the argument resolver? Then all the controller methods would just look like this:

@RequestMapping(value = "foo", method = RequestMethod.POST)
@ResponseBody
public SimpleMasterWidget doStuff(ServerData serverData) throws Exception
{
        //stuff specific to this operation on the serverData
        return whatever;
}

And the pushClientDataToServerData call would be in only one place.

Thanks in advance.


回答1:


Looks like a good candidate for Spring AOP. Below is just an example of pointcut, you should improve it to catch all possible methods:

@Component
@Aspect
public class PushClientDataAspect {

    @Before(value = "execution(* com.xyz.myapp.dao.*.*(..) && args(clientData, serverData) && @annotation(org.springframework.web.bind.annotation.ResponseBody))")
    public void pushClientData(ClientData clientData, ServerData serverData) {
        pushClientDataToServerData(clientData, serverData);
    }   

}


来源:https://stackoverflow.com/questions/16572432/how-can-i-hook-into-springs-requestbody-argument-resolving-to-resolve-my-own-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!