Spring 3 web request interceptor - how do I get BindingResult? - java

I realy appreciate Spring 3 anoation driven mapping of Web Controllers
I have a lot of Controllers with signatures like:
#RequestMapping(value = "solicitation/create",method = RequestMethod.POST)
public String handleSubmitForm(Model model, #ModelAttribute("solicitation") Solicitation solicitation, BindingResult result)
But my issue is, that I want to write an interceptor that would ho through BindingResults after processing - how do I get them from HttpRequest or HttpResponse?
as intercpetor methods are with alike signature
public boolean postHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

After execution of controller method BindingResult is stored as a model attribute named BindingResult.MODEL_KEY_PREFIX + <name of the model attribute>, later model attributes are merged into request attributes. So, before merging you can use Hurda's own answer, after merging use:
request.getAttribute(BindingResult.MODEL_KEY_PREFIX + "solicitation")

So with big help from #Axtavt I came to conlusion, that you can get to Bind reuslt from ModelAndView in postHandle method:
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
String key = BindingResult.MODEL_KEY_PREFIX + "commandName";
BindingResult br = (BindingResult) modelAndView.getModel().get(key);
}

Related

How to add a new request header to all the existing APIs in the application using spring boot

I'm using Spring boot version 2.0.5.RELEASE in my application. I have got more than 500 Restful APIs in the application. To these APIs, a new request header needs to be added. Is there a way to add header in one place and can be used by all the 500 APIs?
Yes you can write an interceptor for every request at root level and append your headers to that request.You can use prehandle as
This is used to perform operations before sending the request to the
controller.
Below is the code snippet
#Component
public class ProductServiceInterceptor implements HandlerInterceptor {
#Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
#Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exception) throws Exception {}
}
#RestController
#RequestMapping("/headerRequestPath)
Add this at the begining of your code file. That way all path's will be appended with header 'headerRequestPath'

Spring create a method controller that executes in every page

Currently , I am implementing the hreflang meta tag in my site and I am facing a problem , I need to create a method that must be executed in every page (in order to load the hreflangs into the model and pass them to the JSP) of my site and this method must have this parameters HttpServletRequest request, HttpServletResponse response.
I tried with this :
#RequestMapping(value = {"/*"})
public class GLobalPageController {
#ModelAttribute
public void setupHreflangs(Model model, HttpServletRequest request, final HttpServletResponse response) {
//code
}
}
But its not working , any idea about how can I achieve this ?

How to access a spring-mvc flash redirectAttribute in the filter chain before the DispatcherServlet is invoked?

I have the following controller:
#Controller
#RequestMapping("/my-account")
public class AccountController {
#RequestMapping(value = "/foo/post",
method = RequestMethod.POST)
public String doPost(final RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute("flashAttribute", "flashAttributeValue");
return "redirect:/my-account/foo/get";
}
#RequestMapping(value = "/foo/get",
method = RequestMethod.GET)
public void doGet(final HttpServletRequest request, final Model model) {
System.out.println("in request: " + RequestContextUtils.getInputFlashMap(request).get("flashAttribute"));
System.out.println("in model: " + model.asMap().get("flashAttribute"));
}
}
I would also like to access the flash attribute flashAttribute during the invocation of a filter in the filter chain that finally invokes springs default DispatcherServlet which in turn invokes AccountController.
public class FlashAttributeBasedFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain)
throws ServletException, IOException {
String flashAttribute = // how to access the redirectAttribute flashAttribute here?
// do something with flashAttribute ...
filterChain.doFilter(request, response);
}
The DispatcherServlet uses a org.springframework.web.servlet.FlashMapManager that handles these flash attributes, but it doesn't provide read-only access so I think I would be messing something up if I would use it in the filter. And also the FlashMapManager instance is kept in the dispatcher servlet privately.
Does anybody have an idea how I can make the redirect attribute accessible in the filter chain for the GET request succeeding the POST?
Considering that all these methods return null into my filter (I don't understand why):
RequestContextUtils.getFlashMapManager(httpRequest)
RequestContextUtils.getInputFlashMap(httpRequest)
RequestContextUtils.getOutputFlashMap(httpRequest)
I used a drastic solution: read directly the into the session (where flash attributes are stored).
CopyOnWriteArrayList<FlashMap> what = (CopyOnWriteArrayList<FlashMap>) httpRequest.getSession().getAttribute("org.springframework.web.servlet.support.SessionFlashMapManager.FLASH_MAPS");
if (what != null) {
FlashMap flashMap = what.get(0);
[read flashMap as you read a HashMap]
}
I know, this code is super ugly but at the moment I don't find another solution.
Had the same problem, following works for me.
FlashMap flashMap = new SessionFlashMapManager().retrieveAndUpdate(request, null);
flashMap.get("parameter");

How can I run common code for most requests in my Spring MVC Web App?

i.e.
I have various URLs mapped using Spring MVC RequestMapping
#RequestMapping(value = "/mystuff", method = RequestMethod.GET)
#RequestMapping(value = "/mystuff/dsf", method = RequestMethod.GET)
#RequestMapping(value = "/mystuff/eee", method = RequestMethod.GET)
etc
I want to run some common action before about 90% of my requests. These are across several controllers.
Is there anyway to do that without delving into AOP? And if I have to use aspects, any guidance on how to do this?!
Thanks!
More info:
It is to run some app specific security - we are chained to a parent security set up, which we need to read and call into, and then need to access a cookie prior to some most of ours calls, but not all.
You can use an Interceptor:
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-handlermapping
Interceptor is the solution. It has methods preHandler and postHandler, which will be called before and after each request respectively. You can hook into each HTTPServletRequest object and also by pass few by digging it.
here is a sample code:
#Component
public class AuthCodeInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// set few parameters to handle ajax request from different host
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
response.addHeader("Access-Control-Max-Age", "1000");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Cache-Control", "private");
String reqUri = request.getRequestURI();
String serviceName = reqUri.substring(reqUri.lastIndexOf("/") + 1,
reqUri.length());
if (serviceName.equals("SOMETHING")) {
}
return super.preHandle(request, response, handler);
}
#Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
}
}
The HandlerInterceptor.preHandle() method gives you access to the request and response and also the target handler. In Spring 3.1 that will be of type HandlerMethod, which gives you access to the target controller class and method. If it helps you can try excluding entire controller classes by type name, which would be strongly typed and without specifying explicit URLs.
Another option would be created an interceptor mapped to a set of URL patterns. See the section on configuring Spring MVC in the reference documentation.

How to differentiate domains using Spring RequestMapping

I'm trying to use different methodes depending on from which domain the request is send.
e.g.
#RequestMapping(value = "/index.html", domain = "google.de", method = RequestMethod.GET)
public ModelAndView handleDeRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
}
#RequestMapping(value = "/index.html", domain = "google.com", method = RequestMethod.GET)
public ModelAndView handleComRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
}
The two domains are routing to one, the same, server and webapp, but I'd like to return a different modelAndView in the controllerclass depending from which URL the reqeust is comming.
Any ideas?
cheers.
Can you not have a single handleRequest method where you simply check HTTP referrer header and act correspondingly - fork into different methods, etc.?

Categories

Resources