How to solve " No mapping for GET HTTP URL" - spring

I am working on webapp using spring mvc + hibernate. I am getting a warning as
WARN [org.springframework.web.servlet.PageNotFound] (default task-1) No mapping for GET /ProjectFE/deleteproducts/
here's my code for Controller mapped deleteproducts:
#DeleteMapping(value="/deleteproducts/{productId}")
public String deleteProduct(#PathVariable("productId")int productId) {
IProductsDAO ip = new ProductsDAOImpl();
boolean b = ip.deleteProduct(productId);
if(b)
return "success";
else
return "deleteproducts";
}
jsp view:
<body>
<form id="update product form" action="${pageContext.request.contextPath}/deleteproducts" style="display: none;">
<div class="form-group row">
<label for="product Id" class="col-sm-2 col-form-label">Id</label>
<div class="col-sm-10">
<input type="text" name="productId" class="form-control" id="productId" placeholder="Enter the product Id you want to delete">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search"></span>
</button>
</div>
</div>
</form>
</body>
DAOImplementation for delete method call:
public boolean deleteProduct(int productId)
{
boolean b = true;
try
{
sess.beginTransaction();
Products p = (Products)sess.load(Products.class, new Integer(productId));
sess.delete(p);
sess.getTransaction().commit();
}catch(Exception ex)
{
sess.getTransaction().rollback();
b = false;
}
return b;
}
can this issue be occurring because of the /{productId} part ? Please some one help!!
Thankyou.

First, create a controller to go to deleteproduct.jsp page. So write a controller like
#GetMapping(value="/delete")
public String deleteProduct() {
return "deleteproducts";
}
So hit /delete to got to page then do as you want.
Change your #DeleteMapping to #GetMapping. And use #RequestParam instead of #PathVariable. So your controller will be like
#GetMapping(value="/deleteproducts")
public String deleteProduct(#RequestParam(value="productId")String productId) {
IProductsDAO ip = new ProductsDAOImpl();
boolean b = ip.deleteProduct(Integer.parseInt(productId));
if(b)
return "success";
else
return "deleteproducts";
}
And write your form like
<form id="searchForm" class="form-horizontal" action="${pageContext.request.contextPath}/deleteproducts">
<div class="input-group">
<input name="productId" placeholder="Delete product with id" class="form-control productId"
type="text">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</form>

You are trying to get an endpoint which doesn't exists. Why?
When you specify an endpoint /some_end_point and you trying to reach it with http protocol, it will expect you to specify the request method (GET / POST / PUT / DELETE / etc...).
When you have those 2 parameters /some_end_point + POST you need to map it in your server side like this -> #PostMapping("/some_end_point").
If the client (or another server) will try to reach /some_end_point + GET it will fail because it doesn't exists, only /some_end_point + POST exists, therefor you have to add another endpoint which will be #GetMapping("/some_end_point") and so on.

You are sending a GET request,
but you annotated with #DeleteMapping - which expects a DELETE request.

Related

How to implement reCaptcha "v2" in ASP.NET Core MVC?

