Request method 'POST' not supported at pass value - spring-boot

I use the interceptor in spring to make the user has login in,but when i transfer value from front end to back,the interceptor intercept the request,but it warns me that
WARN 8484 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved[org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
and send me to "/error",but i have add the controller into the excludePath like this
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(cookiesInterceptor).addPathPatterns("/**")
.excludePathPatterns("/adminapi/login")
.excludePathPatterns("/Login.html")
.excludePathPatterns("/index.html")
.excludePathPatterns("/static/**");
}
and the controller
#RequestMapping(value = "/adminapi")
public class AdminController {
#RequestMapping("/login")
public String .....
}
the action of form
<form th:action="#{/adminapi/login}" method="post">
so i do not know why the problem occur

In your AdminController,
replace #RequestMapping("/login")
with #PostMapping("/login")
This tells Spring Boot that you are using the POST method, otherwise by default GET is expected

I don't see the #Controller annotation in your AdminController
By the way, you should specify the method for your RequestMapping, you can use
#Controller
#RequestMapping(value = "/adminapi")
public class AdminController {
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String .....
}
or
#Controller
#RequestMapping(value = "/adminapi")
public class AdminController {
#PostMapping("/login")
public String .....
}

Check whether CSRF is enabled in spring security xml file . If so add the
So you should be able to submit the model attribute.
Seems duplicate check here Spring,Request method 'POST' not supported
Check whethr on the Controller receiving function for Spring MVC , you ahve this annotation. #ModelAttribute
For the requestmapping specify the method type .
#RequestMapping(value = "/login", method = RequestMethod.POST)

Related

How to handle if client request by GET method which is originally POST in controller in Spring Boot?

#RequestMapping(value = "/abc", method = RequestMethod.POST)
public class TestController {
.....
}
what if user will request /abc as GET Method how i can Handle Request?
You will get an exception:
Request method 'GET' not supported
You can support multiple method (GET,POST...) by remove method in annotation.
#RequestMapping(value = "/abc")

Springboot #Controller cannot be invoked, but #RestController works

My controller has been annotated with #Controller and it cannot be invoked
- The browser shows
There was an unexpected error (type=Not Found, status=404).
But, if it is annotated with #RestController, then it works. My SpringBoot version:1.5.3.RELEASE
My Controller : (in com.sbootsecurityjsp.controller)
#Controller
public class LoginController {
#RequestMapping(value = "/login", method= RequestMethod.GET )
public String login() {
return "Login Controller";
}
}
Main Class: (in com.sbootsecurityjsp)
#SpringBootApplication(scanBasePackages = {"com.sbootsecurityjsp"})
public class SbootSecurityJspApplication {
public static void main(String[] args) {
SpringApplication.run(SbootSecurityJspApplication.class, args);
}
}
I am curious why the #Controller cannot work if the #RestController annotation works. If component scan is not working, #RestController also should not work. I have added scanbasePackages too. Even without scanbasePackages, it does not work.
By the way, when the app starts, the logs also show a line as following:
INFO 532 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login],methods=[GET]}" onto public java.lang.String com.sbootsecurityjsp.controller.LoginController.login()
Why #Controller is used is to differentiate requests to pages and rest calls. Please correct me if I am wrong. My idea is to use #RestController s for REST requests, on the other hand #Controller for pages related requests- redirecting to JSP or any logics related to views. Is it a bad practice ?
Why does it return a 404 when I use #Controller annotation?
When using #Controller, Spring expects the String you return in #RequestMapping methods to correspond to the page you want to redirect the user to.
#RequestMapping(value = "/login", method= RequestMethod.GET )
public String login() {
return "Login Controller";
}
Here, Spring will try to redirect the user to Login Controller.jsp, which cannot be found and thus returns a 404.
Why does it not return 404 when I use #RestController
When using #RestController, the String you return is not mapped to any page. Instead, Spring just transforms it to e.g. a JSON response. This is why this doesn't give you a 404.
Proposed solution
If you have a jsp page called login.jsp, simply return "login":
#RequestMapping(value = "/login", method= RequestMethod.GET )
public String login() {
return "login";
}

calling a method by class level annotated with #RequestMapping that includes an autowired class

