Spring MVC controller methods accespt different parameters that are injected before the method is invoked. Like HttpServletRequest, HttpServletResponse, java.security.Principal, etc.
#RequestMapping("/test")
public String test(HttpServletRequest req, Principal user){}
How can I declare something that can be injected in a controlelr method?
#RequestMapping("/test")
public String test(MyCustomInjectable myInjectable){}
More on the specific case:
I want to parse the HttpServletRequest in some servlet filter and construct an object that will be used in the controller method. More precisely I will parse a JWT token and access the claims.
There is an option to create custom HandlerMethodArgumentResolver.
Related
In a controller, I can access all the #RequestHeaders using the following code
#RestController
public class MyController {
#RequestMapping(value = "/mypath", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity moveEnrollment(#RequestHeader Map<String, String> headers) {
..invoke business logic
}
}
How do I inject the headers into a Spring service bean which is not a controller? Otherwise i need to pass on this hashmap all over the place.
I know that I can inject HttpServletRequest and then get the headers but it would be easier if it can be injected directly.
What you are missing is that the HttpServletRequest is an instance of one request coming to your web app. It's not a global bean that you can inject in your other classes. It's a new instance with every request.
The same goes with your headers, they are only valid in the context of a request. You can't globally inject them anywhere.
In your controllers they are passed to your controller methods and as far I as I remember they are not available in your non-controller instances.
There are other types of handlers such as ExceptionHandler and Controller advice that you have access the request in the methods but not on arbitrary classes. It has to be in the context of a request.
I am trying to avoid declaring/supplying same set of parameters to Spring MVC controller methods used throughout my application.
These are specific spring related parameters and not domain models/application objects.
These parameters include :
Device, Model, Principal, HttpServletRequest, HttpServletResponse.
Is there a way to encapsulate all these into single object (or probably custom annotation) to supply these to all controller methods?
I am currently working on a rest api and I need to validate the HttpServletRequest object which my Controller method receives. Is there a way to validate it using the #Valid annotation? I need to check the content type, request body? I know we can use the #Valid annotation to validate user defined classes. Can we use the same for HttpServletRequest Class? If not what other options do i have?
thanks,
kayzid
I came across authentication code in my company's java code. The application is a set of several REST services built on Spring MVC. There is a method that gets called in one of the authentication services on the HttpServletRequest object called getHeader(). And the method retrieves an AuthId. Why would they use HttpServletRequest in a spring MVC application? What are the benefits of using this servlet type code in the spring app? What would this method do? Any alternatives?
Spring MVC provides a lot of fabulous abstractions on top of HttpServletRequest, so you can avoid its low-level implementation details. You rarely need to access it directly.
For example, you could get a header value like Content-Type like this:
#GET
#Path("/myService")
public Response doSomething(#HeaderParam("Content-Type") String contentType) {
...
}
But there are times when you do need to access the HttpServletRequest directly--usually when you are using another API that demands it. If you are using some other library with a method you need that takes HttpServletRequest, then you got to grab it from Spring MVC directly.
For example, check out this method in this random UrlUtil class:
public static String encodeUrlPathSegment(String pathSegment, HttpServletRequest httpServletRequest) {
//Get a path segment
}
You have no choice but to grab HttpServletRequest from Spring MVC.
Spring MVC is built on the Servlet API. Anything you could do with a Servlet, you can therefore do with Spring MVC. What the Spring MVC framework provides is a wrapper to code a web application in a specific architectural style. This wrapper adds behavior and some times simplifies tasks.
Why would they use HttpServletRequest in a spring MVC application?
In this case, because it is the most direct way to get the header.
What are the benefits of using this servlet type code in the spring
app?
Spring doesn't have to wrap anything. You get it directly from the source.
What would this method do?
Read the javadoc.
Any alternatives?
In a #Controller class' handler method, you can declare a parameter annotated with #RequestHeader and have Spring pass an argument that it retrieves from the HttpServletRequest headers.
This is, by default, restricted to #Controller methods annotated with #RequestMapping. If your service class is a HandlerInterceptor, Filter, or other type of class and simply has a reference to the HttpServletRequest object, there is nothing more you can do than retrieve it directly with getHeader(String).
Here is an alternative : Spring MVC define the parameter annotation #RequestHeader to read httpServletRequest headers :
#RequestMapping(...)
public #ResponseBody String myMethod(#RequestHeader String AuthId){
//the value of the parameter AuthId is the value of request header named AuthId
...
}
In Spring MVC I have a controller that listens to all requests coming to /my/app/path/controller/*.
Let's say a request comes to /my/app/path/controller/blah/blah/blah/1/2/3.
How do I get the /blah/blah/blah/1/2/3 part, i.e. the part that matches the * in the handler mapping definition.
In other words, I am looking for something similar that pathInfo does for servlets but for controllers.
In Spring 3 you can use the # PathVariable annotation to grab parts of the URL.
Here's a quick example from http://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/
#RequestMapping(value="/hotels/{hotel}/bookings/{booking}", method=RequestMethod.GET)
public String getBooking(#PathVariable("hotel") long hotelId, #PathVariable("booking") long bookingId, Model model) {
Hotel hotel = hotelService.getHotel(hotelId);
Booking booking = hotel.getBooking(bookingId);
model.addAttribute("booking", booking);
return "booking";
}
In Spring 2.5 you can override any method that takes an instance of HttpServletRequest as an argument.
org.springframework.web.servlet.mvc.AbstractController.handleRequest
In Spring 3 you can add a HttpServletRequest argument to your controller method and spring will automatically bind the request to it.
e.g.
#RequestMapping(method = RequestMethod.GET)
public ModelMap doSomething( HttpServletRequest request) { ... }
In either case, this object is the same request object you work with in a servlet, including the getPathInfo method.