I want to add Recaptcha, the second version, not another version, and I want it to be in ASP.NET Core, not MVC, and I searched a lot and did not find the solution.. I hope for help
I have a login controller :
public IActionResult Login([Bind("Username , Password")] User userLogin)
{
const string id = "id";
var auth = _context.Users.Where(x => x.Username == userLogin.Username &&
x.Password == userLogin.Password).SingleOrDefault();
var x = _context.Users.Where(x => x.Username == userLogin.Username && x.Password
== userLogin.Password).Select(i => i.UserId).FirstOrDefault();
if (auth != null)
{
// 1 > admin
// 2 > Accountant
// 3 > customer
switch (auth.RoleId)
{
case 1: // admin
HttpContext.Session.SetInt32(id, (int)x);
return RedirectToAction("Index", "Home");
case 2:
HttpContext.Session.SetInt32(id, (int)x);
return RedirectToAction("AccountantDashboard", "Home");
case 3:
HttpContext.Session.SetInt32(id, (int)x);
return RedirectToAction("Home", "Home");
}
}
return View();
}
and another for view (head and body)
<form asp-action="Login" enctype="multipart/form-data">
<div class="input-group">
<label asp-for="Username" class="input--style-2" placeholder="username"></label>
<input asp-for="Username" class="input--style-2" />
<span asp-validation-for="Username" class="text-danger"></span>
</div>
<div class="input-group">
<label asp-for="Password" class="input--style-2" placeholder="Password"></label>
<input asp-for="Password" type="password" class="input--style-2" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="p-t-30">
<button class="btn btn--radius btn--green" type="submit" value="Create">Login</button>
</div>
<div style="position: relative ; left: 350px ; bottom: -50px">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Home">Or back to home page</a>
</div>
</form>
As far as I know, the reCaptcha "v2" is build based on js and we could directly use it inside the html page.
We could use it like this, firstly put below codes inside your view and it is used to put the g-recaptcha and it contains a callback method, if this method is called that means the user has passed the validation and you could show the button by using JQuery or javascript.
<div class="g-recaptcha" data-callback="recaptcha_callback" data-sitekey="xxxxx"></div>
Like this:
<script type="text/javascript">
function recaptcha_callback(){
$('#login).show();
}
</script>
More details, you could refer to this article.

Spring Web application tymeleaf : POST request directed to wrong address

I have post mapping for URL: "/bank/addnew" My controller looks like:
Upon submission the form is submitted to "http://127.0.0.1:8082/banks/%20/banks" However, I need it to go to "http://127.0.0.1:8082/banks/addnew". Thanks for the Help!
#Controller
public class BankController {
#Autowired private BankService bankService;
#GetMapping("/banks")
public String bankList() {
return "bank/bank_list";
}
#PostMapping(value="/banks/addnew")
public String addNew(Bank bank) {
bankService.save(bank);
return "redirect: /banks";
}
}
And my template:
<form method="POST" action="#" th:action="#{/banks/addnew}" >
<div class="form-group">
<label for="recipient-name" class="col-form-label">Bank Name:</label>
<input type="text" class="form-control" id="recipient-name" name="name">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
The Post Method was actually working okay. I checked it by printing the Model object inside the target controller. However, it was being submitted to the database a NULL value because I didn't initialize getters and setters for my Model. Finally, there was a space in the return string, thus I removed it.
The controller Should have a return statement with no space.
return "redirect:/banks";

how to resolve Request method 'GET' not supported

I am getting below warning as
WARN [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] (default task-1) Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported]
I have already set the method as POST but still I'm getting the above error. I'm getting this warning message for my delete controller all other CRUD operations are working fine, except delete.
Please find below code
Controller mapped deleteproducts :
#RequestMapping(value="/deleteproducts", method= RequestMethod.POST)
public String deleteProduct(#PathVariable("productId")int productId) {
IProductsDAO ip = new ProductsDAOImpl();
boolean b = ip.deleteProduct(productId);
if(b)
return "success";
else
return "deleteproducts";
here's my jsp view:
<body>
<form id="update product form" action="${pageContext.request.contextPath}/deleteproducts" method="post" role="form" style="display: none;">
<div class="form-group row">
<label for="product Id" class="col-sm-2 col-form-label">Id</label>
<div class="col-sm-10">
<input type="text" name="productId" class="form-control" id="productid" placeholder="Enter the product Id you want to delete">
</div>
</div>
</form>
</body>
DAOimplementation for delete Method call:
public boolean deleteProduct(int productId)
{
boolean b = true;
try
{
sess.beginTransaction();
Products p = (Products)sess.load(Products.class, new Integer(productId));
sess.delete(p);
sess.getTransaction().commit();
}catch(Exception ex)
{
sess.getTransaction().rollback();
b = false;
}
return b;
}
can some one now tell me what changes should I make in my code to fix this ?
Thank you!
edit 1:
#DeleteMapping(value="/deleteproducts/{productId}")
public String deleteProduct(#PathVariable("productId")int productId) {
IProductsDAO ip = new ProductsDAOImpl();
boolean b = ip.deleteProduct(productId);
if(b)
return "success";
else
return "deleteproducts";
}
still getting a warning as:
WARN [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] (default task-1) Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported]
I don't understand #RequestMapping(value="/deleteproducts", method= RequestMethod.POST)
what do you mean by this? You are making a RequestMapping want to delete a record and method is POST?
I would suggest please follow the standard way of development. If you want to delete DeleteMapping, for POST use PostMapping and to retrieve some information you can use GetMapping.
Ideally, it should be
#DeleteMapping("/deleteproducts/{id}")
public void deleteStudent(#PathVariable long id) {
deleteproductsRepository.deleteById(id); or some CRUD logic to delete
}
You can refer to this link for better understanding REST
AS i think request form going to GET Method you can try javascript to submit form with function call.
Please find below code :
<form id="update product form" action="${pageContext.request.contextPath}/deleteproducts" method="POST">
<div class="form-group row">
<label for="product Id" class="col-sm-2 col-form-label">Id</label>
<div class="col-sm-10">
<input type="text" name="productId" class="form-control" id="productid" placeholder="Enter the product Id you want to delete">
</div>
<div class="col-sm-10">
<input type="button" value="submit" onclick="javascript:formSubmit()" name="submit" ></a>
</div>
</div>
</form>
<script>
function formSubmit() {
if(!isEmpty(document.from.productId.value)){ //even you can validate values in productId
document.form.method='POST';
document.form.action='/deleteproducts';
document.form.submit();
}
)
<script>
After writing the below code
#DeleteMapping(value="/deleteproducts/{productId}")
public String deleteProduct(#PathVariable("productId")int productId) {
IProductsDAO ip = new ProductsDAOImpl();
boolean b = ip.deleteProduct(productId);
if(b)
return "success";
else
return "deleteproducts";
}
After this instead of running on a normal browser, try running it on a REST API. I tried it on POSTMAN API and I don't get the error. Look at the below image

