"org.springframework.web.servlet.PageNotFound handleHttpRequestMethodNotSupported" Request method 'POST' not supported - spring

I am using angular JS and Spring MVC+Spring Security in my application. When using $http like below:
$http.post('/abc/xyz/'+catalogId);
it is giving below error:
org.springframework.web.servlet.PageNotFound handleHttpRequestMethodNotSupported
WARNING: Request method 'POST' not supported.
Moreover I've put POST in my controller as well:
#RequestMapping(value = "/xyz/{catalogId}", method = RequestMethod.POST)
public #ResponseBody List<Category> getCategorybyCatalogId(#PathVariable(value = "catalogId") long catalogId, ModelMap modelMap,
HttpSession session) throws IOException {
if (catalogId != 0) {
return menuService.getCategorybyCatalogId(catalogId);
} else {
return null;
}
}
this problem started coming when I added spring security config class.
Please help!!

Related

Spring MVC - Stop redirect in Controller function

I have a Spring MVC Controller and a PUT mapping that consumes JSON. I receive the JSON and everything just fine, the problem is whenever I fire off the JSON the mapper wants to redirect to the URL, giving me error 500 because the server can't find any template for the URL. How can I stop Spring MVC from trying to redirect to the URL and just receive the JSON?
My relevant Controller code :
#RequestMapping(value = "admin/users/VMs", method = RequestMethod.PUT, consumes = "application/json")
public void removeVM(#RequestBody ManageVMRequest packet, Authentication authentication) {
System.out.println(packet.getVm());
System.out.println(packet.getUser_id());
}
You can try to return ResponseEntity<Void>
#RequestMapping(value = "admin/users/VMs", method = RequestMethod.PUT, consumes = "application/json")
public #ResponseBody ResponseEntity<Void> removeVM(#RequestBody ManageVMRequest packet, Authentication authentication) {
System.out.println(packet.getVm());
System.out.println(packet.getUser_id());
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
}

Spring MVC - #RequestMapping GET and POST #RequestMethod

