2

My project consist of many types of sites, like a blog and a forum and a site.

I have specific controllers for the blog, forum and site (and a lot more)

Certain controllers i wish to share between types of site, for example the login controller.

But i only want the login controller to be shared with forum and site.

I use a filter to add a request header "partType" which has value site, forum or blog.

My @RequestMapping of my login controller is:

@RequestMapping(value="/dash/login",  headers={"partType=forum","partType=site" })

This results in mapping:

{[/dash/login/dologin],methods=[GET || POST],headers=[partType=forum && partType=site]}

Notice the && (and). Is it possible to get an || (or) in here?

Because the "partType" header is never a forum and a site, but i do want the logincontroller to support partType forum and site, but not blog, so i can't just remove the header attribute from the requestmapping annotation.

Tinus Tate
  • 2,237
  • 2
  • 12
  • 33
  • 1
    Not with the defaults you would have to write your own rules for that and rewrite part of the `RequestMappingHandlerMapping` for them to get configured. – M. Deinum Jan 18 '18 at 19:44
  • Cheers @M. Deinum , indeed i was already looking at RequestMappingHandlerMapping but the problem with overriding this one is that mvc:annotation-driven is disabled when doing so, rendering all the nice things of spring finding controllers and methods useless. There is a trick when using java config, but i'm still stuck with xml config. – Tinus Tate Jan 18 '18 at 20:09
  • On an side note: i found a suboptimal solution, using an interceptor preHandle() to append "partType" to the uri and using RequestDispatcher to forward the request with the new uri. This works but i'm worried about the performance hit, cause every request now gets forwarded by the RequestDispatcher. – Tinus Tate Jan 18 '18 at 20:09
  • Doesn't matter if you use XML or Java based configuration the solution is the same. Detecting controllers is done by component scanning and what actually processes them is the `RequestMappingHandlerAdapter` so no there isn't an issue (apart from loosing the default configured and detected things from the namespace/annotation). – M. Deinum Jan 19 '18 at 06:19
  • The easiest solution is to create 2 handler mapping methods one for each header and let them call the same (internal) method on the controller. – M. Deinum Jan 19 '18 at 06:20
  • Thanks @M. Deinum for the hints and tips! I just posted a reply explaining how i solved it. – Tinus Tate Jan 19 '18 at 10:41

2 Answers2

3

It sure was a journey through the inner workings of spring mvc. While i was browsing the source code of RequestMappingHandlerMapping in noticed that createRequestMappingInfo looked for RequestCondition on the Controller.

Looking a bit further into the RequestCondition thing i noticed that the default RequestMappingHandlerMapping does nothing with it. While searching online why it ignores RequestCondition i found this post: How to implement @RequestMapping custom properties

This first answer gives a example of RequestCondition and extending RequestMappingHandlerMapping. But extending RequestMappingHandlerMapping means not having <mvc:annotation-driven />.

I messed around with BeanPostProcessor and got that working with a custom RequestMappingHandlerMapping, but writing a wrapper around an existing instance of RequestMappingHandlerMapping is not possible.

Lucky i surfed back to the above url and read the comments which link to a post: Howto get rid of <mvc:annotation-driven />? This one explains how to replace <mvc:annotation-driven /> with custom xml that does the same thing, but allowing to set the RequestMappingHandlerMapping.

After a bit of fiddling around it now works!

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
Tinus Tate
  • 2,237
  • 2
  • 12
  • 33
0

Try using headers=["partType=forum,site"], it might work. It works when you are setting the content-type=application/json,application/xml

JaisAnkit
  • 154
  • 1
  • 6
  • 1
    Thanks for your reply, i just gave it a shot but it doesn't work. When using "partType=forum,site" the header needs to be "partType=forum,site". The , (comma) is ignored and it not threaded as OR. I suspect the "content-type" does something magical. – Tinus Tate Jan 18 '18 at 18:45