Request method 'GET' not supported - spring

Trying to redirect from controller method to another controller, facing below error
org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
I have submitForm method in controller 1, once i call submit method it should call controller 2
Controller 1
#RequestMapping(method = RequestMethod.POST)
public ModelAndView submitForm(#ModelAttribute("loginForm") Login login, BindingResult errors, SessionStatus status, HttpServletRequest request, HttpServletResponse response) throws IOException {
return new ModelAndView("path2.sp");
}
Controller 2
#Controller
#RequestMapping("path2.sp")
public class DestinationController {
System.out.println("");
}

This is not the way to do redirection.
First, fix your #RequestMapping in Controller 2, like this:
#Controller
#RequestMapping("/path2")
public class DestinationController {
System.out.println("");
}
Now, in controller 1 just do this:
#RequestMapping(method = RequestMethod.POST)
public String submitForm(#ModelAttribute("loginForm") Login login, BindingResult errors, SessionStatus status, HttpServletRequest request, HttpServletResponse response) throws IOException {
return "redirect:/path2";
}

Related

Why is a GET request mapped to "/error" in Spring-Boot?

When I send a GET request to /todo-list/user/list
it was mapped to /error.
Code
Interceptor:
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
RequestMapping classMapping = handlerMethod.getMethod().getDeclaringClass().getAnnotation(RequestMapping.class);
// when debugging: classMapping.value() was "${server.error.path:${error.path:/error}}"
RequestMapping methodMapping = handlerMethod.getMethodAnnotation(RequestMapping.class);
//some other codes
Controller:
//the contexPath is "/todo-list"
#RestController
#RequestMapping("/user")
#RequiredArgsConstructor
public class UserController
Method
#GetMapping(value = "/list")
public #ResponseBody Page<UserProjection> listGrid() {
return userService.listGrid();
}
I checked the address and method and whatever I think is the reason.
When debugging my code, classMapping.value() was equal to "${server.error.path:${error.path:/error}}".
What is the problem?

Spring ModelAndView Attribute is null

I have one simple controller and one interceptor.
Within interceptor in postHandle-method I am checking user.
Problem: My user-model is sometimes null, between controller-handles.
postHandle invoked by home-handle==> User-Model is not null
postHandle invoked by check_user-handle ==> User-model is null
postHandle invoked by redirectToErrorPage-handle ==> User-model is
not null anymore and contains everything, what i've expected by
check_user-PostHandle Invocation.
Here is my controller
#Controller
#SessionAttributes("user")
public class HomeController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView home(Model model, HttpServletRequest request, HttpSession session) {
User user = new User();
return new ModelAndView("login", "user", user);
////now User-Model was saved in the session
}
//now i'am redirectring user in the "check_user"-handle
#RequestMapping(value = "/check_user", method = RequestMethod.POST)
public ModelAndView checkUser(#Valid #ModelAttribute("user") User user, BindingResult bindingResult, Model model,
HttpServletRequest request, RedirectAttributes redirectAttr) {
RedirectView redirectView = null;
ModelAndView mav=null;
try {
if(!bindingResult.hasErrors()){
redirectView = new RedirectView("home");
redirectView.setStatusCode(HttpStatus.FOUND);
redirectAttr.addFlashAttribute("httpStatus", HttpStatus.FOUND);
mav = new ModelAndView(redirectView);
return mav; //at next i entry post-handle from interceptor,
//which says to me, that user-model is null.
}
}
//My interceptor redirects me to this handle.
//After this handle within interceptor method "postHandle", i see, that
//user-object exists
#RequestMapping(value = "/error", method = RequestMethod.GET)
public String redirectToErrorPage(HttpServletRequest request){
return "error";
}
}
And my Interceptor:
public class UserInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
User user = (User) modelAndView.getModel().get("user");
if(user == null || !user.isAdmin()){
response.sendRedirect(request.getContextPath()+"/failed");
}
}
}
While I retrive, which keys my model has, when postHandle was invoked by "check_user", I have only one key "totalTime". Whats going on with my model?
Try modifying your postHandle() as below:
...
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
User user = (User) request.getSession().getAttribute("user");
...

HTTP redirect: 301 (permanent) vs. 302 (temporary) in Spring

