问题
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