0

I've spent a few days researching this, but haven't found a suitable answer for my situation. I have a Spring 3.1 MVC application. Currently, some vendors log into the application via a web client in which case the user information is stored in the session. I want to expose some services to other vendors via RESTFul web services, but have the vendor pass their vendor id as a part of the URI or via PARAMS. Is there a way to handle the vendor id in a single place that then forwards to the respective controller for request processing? Should the vendor id be a part of the URI or should the vendor id be passed in the request body? I've looked into Interceptors, but how would I do this with multiple URIs or for every controller for the RESTFul webservice? Any suggestion would be greatly appreciated

2
  • What do you mean by handling the request in a single place? Can you provide an example of what you mean?
    – Bart
    Commented Jul 27, 2013 at 18:16
  • I mean in a generic way via Interceptor, Filter, etc. I don't want to have the code in all the controllers. I want to pass the vendor id as part of the URI template, but was looking for a way to convert the vendor id param into a vendor object which has more useful information. Passing id in the header as Solubis suggests might be good, but the web service could be going through a proxy in which case the header might be rewritten losing the custom header info. Other suggestions are welcomed Commented Jul 28, 2013 at 4:00

2 Answers 2

1

Having a custom header is the most clean option but parameters also work equally well. In the interceptors preHandle method you could lookup the vendor by either a header or a parameter and attach it to the request by adding the object to it's attributes.

request.addAttribute("vendor", myVendorInstance);

From that point on the vendor can be retrieved from the request like:

Vendor vendor = (Vendor) request.getAttribute("vendor");

Interceptors can be mapped to any URL you like using a mapping e.g.

<mvc:interceptor>
    <mvc:mapping path="/vendors/**" />
    <bean class="my.package.VendorLookupInterceptor" />
</mvc:interceptor>

Another way of making the vendor object available to controllers is to inject it. For instance, say that controllers interested in the object should implement this interface.

public interface VendorAware {
    public void setVendor(Vendor vendor);
}

Controllers implementing this interface could be handled by the interceptor and get the vendor injected.

if (handler instanceof HandlerMethod) {
    Object bean = ((HandlerMethod) handler).getBean();

    if (bean instanceof VendorAware) {
        Vendor vendor = getVendor();
        ((VendorAware) bean).setVendor(vendor);
    }
}
4
  • So the interceptors will intercept the requests before they reach the controllers?
    – acdcjunior
    Commented Jul 28, 2013 at 7:37
  • If you use the preHandle method. Yes.
    – Bart
    Commented Jul 28, 2013 at 7:37
  • Bart, that is the direction that I was heading in. Not sure why I talked myself out of it. I've made a slight modification to your suggestion and put the vendor object on the current thread so that all controller can access it in a static way via a generic spring bean. Commented Jul 29, 2013 at 0:10
  • @user2626064 There are a lot of routes one could take to tackle the problem. While reading your comment another method came to mind. It's a bit more clean and scoped. I don't know if it will be of any use to you but still felt I should add it to my answer.
    – Bart
    Commented Jul 29, 2013 at 6:54
0

Obviously the problem with adding the vendor id to the URI is that it affects all your URL's, so cannot easily make the controller generic. Another way is to have the vendor id passed as a header to the controllers. You could use the X-User header.

Then you can write some kind of handler to check for this header, possibilities:

  • spring interceptor
  • servlet filter
  • spring security
  • aspectj

Not the answer you're looking for? Browse other questions tagged or ask your own question.