I am pretty new in Spring MVC. Currently I am studying the Spring MVC Showcase, that demonstrates the features of the Spring MVC web framework.
I have some problem to understand how Custom Resolvable Web Arguments are handled in this example.
In practice I have the following situation. In my home.jsp view I have the following link:
<a id="customArg" class="textLink" href="<c:url value="/data/custom" />">Custom</a>
This link generate an HTTP Request towards the URL: "/data/custom"
The controller class that contain the method that handles this request have the following code:
#Controller
public class CustomArgumentController {
#ModelAttribute
void beforeInvokingHandlerMethod(HttpServletRequest request) {
request.setAttribute("foo", "bar");
}
#RequestMapping(value="/data/custom", method=RequestMethod.GET)
public #ResponseBody String custom(#RequestAttribute("foo") String foo) {
return "Got 'foo' request attribute value '" + foo + "'";
}
}
The method that handles this HTTP Request is custom(). So when the previous link is clicked, the HTTP Request is handled by the custom method.
I have some problem to understand what exactly does the #RequestAttribute annotation do. I think that, in this case, it binds the request attribute named foo to a new String foo variable. But where this attribute is taken from? Is this variable taken by Spring?
OK, my idea is that this request attribute is taken from a HttpServletRequest object. I think so because, in this class, I also have the beforeInvokingHandlerMethod() method that have a speaking name, so it seems that this method sets an attribute, that have name=foo and value=bar, inside an HttpServletRequest object, and then so the custom() method can use this value.
In fact my output is:
Got 'foo' request attribute value 'bar'
Why the beforeInvokingHandlerMethod() is called before the custom() method?
And why the beforeInvokingHandlerMethod() is annotated by #ModelAttribute annotation? What does it mean in this case?
The RequestAttribute is nothing but the parameters which you have passed in the form submission. Lets understand with a sample example
Suppose I have the below form
<form action="...">
<input type=hidden name=param1 id=param1 value=test/>
</form>
Now, if I have the below controller which is mapped with the request url which is mapped with the form submission as below.
#Controller
public class CustomArgumentController {
#ModelAttribute
void beforeInvokingHandlerMethod(HttpServletRequest request) {
request.setAttribute("foo", "bar");
}
#RequestMapping(value="/data/custom", method=RequestMethod.GET)
public #ResponseBody String custom(#RequestAttribute("param1") String param1 ) {
// Here, I will have value of param1 as test in String object which will be mapped my Spring itself
}
Related
I am currently setting up a Spring MVC application (version 4.1.4.RELEASE) and I want the application to return a JSON string on a 404 error rather than the default html response. I am using Tomcat 8 as my server. I have what I think should be correct, however it isn't behaving in the manner that I expect. What I'm trying to do is based off of this answer.
public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
...
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration){
registration.setInitParameter("throwExceptionIfNoHandlerFound","true");
}
}
and then I have an exception controller (which is different than the question I based my solution off of, however I don't believe that is an issue as I am under the impression that #ControllerAdvice is an acceptable way to manage this based off of the Spring Docs. It looks something like:
#ControllerAdvice
public class GlobalExceptionController{
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public Message handleMethodNotSupported(HttpServletRequest request){
...
}
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ExceptionHandler(NoSuchRequestHandlingMethodException.class)
public Message handleBadRequest(HttpServletRequest request){
...
}
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ExceptionHandler(NoHandlerFoundException.class)
public Message requestHandlingNoHandlerFound(HttpServletRequest request){
...
}
...
}
It continues to send back the default response. I know for a fact that it is hitting my customizeRegistration() function because breakpoints stop it, however, any breakpoints that I have in my GlobalException class are not hit. Also, the GlobalException class is within a package that is hit by a #ComponentScan() annotation, so I am fairly confident that it is also being handled by spring.
I assume I'm missing something obvious, any help would be greatly appreciated.
I don't think the return type you're trying to use is supported. Have you tried changing your return value to ResponseEntity or adding a #ResponseBody annotation?
From the docs:
A ModelAndView object (Servlet MVC or Portlet MVC).
A Model object, with the view name implicitly determined through a RequestToViewNameTranslator.
A Map object for exposing a model, with the view name implicitly determined through a RequestToViewNameTranslator.
A View object.
A String value which is interpreted as view name.
#ResponseBody annotated methods (Servlet-only) to set the response content. The return value will be converted to the response stream
using message converters.
An HttpEntity or ResponseEntity object (Servlet-only) to set response headers and content. The ResponseEntity body will be
converted and written to the response stream using message converters.
void if the method handles the response itself (by writing the response content directly, declaring an argument of type
ServletResponse / HttpServletResponse / RenderResponse for that
purpose) or if the view name is supposed to be implicitly determined
through a RequestToViewNameTranslator (not declaring a response
argument in the handler method signature; only applicable in a Servlet
environment).
I am new to spring mvc. I am debugging a mvc code as given below
#Controller
#RequestMapping("/register")
public class RegisterController extends BroadleafRegisterController {
#RequestMapping(method=RequestMethod.GET)
public String register(HttpServletRequest request, HttpServletResponse response, Model model,
#ModelAttribute("registrationForm") RegisterCustomerForm registerCustomerForm) {
return super.register(registerCustomerForm, request, response, model);
}
#RequestMapping(method=RequestMethod.POST)
public String processRegister(HttpServletRequest request, HttpServletResponse response, Model model,
#ModelAttribute("registrationForm") RegisterCustomerForm registerCustomerForm, BindingResult errors) throws ServiceException, PricingException {
return super.processRegister(registerCustomerForm, errors, request, response, model);
}
#ModelAttribute("registrationForm")
public RegisterCustomerForm initCustomerRegistrationForm() {
return super.initCustomerRegistrationForm();
}
}
above is a spring handler class. for /register request i was thinking regsister() method should called but before this method inintcustomerRegisterationForm() is called i do not know why and how this method is called. I searched this in google but not find any useful information. I think this is like a interceptor method as in struts2. Please tell us how this method is called
Thanks
The initCustomerRegistrationForm() is being called because it is the 'model' of your controller. The model is typically always need for a get and post request for a specific form and represents the data entered into the form.
If you want your form pre-populated with some data, then you would add that data to the 'model'. The 'model' is also what is submitted to the post request then submitting a form.
According to spring documentation
#ModelAttribute methods are used to populate the model with commonly needed attributes for example to fill a drop-down with states or with pet types, or to retrieve a command object like Account in order to use it to represent the data on an HTML form.
A controller can have any number of #ModelAttribute methods. All such methods are invoked before #RequestMapping methods of the same controller.
Which explains why the initCustomerRegistrationForm() method is called before request mapping methods.
I have a simple controller with scope annotation.
#Controller
#Scope("session")
#RequestMapping("/")
public class HelloController {
private User user = new User("Bob");
#RequestMapping(method = RequestMethod.GET)
public String printWelcome() {
return "hello";
}
}
and simple jsp page
<html>
<body>
<h1>Y=${sessionScope.user}</h1>
<h1>Z=${user}</h1>
</body>
</html>
But when I'm trying to run this code, I'm getting nothing. The result is empty. I don't want to use single beans of User, also I don't like to pass object of HttpSession to method in controller or HttpServletRequest object for retrieving session from it. Is there any solution for using some annotation (except #SessionAttributes) to pass object to jsp from my controller?
I don't see why you are surprised. The only thing in your code that is in the HttpSession is the #Controller bean.
Just because that object has a field of type User doesn't mean there will be a User attribute in the HttpSession.
The result is empty. I don't want to use single beans of User, also I
don't like to pass object of HttpSession to method in controller or
HttpServletRequest object for retrieving session from it. Is there any
solution for using some annotation (except #SessionAttributes) to pass
object to jsp from my controller?
You've basically listed all your options. Use any of those.
I am pretty new in Spring MVC.
In this period I am studying the Spring MVC showcase example downlodable from STS dashboard.
I am having some problems understanding how Custom Resolvable Web Arguments are handled in this example.
In practice I have the following situation:
In my home.jsp view I have the following link:
<a id="customArg" class="textLink" href="<c:url value="/data/custom" />">Custom</a>
This link generate an HTTP Request towards the URL: "/data/custom"
The controller class that contains the method that handles this request has the following code:
#Controller
public class CustomArgumentController {
#ModelAttribute
void beforeInvokingHandlerMethod(HttpServletRequest request) {
request.setAttribute("foo", "bar");
}
#RequestMapping(value="/data/custom", method=RequestMethod.GET)
public #ResponseBody String custom(#RequestAttribute("foo") String foo) {
return "Got 'foo' request attribute value '" + foo + "'";
}
}
The method that handles this HTTP Request is custom()
So when the previous link is clicked the HTTP Request is handled by the custom method...
I am having problems understanding what the #RequestAttribute annotation.
I think that, in this case, it binds the request attribute named foo to a new String foo variable.
But... where is this attribute taken from? Is this variable taken by Spring?
Ok...my idea is that this request attribute is taken from a HttpServletRequest object...
I think this because, in this class, I have also have the beforeInvokingHandlerMethod() method that have a speacking name...so it seems that this method seta an attribute, that have name=foo and value=bar, inside an HttpServletRequest object...and then so the custom() method can use this value...
In fact my output is:
Got 'foo' request attribute value 'bar'
Why is the beforeInvokingHandlerMethod() called before the custom() method?
And why is the beforeInvokingHandlerMethod() annoted by #ModelAttribute annotation? What does this case mean?
You are correct in assumption of #RequestAttribute, it need not be set in beforeInvokingHandlerMethod. Assume you have a method mapped to /data/init which forwards request to /data/custom. In this case request attribute can be set in init method also.
Why the beforeInvokingHandlerMethod() is called before the custom() method?
And why the beforeInvokingHandlerMethod() is annoted by #ModelAttribute annotation? what means in this case?
you will get the reason here
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib-methods
An #ModelAttribute on a method indicates the purpose of that method is to add one or more model attributes. Such methods support the same argument types as #RequestMapping methods but cannot be mapped directly to requests. Instead #ModelAttribute methods in a controller are invoked before #RequestMapping methods, within the same controller.
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.