Passing parameter from get to post method

I'm building an feature for a webste where a user can reset his password. He receives an email with a generated token in the url. When this link is clicked, the user is sent to the /reset page. The Get method for that page is the following:
#RequestMapping(value = "/reset", method = RequestMethod.GET)
public ModelAndView displayResetPasswordPage(ModelAndView modelAndView, #ModelAttribute User user, #RequestParam("token") String token) {
User u = userService.findByResetToken(token);
if (u == null) {
modelAndView.setViewName("error/404");
return modelAndView;
} else {
modelAndView.addObject("token", token);
modelAndView.setViewName("resetPassword");
return modelAndView;
}
}
This works fine, if the token in the url is changed, the user is sent to an error page. Now I want to pass this "token" parameter to the post method:
#RequestMapping(value = "/reset", method = RequestMethod.POST)
public ModelAndView setNewPassword(ModelAndView modelAndView, #RequestParam Map<String, String> requestParams, #ModelAttribute User user, BindingResult bindingResult, RedirectAttributes redir) {
System.out.println("token: " + requestParams.get("token"));
User u = userService.findByResetToken(requestParams.get("token"));
// User u = userService.findByEmail(user.getEmail());
if (u != null) {
User updatedUser = userService.updateUserPassword(user);
modelAndView.addObject("User",updatedUser);
modelAndView.setViewName("redirect:login");
return modelAndView;
} else {
modelAndView.setViewName("resetPassword");
}
return modelAndView;
}
This always returns the resetPassword view, since the requestparams.get("token") always returns an empty string. Am I not using the correct method to get the param value?
The reset password view:
<div class="wrapper">
<form class="form-signin" th:action="#{/reset}" method="post" th:object="${user}">
<h2 class="form-signin-heading">Reset wachtwoord</h2>
<input type="hidden" name="token" th:value="*{resetToken}"/>
<div class="form-group">
<input type="password" th:field="*{encryptedPassword}" id="password" class="form-control input-lg"
placeholder="Password" tabindex="3"/>
<div class="form-group">
<input type="password" th:field="*{matchingPassword}" id="password_confirmation"
class="form-control input-lg" placeholder="Confirm Password" tabindex="4"/>
</div>
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6">
<input type="submit" class="btn btn-secondary" value="Registreer"/>
</div>
</div>
</form>
This can be done by employing the Flash Scope that will allow your token to survive a redirect. You can do that by:
Making the first controller method accessing the second one via a redirect
Using RedirectAttributes on your first controller method and explicitly adding your token into the RedirectAttributes as a Flash Attribute
Take a look at the documentation about RedirectAttributes.

Spring Boot ModelAndView - cannot update value to Model

I am trying to create a form with 3 fields within the class LoginForm: usuario, senha, msgLogin.
I receive the fields usuário and senha from the input boxes and then I try to redirect to the same page with the same fields plus the field MsgLogin. But I've not been able to update the msgLogin field and I don't understand why.
These are the code:
HTML:
<form id="frmLogin" class="form col-md-12" action="#" th:action="#{/login}" th:object="${loginForm}" method="post">
<div class="form-group">
<label for="usuario" class="col-md-1">Usuário: </label>
<input type="text" id="usuario" placeholder="Email" th:field="*{usuario}"/>
</div>
<div class="form-group">
<label for="senha" class="col-md-1">Senha: </label>
<input type="password" id="senha" placeholder="senha" th:field="*{senha}"/>
</div>
<div class="row">
<button id="entrar">Entrar</button>
</div>
<div class="row">
<div id="msgLogin"></div>
<p th:text="${loginForm.msgLogin}" />
</div>
</form>
The Controller:
#RequestMapping("/")
public String init(#ModelAttribute LoginForm loginForm) {
Logger.getAnonymousLogger().info("Tela Inicial.");
return "home";
}
#PostMapping("/login")
public ModelAndView entrar(LoginForm loginForm) throws IOException {
Logger.getAnonymousLogger().info("Entrando no Internet Banking.");
service.login(usuario, senha);
ModelMap model = new ModelMap();
loginForm.setMsgLogin("I want to update that value!");
model.addAttribute("loginForm", loginForm);
return new ModelAndView("redirect:/", model);
}
Class using Lombok:
#Getter
#Setter
public class LoginForm {
private String usuario;
private String senha;
private String msgLogin;
}
A redirect send a 302 HTTP status back to the browser to resubmit using a new url, so it resubmits the same two fields to the new url. There's no expectation of payload data in the 302 response.
In your Controller, change the last line in your entrar method to: return new ModelAndView("/login", model);

Resources