I understand this question has been asked previously, I am learning Spring following along Spring Petclinic Sample project. There is no problem with processCreationForm, when a redirect is done to showOwner using GET it works as expected, but when I experiment it by using POST it throws HTTP Status 405 - Request method 'GET' not supported. Is it because processCreationForm is doing a redirect to showOwner I am unable to grab it as POST request?
#RequestMapping(value = "/owners/new", method = RequestMethod.POST)
public String processCreationForm(#Valid Owner owner,
BindingResult result) {
if(result.hasErrors()) {
return "owners/ownerForm";
} else {
this.clinicService.saveOwner(owner);
return "redirect:/owners/" + owner.getId();
}
}
#RequestMapping(value = "/owners/{ownerId}", method = RequestMethod.POST)
public ModelAndView showOwner(#PathVariable("ownerId") int ownerId) {
ModelAndView mav = new ModelAndView("owners/ownerDetails");
mav.addObject(this.clinicService.findOwnerById(ownerId));
return mav;
}
Any helpful comments are appreciated.
You're redirecting to /owners/{ownerId} url, but you didn't define a GET handler for that endpoint, hence Spring MVC complains with:
HTTP Status 405 - Request method 'GET' not supported.
Using RequestMethod.GET will solve your problem:
#RequestMapping(value = "/owners/{ownerId}", method = RequestMethod.GET)
public ModelAndView showOwner(#PathVariable("ownerId") int ownerId) { ... }
Is it because processCreationForm is doing a redirect to showOwner I
am unable to grab it as POST request?
Since your POST handler on /owners/new is redirecting to /owners/{ownerId}, does not mean that redirection will be a POST request. Redirections are always GET requests.

Custom Exception when the URL is invalid and when the Database is not connect - Spring MVC

this example is useful when I want to validate the existence of an object.
#ResponseStatus(value=HttpStatus.NOT_FOUND)
public class CustomGenericException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String errCode;
private String errMsg;
#Controller
public class MainController {
#RequestMapping(value = "/units/{id}", method = RequestMethod.GET)
public ModelAndView getPages(Integer id)
throws Exception {
if ( service.getUnidad(id) == null) {
// go handleCustomException
throw new CustomGenericException("E888", "This is custom message");
}
}
#ExceptionHandler(CustomGenericException.class)
public ModelAndView handleCustomException(CustomGenericException ex) {
ModelAndView model = new ModelAndView("error/generic_error");
model.addObject("errCode", ex.getErrCode());
model.addObject("errMsg", ex.getErrMsg());
return model;
}
URL : /units/85
The unit 85 does not exist.
But I want to custime exception when I enter a URL invalid (For example /thisurlnoexists),
and the output should be THIS URL IS INCORRECT.
So I want to know if there is any way to intercept url exepcion customize without having to type throw new EXAMPLEEXCEPTION in the method. The same would like to know if I get an SQL error.
Thanks in advance
UPDATE
For 404 page not found , its work fine. The code is
web.xml
<error-page>
<error-code>404</error-code>
<location>/error</location>
</error-page>
controller
#RequestMapping("error")
public String customError(HttpServletRequest request, HttpServletResponse response, Model model) {
model.addAttribute("errCode", "324");
model.addAttribute("errMsg", "PAGE NOT FOUND");
return "error";
}
But for Database this code not found
#ControllerAdvice
public class GeneralExceptionController {
#ExceptionHandler({SQLException.class,DataAccessException.class})
public String databaseError(ModelMap model, Exception exception) {
model.addAttribute("errCode", "ERROR");
model.addAttribute("errMsg", "SQL");
return "error";
}
#ExceptionHandler(Exception.class)
public ModelAndView handleError(HttpServletRequest req, Exception exception) {
ModelAndView mav = new ModelAndView();
mav.addObject("errCode", exception);
mav.addObject("errMsg", req.getRequestURL());
mav.setViewName("error");
return mav;
}
}
Controller
#RequestMapping(value = "/sites", method = RequestMethod.GET)
public String getSites(#RequestParam(required = false) String error, ModelMap modelMap) {
List sites = siteBusiness.getAllSites(); //assume that the database is offline, at this point the exception originates
modelMap.put("sites", sites);
return "sites";
}
Spring controller has different notions for inexistant, and invalid Urls.
Taking your example :
/uuuunits/* : NoSuchRequestHandlingMethodException (at DispatcherServlet level) -> 404
/units/foo : (you asked for an Integer ) : TypeMismatchException -> 400
/units/85 : to be dealt with by controller.
You will find references on Spring Reference Manual/ Web MVC framework / Handling Exceptions
If you're looking for Urls that are invalid, it means those URL don't Exist. Hence, all that you need is a 404-Page not Found handler, and you can easily set up that in spring.
About connection error to database, The same applies to it also.
You can make your application container handle such exceptions.
Uncaught exceptions within an application can be forwarded to an error page as defined in the deployment descriptor (web.xml).
<error-page>
<exception-type>Your-exception-here</exception-type>
<location>/error</location>
</error-page>
You can a common page for all your DB errors using the following code snippet.

Spring MVC Controller respond on case of error

I have the following controller method :
#RequestMapping(value = "/", method = RequestMethod.POST)
#ResponseStatus(value = HttpStatus.CREATED)
#ResponseBody
public AbstractIngoingMessage postMessages(Locale locale, Model model, HttpServletRequest request, HttpServletResponse response) {
logger.info(String.format(
Constants.LogMessages.NEW_POST_REQUEST_FROM_IP,
request.getRemoteAddr()));
AbstractIngoingMessage handledMessage = dispatchMessageHandling(request);
return handledMessage;
}
problem is, when an error occurred on the method the response im sending back is still "CREATED"
is there a way to respond with "ERROR" ?

Spring security perform validations for custom login form

I need to do some validations on the login form before calling the authenticationManager for authentication. Have been able to achieve it with help from one existing post - How to make extra validation in Spring Security login form?
Could someone please suggest me whether I am following the correct approach or missing out something? Particularly, I was not very clear as to how to show the error messages.
In the filter I use validator to perform validations on the login field and in case there are errors, I throw an Exception (which extends AuthenticationException) and encapsulate the Errors object. A getErrors() method is provided to the exception class to retrieve the errors.
Since in case of any authentication exception, the failure handler stores the exception in the session, so in my controller, I check for the exception stored in the session and if the exception is there, fill the binding result with the errors object retrieved from the my custom exception (after checking runtime instance of AuthenticationException)
The following are my code snaps -
LoginFilter class
public class UsernamePasswordLoginAuthenticationFilter extends
UsernamePasswordAuthenticationFilter {
#Autowired
private Validator loginValidator;
/* (non-Javadoc)
* #see org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#attemptAuthentication(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
#Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
Login login = new Login();
login.setUserId(request.getParameter("userId"));
login.setPassword(request.getParameter("password"));
Errors errors = new BeanPropertyBindingResult(login, "login");
loginValidator.validate(login, errors);
if(errors.hasErrors()) {
throw new LoginAuthenticationValidationException("Authentication Validation Failure", errors);
}
return super.attemptAuthentication(request, response);
}
}
Controller
#Controller
public class LoginController {
#RequestMapping(value="/login", method = RequestMethod.GET)
public String loginPage(#ModelAttribute("login") Login login, BindingResult result, HttpServletRequest request) {
AuthenticationException excp = (AuthenticationException)
request.getSession().getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
if(excp != null) {
if (excp instanceof LoginAuthenticationValidationException) {
LoginAuthenticationValidationException loginExcp = (LoginAuthenticationValidationException) excp;
result.addAllErrors(loginExcp.getErrors());
}
}
return "login";
}
#ModelAttribute
public void initializeForm(ModelMap map) {
map.put("login", new Login());
}
This part in the controller to check for the instance of the Exception and then taking out the Errors object, does not look a clean approach. I am not sure whether this is the only way to handle it or someone has approached it in any other way? Please provide your suggestions.
Thanks!
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView signInPage(
#RequestParam(value = "error", required = false) String error,
#RequestParam(value = "logout", required = false) String logout) {
ModelAndView mav = new ModelAndView();
//Initially when you hit on login url then error and logout both null
if (error != null) {
mav.addObject("error", "Invalid username and password!");
}
if (logout != null) {
mav.addObject("msg", "You've been logged out successfully.");
}
mav.setViewName("login/login.jsp");
}
Now if in case login become unsuccessfull then it will again hit this url with error append in its url as in spring security file you set the failure url.
Spring security file: -authentication-failure-url="/login?error=1"
Then your URl become url/login?error=1
Then automatically signInPage method will call and with some error value.Now error is not null and you can set any string corresponding to url and we can show on jsp using these following tags:-
<c:if test="${not empty error}">
<div class="error">${error}</div>
</c:if>

Resources