Redirect in controllers spring3 - spring

In Spring 3 you map urls as simply as this:
#RequestMapping(value = "/index.html", method = RequestMethod.GET)
public String index(Model model) {
return "index";
}
Is it possible to make this kind of method to kinda redirect to another url like:
#RequestMapping(value = "/index.html", method = RequestMethod.GET)
public String index(Model model) {
return "second.html";
}
#RequestMapping(value = "/second.html", method = RequestMethod.GET)
public String second(Model model) {
//put some staff in model
return "second";
}

You don't need to redirect - just call the method:
#RequestMapping(value = "/index.html", method = RequestMethod.GET)
public String index(Model model) {
return second(model);
}
#RequestMapping(value = "/second.html", method = RequestMethod.GET)
public String second(Model model) {
//put some staff in model
return "second";
}
This is one of the nice things about the annotation style; you can just chain your methods together.
If you really want a redirect, then you can return that as a view:
#RequestMapping(value = "/index.html", method = RequestMethod.GET)
public View index(Model model) {
return new RedirectView("second.html");
}
#RequestMapping(value = "/second.html", method = RequestMethod.GET)
public String second(Model model) {
//put some staff in model
return "second";
}

Yes redirect will work. In index method, change last line to return "redirect:/second.html" ;
Edit
context path and controller mapping are required. If DispatcherServlet is mapped to /ABC and request mapping for controller is /XYZ then you will have to write:
return "redirect:/ABC/XYZ/second.html";

Related

The input tag not showing in the form spring-mvc-form

So i'm trying to create a from for adding products but when i go to the url the form doesn't show any input tag only the labels
I followed this documentation : https://www.baeldung.com/spring-mvc-form-tutorial
this is the GET method
#RequestMapping(value = "/product", method = RequestMethod.GET)
public ModelAndView showForm() {
return new ModelAndView("products/CreateProduct", "produit", new Produit());
}
and this is the POST method
#RequestMapping(value = "/create-product", method = RequestMethod.POST)
public String submitproduct(#Valid #ModelAttribute("produit")Produit produit,
BindingResult result, ModelMap model) {
if (result.hasErrors()) {
return "error";
}
model.addAttribute("productID", produit.getId_produit());
model.addAttribute("productName", produit.getNom_produit());
model.addAttribute("productPrice", produit.getPrix_produit());
model.addAttribute("productDescription", produit.getDescription_produit());
model.addAttribute("productBrand", produit.getMarque_produit());
model.addAttribute("productBarCode", produit.getCodeBarre_produit());
return "products/CreateProduct";
}

404 Request Resource not found