I want to make a 301 redirect in Spring, So here the piece of code I use
#RequestMapping(value = { "/devices" } , method = RequestMethod.GET)
private String initGetForm(#ModelAttribute("searchForm") final SearchForm searchForm,
BindingResult result,
HttpServletRequest request,
HttpServletResponse response,
Model model, Locale locale) throws Exception {
String newUrl = "/devices/en";
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
response.setHeader("Location", newUrl);
response.setHeader("Connection", "close");
return "redirect:" + newUrl;
}
But checking the IE Developer Tools I got this Status 302 Moved Temporarily !
Spring is resetting your response headers when it handles the redirection since you are returning a logical view name with a special redirect prefix.If you want to manually set the headers handle the response yourself without using Spring view resolution. Change your code as follows
#RequestMapping(value = { "/devices" } , method = RequestMethod.GET)
private void initGetForm(#ModelAttribute("searchForm") final SearchForm searchForm,
BindingResult result,
HttpServletRequest request,
HttpServletResponse response,
Model model, Locale locale) throws Exception {
String newUrl = request.getContextPath() + "/devices/en";
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
response.setHeader("Location", newUrl);
response.setHeader("Connection", "close");
}
You can use RedirectView with TEMPORARY_REDIRECT status.
#RequestMapping(value = { "/devices" } , method = RequestMethod.GET)
private ModelAndView initGetForm(#ModelAttribute("searchForm") final SearchForm searchForm,
BindingResult result,
HttpServletRequest request,
HttpServletResponse response,
Model model, Locale locale) throws Exception {
....
RedirectView redirectView = new RedirectView(url);
redirectView.setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
return new ModelAndView(redirectView);
}

Converting a responseEntity to httpServletResponse with spring

My controller method looks like this :
public void doLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
and I want to do this
ResponseEntity<String> responseEntity = restTemplate.postForEntity(testPrefix + "/login", map, String.class);
response = responseEntity;
or similar, basically make a restcall and return the HttpReponseEntity as the response n its enitirety
From updated comments I assume that you are wanting to return the result of the restTemplate.postForEntity() call from your Controller.
As shown by the Spring MVC documentation, ResponseEntity is a valid return type from a Controller method. So you can simply return the result of your restTemplate.postForEntity() call from the doLogin() method. As an example:
#Controller
public class MyController
{
#AutoWired
private RestTemplate restTemplate;
#RequestMapping("/yourPath")
public ResponseEntity<String> doLogin(HttpServletRequest request) throws IOException
{
return restTemplate.postForEntity(testPrefix + "/login", map, String.class);
}
}
Spring MVC will take care of marshalling the ResponseEntity into the HTML response using a HTTPMessageConverter.

Bad design letting controller return an Object?

Hi is this bad design? I would like return Profile if everything goes according to plan. If not I would like to return my custom error message.
Is this ok?
#RequestMapping(value = "/{userId}", method = RequestMethod.PUT)
public #ResponseBody
Object saveUser(#PathVariable Long userId, ModelMap data, #Valid Profile profile, BindingResult bindingResult, HttpServletResponse response) {
if (bindingResult.hasErrors()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return ValidationUtil.createValidationErrors(bindingResult);
}
profileService.save(profile);
return profile;
}
You should use #ExceptionHandler (Exception.class) and #ResponseStatus Annotation
Example
#ExceptionHandler (Exception.class)
#RequestMapping(value = "/{userId}", method = RequestMethod.PUT)
public #ResponseBody
Profile saveUser(#PathVariable Long userId, ModelMap data, #Valid Profile profile, BindingResult bindingResult, HttpServletResponse response) {
if (bindingResult.hasErrors()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
throw new Exception("message");
if(ValidationUtil.createValidationErrors(bindingResult)) {
throw new Exception("message");
}
}
profileService.save(profile);
return profile;
}
For more details refer
http://jnb.ociweb.com/jnb/jnbNov2010.html
http://www.stormpath.com/blog/spring-mvc-rest-exception-handling-best-practices-part-1
http://blog.cuttleworks.com/2011/12/spring-restful-controllers-and-error-handling/
If you need access to the profile object, I'd suggest you add it to the session or the request context. Then you can return a string from your saveUser method (or a ModelAndView object, if you prefer), and still have the object available to later requests.

Resources