0

In our web application we have a lot of REST services. Suddenly it found out that we need to modify one object inside of each request before we go on. So let's say we have n different controllers with REST services. In each controller, before we call the service from next layer, we need to modify an object inside the request.

The question is how to achieve this without providing hundreds of changes inside the controllers... Is there any simple way to do this?

UPDATE:

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @RequestMapping(path = "/order", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public OrderResponse getOrderData(@RequestHeader HttpHeaders httpHeaders,
            @RequestBody OrderDataRequest orderDataRequest) {

        // Use here interceptor to modify the object Details 
        // (inside OrderDataRequest) before below call:
        OrderResponse resp = orderService.getOrderData(orderDataRequest);

        return resp;
    }

    @RequestMapping(path = "/cancel/{orderId}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public boolean cancelOrder(@RequestHeader HttpHeaders httpHeaders,
            @RequestBody Details details, @PathVariable Integer orderId) {

        // Use here interceptor to modify object Details before below call:
        return orderService.cancelOrder(details, orderId);
    }
}

In each controller I need to modift the object Details, which as you can see could be inside another object like in the first example or exist alone like in the second option.

Lui
  • 594
  • 3
  • 10
  • 23

2 Answers2

0

You should consider writing an interceptor, that would allow you to do what you want .

You could also use AOP to do this.. though, I think it's quite over-complicated, especially when such a solution already exists through interceptors!

EDIT : A few other links :

EDIT 2 : Follow the "before advice" from mykong.com example, then go that way to edit your specific object according to its class (for exemple) :

package com.your.company;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class HijackBeforeMethod implements MethodBeforeAdvice
{
    @Override
    public void before(Method method, Object[] args, Object target)
        throws Throwable {
            for(Object arg :  args) {
                if(com.your.company.OrderDataRequest.class.isAssignableFrom(arg.getClass())) {
                    // update you object here
                }
            }
    }
}

- Get response body - Json To Java

Marvin
  • 1,650
  • 4
  • 19
  • 41
  • So in my case it would be enough to add all paths patterns with ("/*") to the interceptor registry or it's not the best idea to do it? Basically each service contains the object which I need to modify, but it's right now. I don't know if in the future it will change... And how to modify the object inside of each request with this interceptor? – Lui Nov 15 '17 at 14:55
  • Nope... I'm confused... How with this interceptor modify the one of the object from the incoming request and do this before calling the method from the business layer? Look at my example in updated question. – Lui Nov 15 '17 at 15:10
  • If you set up the interceptor so that it happens before your controller, you have access to the request body before the controller is reached by the request. You can then do whatever you need here. Take note that you will have raw data (text/json) and you may need to unmarshall it or access it through keyword to modify your target.I add a few links to my post – Marvin Nov 16 '17 at 09:11
  • You are saying that " have access to the request body before the controller is reached by the request". So what will happen when the request reach my controller? As I mentioned I want to modify the request before the call to the business layer is done. So it means, that I want to keep some objects from the request as they are coming and some of them I want to override. – Lui Nov 16 '17 at 09:49
  • Enventually, I realize it may be easier to perform AOP here : since you need to access a complex object according to some condition. AOP will help you access the already-unmarshalled object , rather than doing it on your own. I edited my post again using mkyong example as a base – Marvin Nov 16 '17 at 10:55
0

You can use Spring AOP to achieve this. Another option using traditional Filters.

Har Krishan
  • 273
  • 1
  • 11
  • I followed [this link](https://stackoverflow.com/questions/27504696/how-to-change-the-posted-values-with-a-spring-mvc-interceptor), but its not working for some reasons... I'm reaching the wrapper constructor, but not the getParameter method... – Lui Nov 15 '17 at 18:04