I am using Spring Framework with restful web services, and I am trying to create an API with restful service and use a get method. I have created a method and I'm trying to have it return a string, but instead I get a 404 error - requested resources not found. Please see my code below:
#RestController
#RequestMapping("/test")
public class AreaController {
public RestResponse find(#PathVariable String name, ModelMap model) {
model.addAttribute("movie", name);
return "list";
}
}
I am using: localhosr:8080/MyProject/wangdu
This error occurs because you forgot to add
#RequestMapping(value = "/{name}", method = RequestMethod.GET) before your find method:
#RestController
#RequestMapping("/test")
public class AreaController {
#RequestMapping(value = "/{name}", method = RequestMethod.GET)
public RestResponse find(#PathVariable String name, ModelMap model) {
model.addAttribute("movie", name);
return "list";
}
}
Please make sure about this:
The value that the find method is returning is a String with the value "list" and the find method declaration is waiting for a RestResponse object
For example if I have a RestResponse object like this:
public class RestResponse {
private String value;
public RestResponse(String value){
this.value=value;
}
public String getValue(){
return this.value;
}
}
Then try to return the value in this way:
public RestResponse find(#PathVariable String name, ModelMap model) {
model.addAttribute("movie", name);
return new RestResponse("list");
}
Verify that the method has #RequestMapping annotation with the value that your expect from the url
#RequestMapping(method = RequestMethod.GET, value = "/{name}")
By default the proper way to call the rest resource is by the #RequestMapping value that you set at the #RestController level (#RequestMapping("/test")), in this case could be: http://localhost:8080/test/myValue
If you need to use a different context path then you can change it on the application.properties (for spring boot)
server.contextPath=/MyProject/wangdu
In that case you can call the api like this:
http://localhost:8080/MyProject/wangdu/test/myValue
Here is the complete code for this alternative:
#RestController
#RequestMapping("/test")
public class AreaController {
#RequestMapping(method = RequestMethod.GET, value = "/{name}")
public RestResponse find(#PathVariable String name, ModelMap model) {
model.addAttribute("movie", name);
return new RestResponse("list");
}

How to specify the controller name if two controllers have same RequestMapping path value?

There are 2 controllers having same #RequestMapping value :
package com.ambre.hib.controller;
#Controller
public class AppointmentsController {
#RequestMapping(value = "/new", method = RequestMethod.GET)
public AppointmentForm getNewForm() {
return new AppointmentForm();
}
}
package com.ambre.hib.controller;
#Controller
public class ClientsController {
#RequestMapping(value = "/new", method = RequestMethod.GET)
public ClientForm getNewForm() {
return new ClientForm();
}
}
So the 2 controllers have same "/new" action.
Now from a jsp page I want to target a link to the "/new" action of the second controller : <img src="resources/images/plus.png" />
This writing is ambiguous because Spring does not know into which controller to look ! So how to specify the controller name in the link target ?
It's not possible to have two or more controller methods with the same #RequestMapping. The dispatcher won't know wich method to call.
You could set a base request mapping for each controller:
package com.ambre.hib.controller;
#Controller
#RequestMapping("/appointments")
public class AppointmentsController {
#RequestMapping(value = "/new", method = RequestMethod.GET)
public AppointmentForm getNewForm() {
return new AppointmentForm();
}
}
package com.ambre.hib.controller;
#Controller
#RequestMapping("/clients")
public class ClientsController {
#RequestMapping(value = "/new", method = RequestMethod.GET)
public ClientForm getNewForm() {
return new ClientForm();
}
}
If so, the way of calling each would be <a href="<c:url value='/appointments/new' />"> for the first controller and
<a href="<c:url value='/clients/new' />"> for the second
You need to narrow down the request using the "params" option. For example
#Controller
public class HelloWorldController {
#RequestMapping(value="/fetch", params = {"id=100"})
public String getInfo1(#RequestParam("id") String id) {
System.out.println("Inside getInfo1");
return "success";
}
#RequestMapping(value="/fetch", params = {"id=200"})
public String getInfo2(#RequestParam("id") String id) {
System.out.println("Inside getInfo2");
return "success";
}
}
When you access the URL /fetch?id=100 , method getInfo1() is called. When you access URL /fetch?id=200 , method getInfo2() is called and when you access /fetch?id=300 , HTTP Status 404 is received. In this case the "id" parameter is just another parameter which you use to narrow down the request to your preferred method in the controller.

how to set multiple pattern for one method in spring mvc controller

In my controller:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index() {
return "page/post/list";
}
I want url with pattern '/' or '/list' or '/index' are all handled by this method,is there any way to config it?
#RequestMapping(value = {"/", "/list", "/index"}, method = RequestMethod.GET)
public String index() {
return "page/post/list";
}

Spring : timely/late binding of #ModelAttribute

I'm using the following code to bind the users to the model [to be used in the view/jsp]:
#ModelAttribute("users")
public Collection<User> populateUsers() {
return userService.findAllUsers();
}
But sometimes I just need to load few users with a particular Role, which I'm trying by using the following code:
int role = 2; //this is being set in a Controller within a method #RequestMapping(method = RequestMethod.GET) public String list(
#ModelAttribute("users")
public Collection<User> populateUsers() {
if(role == 2)
return userService.findAllUsersByRole(role);
else
return userService.findAllUsers();
}
but the populateUsers is always called at the start of the controller, before the role is set in list method, Could you please help me on how to set the users [something like late binding]
Regards
-- adding code
#Controller
#RequestMapping("/users")
public class UserController {
#Autowired
UserService userService;
#RequestMapping(method = RequestMethod.POST)
public String create(#Valid User user, BindingResult bindingResult,
Model uiModel, HttpServletRequest httpServletRequest) {
if (bindingResult.hasErrors()) {
uiModel.addAttribute("user", user);
addDateTimeFormatPatterns(uiModel);
return "users/create";
}
uiModel.asMap().clear();
userService.saveUser(user);
return "redirect:/users/"
+ encodeUrlPathSegment(user.getId().toString(),
httpServletRequest);
}
#RequestMapping(params = "form", method = RequestMethod.GET)
public String createForm(Model uiModel) {
uiModel.addAttribute("user", new User());
addDateTimeFormatPatterns(uiModel);
return "users/create";
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String show(#PathVariable("id") Long id, Model uiModel) {
addDateTimeFormatPatterns(uiModel);
uiModel.addAttribute("user", userService.findUser(id));
return "users/show";
}
#RequestMapping(value = "/{id}", params = "form", method = RequestMethod.GET)
public String updateForm(#PathVariable("id") Long id, Model uiModel) {
uiModel.addAttribute("user", userService.findUser(id));
addDateTimeFormatPatterns(uiModel);
return "users/update";
}
#ModelAttribute("users")
public Collection<User> populateUsers() {
return userService.findAllUsers();
}
#ModelAttribute("userroles")
public Collection<UserRole> populateUserRoles() {
return Arrays.asList(UserRole.class.getEnumConstants());
}
void addDateTimeFormatPatterns(Model uiModel) {
uiModel.addAttribute(
"user_modified_date_format",
DateTimeFormat.patternForStyle("M-",
LocaleContextHolder.getLocale()));
}
}
#PathVariable("id") Long id is the ID I require in populateUsers, hope it is clear.
If role is in the current request, this method binding role to variable role.
#ModelAttribute("users")
public Collection<User> populateUsers(#RequestParam(required=false) Integer role) {
if(role != null && role == 2)
return userService.findAllUsersByRole(role);
else
return userService.findAllUsers();
}
Setting the model attribute in the required method has solved my issue:
model.addAttribute("users", return userService.findAllUsersByRole(role));
Thanks!

Resources