I am trying to call a method that is annotated with #RequestMapping(signIn) through a class level (from method: authentication) like so:
#RequestMapping(value = /authenticate, method = RequestMethod.POST)
public #ResponseBody Response authentication(HttpServletRequest request)
{
UserController user = new UserController();
return user.signIn(request, null);
}
and my controller looks like:
#Autowired
private UserManager userManager;
#RequestMapping(value = /signin, method = RequestMethod.POST)
public #ResponseBody Response signIn(HttpServletRequest request) {
JsonObject json = Misc.parseJson(request);
String lang = Misc.getLang(request);
user.setEmail(Misc.getEmail(json));
user.setPassword(Misc.getEncryptedPassword(json));
return ResponseUtils.success(userManager.auth(user, lang));
}
user manager is annotated with #component:
#Component
public class UserManager {
public User auth(User user, String lang) {
....
return user;
}
}
Problem is when I call the method "signIn" and just new-up a UserController instance through "/authenticate" mapping, the UserManager becomes NULL. So now I'm assuming that autowiring doesn't work when it's done this way.
Is there any other way to call the signIn method? I would hate to copy paste an already existing code to another class just to get this to work...
Autowiering only works in spring managed bean. If you create a class with new keyword, it is not a spring managed bean and autowiering would not work.
You can try to autowire the class which contains the method which is annotated or better put the code in a service class which can be used by both methods.
It's not problem with #Autowired .There are two type of Annotation
firstly method base annotation and field level annotation. You just used field level annotation.Check your import class with "org.springframework.beans.factory.annotation.Autowired" or it can be problem with initiation of "UserManager"
I don't know why you not moving logic into separate Service classs, but try this:
UserController.java
public UserController(UserManager userManager) {
this.userManager = userManager;
}
and then inside controller where authentication resource method is located:
#Autowired UserManager userManager;
#RequestMapping(value = /authenticate, method = RequestMethod.POST)
public #ResponseBody Response authentication(HttpServletRequest request) {
UserController user = new UserController(userManager);
return user.signIn(request);
}
So in the end I just separated the logic instead. Though one solution that I tried and I could have used was to just add another mapping to the signIn method instead of adding a new method in the other class since the logic was similar. Still I opted for a separate logic instead since there were a lot of unnecessary code in the signIn method for my purpose.

Handling Session in spring MVC?

i'm actually new to handling with spring mvc and in particular i have to implement session in spring mvc. Can anybody guide me out of how to handle with session in spring mvc ?
It is the example of controller method level session
#Controller
Class YourController{
#RequestMapping(value = "/yourrequest", method = RequestMethod.GET)
public String yourMethod(Model model,HttpSession session){
return null;
}
}
You can also put session valid to Controller Class.It is just done by adding SessionAttribute.This will be available in all methods in YourController Class
#Controller
#SessionAttribute("sessionName")
Class YourController{
#RequestMapping(value = "/yourrequest", method = RequestMethod.GET)
public String yourMethod(Model model){
model.addAttribute("sessionName",valueToBeAddedInSession);
return null;
}
}
Here the name of object added in Session should be same as it is added in modelAttribute e.g. sessionName.
The problem in case of session attribute is that we have to invalidate it manually
Thank you.
#Controller
#SessionAttributes({ "sessionVar1","sessionVar2" })
public class StartController {
public ModelAndView methodName(){
ModelAndView modelandView = new ModelAndView("view");
modelandView.addObject("sessionVar1", "sessionVal1");
modelandView.addObject("sessionVar2", "sessionVal2");
return modelandView;
}
}

Spring MVC web application - enabling / disabling controller from property

I have a web application running in Tomcat and using Spring MVC to define controllers and mappings. I have the following class:
#Controller("api.test")
public class TestController {
#RequestMapping(value = "/test", method = RequestMethod.GET)
public #ResponseBody String test(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
// body
}
}
I would like to make this controller and the ".../test" path available according to a property defined somewhere (e.g. file). If the property is, lets say, false, I would like the app to behave as if that path doesn't exist and if it is true, to behave normally. How can I do this? Thanks.
If you are using Spring 3.1+, make the controller available only in the test profile:
#Profile("test")
class TestController {
...
}
then enable that profile by e.g. passing the following system property at Tomcat boot:
-Dspring.profiles.active=test
To disable the controller simply omit the given profile.
Another way of doing it , may be simpler way of doing it, is to use #ConditionalOnProperty annotation with your RestController/Controller.
#RestController("api.test")
#ConditionalOnProperty(name = "testcontroller.enabled", havingValue = "true")
public class TestController {
#RequestMapping(value = "/test", method = RequestMethod.GET)
public String test(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
// body
}
}
Here testcontroller.enabled property in your yml properties say ,if not set to true , the TestController Bean is never created.
Tip: I suggest you to use RestController instead of Controller as its has #ResponseBody added by default. You can use #ConditionalOnExpression to arrive at the same solution but is little slower due to SpEL evaluation.

Resources