Spring MVC ResquestMapping 'POST' not supported - java

I have a method with get and post in login controller. When application is deployed from index page i am redirecting to login page it makes GET request(/login.htm) it works fine but when i make post request with JSON body it says Request method 'POST' not supported i am using postman tool to test please
Help
#RequestMapping(value="/login",method = RequestMethod.GET)
public ModelAndView redirectLoginForm()
{
System.out.println("Login Page...");
return new ModelAndView("login");
}
#RequestMapping(value="/login",method=RequestMethod.POST,
consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Login> login(#RequestBody Login login)
{
System.out.println("Checking LoginCredentials...");
boolean isValid=loginServiceBo.checkUserLogin(login);
if(isValid)
{
return new ResponseEntity<Login>(login, HttpStatus.ACCEPTED);
}
return new ResponseEntity<>(login, HttpStatus.NOT_FOUND);
}

Taking in account your code:
#RequestMapping(value="/login",method=RequestMethod.POST,
consumes=MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE)
In the screenshot of Postman, is missing the correct mapping, it should be: http://localhost:8073/Spring_Hibernate_Project/login

I think it's connected with your postman query.
May be my screenshot will be helpful to check your postman, on server side I have very similar mapping.

Related

How to redirect/forward angular page from spring boot?

I am developing a application with angular 6 as front end and spring boot as back end. In this while implementing user authentication module I want to redirect to student and staff home after login accordingly.
But, I am not able to redirect the page from spring boot. Using Redirect to an external URL from controller action in Spring MVC this solution I am getting the CORS error :
"Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response."
Or, if there is another way to do this task?
AuthenticationController.java
package sgsits.cse.dis.user.controller;
#CrossOrigin(origins = "*") // enables cross origin request
#RestController
#RequestMapping(value = "/dis")
#Api(value = "Authentication Resource")
public class AuthenticationController {
#Autowired
StudentRepository studRepo;
#Autowired
StaffRepository staffRepo;
#Autowired
EmailController email;
String pattern = "MM-dd-yyyy";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
#ApiOperation(value = "login", response = Object.class, httpMethod = "POST", produces = "application/json")
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String login(#RequestBody Authentication auth, HttpServletResponse httpServletResponse) {
Optional<StaffProfile> staff = staffRepo.findByEmail(auth.getUsername());
if (staff.isPresent()) {
String md5_pass = MD5.getHash(auth.getPassword());
if (staff.get().getPassword().equals(md5_pass)) {
// set session
// update last login
return "forward:/localhost:4200/staff";
} else
return "You have entered incorrect password";
} else {
Optional<StudentProfile> student = studRepo.findByEnrollmentId(auth.getUsername());
if (student.isPresent()) {
String md5_pass = MD5.getHash(auth.getPassword());
if (student.get().getPassword().equals(md5_pass)) {
// set session
// update last login
httpServletResponse.setHeader("Location", "http://localhost:4200/reset-password");
httpServletResponse.setStatus(302);
return "redirect:localhost:4200/student";
} else
return "You have entered incorrect password";
} else {
return "You are not registered with the system. Please signup first";
}
}
}
}
Do not add #CrossOrigin(origins = "*") annotation to controller.
Assume your api runs on 8080 and your angular code on 4200. If true;
create a file called proxy.conf.json
{
"/api/": {
"target": "http://localhost:8080/",
"secure": false,
"changeOrigin": true
}
Start angular app using this command
ng serve --proxy-config proxy.conf.json
With this configuration when you call localhost:4200/api you it will call 8080 and it won't have any CORS error
Why don't you return a proper API Response and code and depending on your response and Code you can redirect on the front end.
It makes your API Completely RESTFUL. I hope this helps.
I observed that when you redirect from Spring Boot to an Angular page the error "request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response" means that, Angular node.js server does not detect field content-type in the header Access-Control-Allow-Headers in your Angular app configuration. The point here is that roles of backend server and and client app are a bit the other way around in this redirection.
To solve this I would add content-type field into the response header Access-Control-Allow-Headers in the following way:
1. create file proxy.config.js just below the package.json file in your Angular project with this code:
module.exports = {
"/": {
"secure": false,
"bypass": (req, res, proxyOptions) => {
res.setHeader('Access-Control-Allow-Headers', "Content-Type");
}
}
};
and modify angular.json file by adding line:
"proxyConfig": "proxy.config.js"
to this location:
projects >> client >> architect >> serve >> options
This solution worked in my case. Note that the capitalization of first letter of the field name matters.

Receiving a POST Request on Spring From Another Site

I'm a little new in Java Spring. What I want to do is as follows:
Some 3rd party is asking a "return URL" from me and I set it as follows:
https://localhost:9002/my-account/order-history
Then they send me a POST request and I'm supposed to handle it within my controller. The request has both url parameters and a form data. The request is
Request URL:https://localhost:9002/my-account/order-history?responseCode=0000&token=E0ECFC1214B19E5D11B9B587920FC5F164C5CB17E7DC67F083E0EC6676F79467DFBDF4B6CCF3C39BF47F0232D1AA42F1FA112F29B0157DDF98EE3997F781CCB1FEB070A44E530691BA36674BEA4CF56A4A43F2B9746D9C3591CF288D745A6694
Request Method:POST
Status Code:403 Bad or missing CSRF token
Remote Address:127.0.0.1:9002
Referrer Policy:no-referrer-when-downgrade
A part of the form data is:
I added the whole form data and other request info as attachment.
The controller I'm desperately trying to use is as follows:
#Controller
#RequestMapping(value = "/my-account")
public class MaviAccountPageController extends MaviAbstractController
{
#RequestMapping(value = "/order-history", method = RequestMethod.POST)
public ModelAndView process(#RequestBody final String req)
{
//consumes = "text/plain"
System.out.println(req);
System.out.println(req);
return new ModelAndView("deneme");
}
....
}
And I keep getting 403 - Bad or missing CSRF token error.
How should I implement my controller? I have checked below links and they did not work out unfortunately:
How to retrieve FORM/POST Parameters in Spring Controller?
How to explicitly obtain post data in Spring MVC?
I tried, but failed to regenerate issue on postman.
Can anyone, please, advise me about how to move on?
you can annotate your method with #CrossOrigin
#CrossOrigin
#RequestMapping(value = "/order-history", method = RequestMethod.POST)
public ModelAndView process(#RequestBody final String req)
{
//consumes = "text/plain"
System.out.println(req);
System.out.println(req);
return new ModelAndView("deneme");
}
https://spring.io/guides/gs/rest-service-cors/

Request Header is getting as null in spring mvc

I am having two mapping methods in my controller. one is redirecting to other.
Before redirecting I'm setting a header in response. But I getting the request header as null.
These are my methods in controller. both are in same controller.
#RequestMapping(value="/testStart", method=RequestMethod.POST)
public String testStart(HttpServletRequest request, HttpServletResponse response){
String token = "126712810-1289291":
response.addHeader("authToken", token);
return "redirect:/test";
}
#RequestMapping(value="/test", method={ RequestMethod.POST, RequestMethod.GET })
public String getTestPage(Model model, HttpServletRequest request, HttpServletResponse response){
String token = request.getHeader("authToken");
System.out.println(token); //prints null
model.addAttribute("Testtoken", token);
System.out.println("Test page about to load ..");
return "test";
}
I'm using postman client to test this api. It is hitting the url and redirecting to other url. but the header is null.
I don't know what's wrong. can any one help me to figure this out? Thanks
With Redirect method web app tells browser to load the page which you want to redirect. So this makes new http request from browser, the original requests are not reachable at this moment.
So your problem can be solved with Forward method. Web app forwards all request data to another handler method internally
return "forward:/test";
Additionally , please change your
String token = request.getHeader("authToken");
with
String token = response.getHeader("authToken");
because you are adding your authToken to the response object.(from comments HttpServletResponse -> getHeader(String name) works since Servlet 3.0)
EDIT :
this code will be your complete solution "/test" method supports forwarded reuqest and also supports request from browser.
(You want to get token info from request becuase you want to call /test method without forwarding, so it works in this way, but when forwarding you cant add header so you tried to add in response and get it from request but that doesnt work in that way so you need to resolve token according to dispatcher's type so check the code )
#RequestMapping(value="/testStart", method=RequestMethod.POST)
public String testStart(HttpServletRequest request, HttpServletResponse response){
String token = "126712810-1289291";
request.setAttribute("authToken", token);
return "forward:/test";
}
#RequestMapping(value="/test", method={ RequestMethod.POST, RequestMethod.GET })
public String getTestPage(Model model, HttpServletRequest request, HttpServletResponse response)
{
//-----------------
//resolving token
String token = null;
DispatcherType type = request.getDispatcherType();
if(type == DispatcherType.FORWARD)
{
token = (String) request.getAttribute("authToken");
}
else if(type == DispatcherType.REQUEST)
{
token = (String) request.getHeader("authToken");
}
//-----------------
System.out.println(token); //prints the value
model.addAttribute("Testtoken", token);
System.out.println("Test page about to load ..");
return "test";
}
Use RedirectAttributes to pass parameters with redirect URL:
#RequestMapping(value="/test1", method=GET)
public String test(RedirectAttributes redirectAttributes){
redirectAttributes.addAttribute("authToken", "val");
return "redirect:/test";
}
or if you can use forward:/test you can go with request.setAttribute and request.getAttribute
Still if you want to add in header then use RestTemplate and HTTPHeaders and get the response String

How to login with #RestController and send the object to angularjs

I have some trouble figuring out how to create a login form in angularjs using springboot.
I can register a user and send the data to the database but the problems begin when i want to login.
in angularjs i have a function like this
function Login(username, password, callback) {
$http.post('/api/authenticate', { username: username, password: password })
.success(function (response) {
callback(response);
});
}
What i managed to do but probably is't right:
#RequestMapping(value = "/authenticate/{id}",method = RequestMethod.GET)
public User getUser(#PathVariable Integer id) {
return repo.findOne(id);
}
This gives me following json
{"id":2,"username":"jdoe","password":"$2a$10$5hgIyQr.K9wb8cXEyWGbROAU.rkYzd19vP7ajHpwp1KUYdShfcPn.","lastname":"doe","firstname":"john","customfield":"Hello there"}
But now i have following problems and questions :
How can i check if the username and password is equal to the username and password of json by going to api/authenticate ? (without {id})
can i hide this json from the users ?
Is this safe ?
how will angular now all the users propertys ? (i suggest i can retrieve this from the json)
any pro tips on how to solve this?
From AngularJS you are calling HTTP POST method and at Spring side you have declared as HTTP GET, which is wrong.
Correct request mapping is
#RequestMapping(value = "/api/authenticate",method = RequestMethod.POST, consumes = "application/json")
#ResponseBody
public User getUser(#RequestBody User user) {
//here request body contains User POJO object's payload (JSON object)
//You are getting username from JSON,
//so you need to update your call to findOne method
return repo.findOne(user.getUserName());
}
Please refer
#RequestBody and #ReponseBody spring
#RequestBody annotation spring docs
#RequestMapping#consumes

Redirect with 301 status in Spring MVC 4 without ModelAndView

I try to have a redirect with 301 Status Code (you know I want to be SEO friendly etc).
I do use InternalResourceViewResolver so I wanted to use some kind of a code similar to return "redirect:http://google.com" in my Controller.
This though would send a 302 Status Code
What I have tried is using a HttpServletResponse to set header
#RequestMapping(value="/url/{seo}", method = RequestMethod.GET)
public String detail(#PathVariable String seo, HttpServletResponse response){
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return "redirect:http://google.com";
}
It does still return 302.
After checking documentation and Google results I've come up with the following:
#RequestMapping(value="/url/{seo}", method = RequestMethod.GET)
public ModelAndView detail(#PathVariable String seo){
RedirectView rv = new RedirectView();
rv.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
rv.setUrl("http://google.com");
ModelAndView mv = new ModelAndView(rv);
return mv;
}
It does work perfectly fine and as expected, returning code 301
I would like to achieve it without using ModelAndView (Maybe it's perfectly fine though). Is it possible?
NOTE: included snippets are just parts of the detail controller and redirect does happen only in some cases (supporting legacy urls).
I would suggest using redirectView of spring like you have it. You have to have a complete URL including the domain etc for that to work, else it will do a 302. Or if you have access to HttpServletResponse, then you can do the below as below.
public void send301Redirect(HttpServletResponse response, String newUrl) {
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
response.setHeader("Location", newUrl);
response.setHeader("Connection", "close");
}
Not sure when it was added, but at least on v4.3.7 this works. You set an attribute on the REQUEST and the spring View code picks it up:
#RequestMapping(value="/url/{seo}", method = RequestMethod.GET)
public String detail(#PathVariable String seo, HttpServletRequest request){
request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.MOVED_PERMANENTLY);
return "redirect:http://google.com";
}
If you already return a ModelAndView and don't want to use HttpServletResponse, you can use this snippet:
RedirectView rv = new RedirectView("redirect:" + myNewURI);
rv.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
return new ModelAndView(rv);

Categories