Spring MVN Controller works in GET but does not in POST - spring-mvc

I have this simple Controller
#Controller
#RequestMapping("/login")
public class LoginController {
private ModelAndView model;
#RequestMapping(value="/loginUser/{username}/{password}", method=RequestMethod.GET)
public ModelAndView loginUser(#PathVariable(value="username") String username, #PathVariable(value="password") String password) {
try {
if( checkCredential( username , password ) ) {
model = new LoginResult( "loginOK" );
model.addObject( "msg" , username );
} else {
model = new LoginResult( "loginKO" );
model.addObject( "msg" , "Impossible to login the user " + username );
}
} catch(Exception e) {
e.printStackTrace();
}
return model;
}
}
and this simple JSP to execute the login
<form method="get" action="/login/loginUser">
<div class="div-top-end-space"> </div>
<div>
<label class="form-label"><i class="fa fa-chevron-right fa-1"></i> USERNAME:</label>
<input class="form-input" type="text" name="username" ng-model="username" />
</div>
<div>
<label class="form-label"><i class="fa fa-chevron-right fa-1"></i> PASSWORD:</label>
<input class="form-input" type="password" name="password" ng-model="password" />
</div>
<div class="div-separator"></div>
<div>
<input type="submit" value="LOGIN" ng-disabled="checkCredential()"/>
</div>
<div class="div-top-end-space"> </div>
</form>
This code works properly, but I have to put into the URL
http://localhost:9001/MY_APP/login/loginUser/aaa/bbb
But I do not want that username and password are shown into the browser's URL.
So I change the method into the form in method="post" and into the controller, method="RequestMethod.POST".
When I run my application and I insert my username and password, it does not work, and into the URL I see this
http://localhost:9001/login/loginUser
Where did my application's name go???
How I can solve it?
Thanks to everybody.
Daniele.

Related

How to pass a js variable to the controller in ASP.NET Core

I am sending an id in my js code and I want to pass that variable to my controller. Any advice on how I can do that?
<input class="btn_confirm" type="submit" id={i}
onclick="id_click(this.id)" value="Delete" />
var id;
function id_click(clicked_id) {
id = clicked_id;
}
I tried different things but nothing worked out.
I tried as below:
Model:
public class ReceiveModel
{
public int Id { get; set; }
public string Name { get; set; }
public string SomeKey { get; set; }
}
View:
<div class="row">
<div class="col-md-4">
<form id="form" asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<input id="1" type="submit" value="Create" class="btn btn-primary" />
</div>
<div class="form-group">
<input id="2" type="submit" value="Create" class="btn btn-primary" />
</div>
<div class="form-group">
<input id="3" type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
$("input[type='submit']").click(function ()
{
var tempid = this.id
var tmpInput = $("<input type='text' name='SomeKey' hidden/>");
tmpInput.attr("value", tempid );
var form = $("#form")
form.append(tmpInput)
form.submit()
})
</script>
Result:
You can lookup API requests. If you want to send one parameter as a primitive type (string, integer, etc.) you can use query strings in your API calls. For example, let's assume you have an API endpoint like this: localhost:5000/api/YourController. You can send params via API get calls like this localhost:5000/api/YourController?yourParam=<param-value>. In this example your API call type is GET.
If you want to send complex types (like classes, objects) to your controller you can lookup POST API requests.
You can find more details in this documentation.

Spring ModelAttribute not biding values Tomcat 9, Spring 5 MVC

I migrated from Spring 3 to 5, upgraded to Tomcat 9. After upgrading not able to get the values from JSP to Controller. #ModelAttribute is not binding the values entered in JSP, while submitting the form.
JSP Code:
<form:form action="/login" modelAttribute="identity" id="loginForm" cssClass="clearfix nodisplay">
<div class="grouping text">
<label for="email">E-mail Address</label>
<form:input path="email" id="email" cssClass="regInput" cssErrorClass="error" />
<form:errors path="email" cssClass="errors" />
</div>
<div class="grouping text">
<label for="pwd">Password</label>
<form:password path="pwd" id="pwd" cssClass="regInput" cssErrorClass="error" autocomplete="off" />
<form:errors path="pwd" cssClass="errors" />
</div>
<div class="grouping remember">
<input type="checkbox" name="remember" id="remember" />
<label for="remember">Remember Me</label>
</div>
<div class="btns clearfix">
<span class="login-btn">
<input type="hidden" name="cookieExist" id="cookieExist" value="false" />
<button type="button" name="login" class="btn js-login-btn"><span class="pictos">K</span> Login</button>
</span>
<span class="password-forget">
I forgot my password
</span>
</div>
</form:form>
Controller Code
#Controller
public class LoginController {
#RequestMapping(method=RequestMethod.GET, value="/login")
public String loginGet(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap,
#ModelAttribute Identity identity){
// commented business logic code
return "login";
}
#RequestMapping(method=RequestMethod.POST, value="/login")
public String loginPost(HttpServletRequest request, HttpServletResponse response,
ModelMap modelMap, #ModelAttribute("identity") Identity identity, BindingResult bindingResult) {
//commented out business logic
return "dashboard";
}
#ModelAttribute("identity")
public Identity formBackingObject() {
return new Identity();
}
}
I have migrated with no webxml way, not sure what else i'm missing here?
No need of action here in the form tag. Mention method in the form tag. So chnage to:
<form:form modelAttribute="identity" method="post" id="loginForm" cssClass="clearfix nodisplay">
And also change your primary action button to:
<input type="submit" ... />

spring+ thymeleaf unable to update

Hi I am working with spring MVC and thymeleaf and I am not able to update data from my controller as I have following code.The main problem I am facing is that my put method is not getting called.
#GetMapping("/{id}/edit")
public String editUser(#PathVariable("id") int id, Model model) {
logger.info("++++++++++++[edit User]\n\n" + userService.findById(id));
model.addAttribute("user", userService.findById(id));
return "user/edit";
}
#PutMapping("/{id}/edit")
public String updateUser(#PathVariable("id") int id, #ModelAttribute("user") User user, Model model) {
logger.info("\n\n+++++++++++++++++inside Update");
User toUpdate = userService.findById(user.getId());
user.setUserName(user.getUserName() != null ? user.getUserName() : toUpdate.getUserName());
user.setName(user.getName() != null ? user.getName() : toUpdate.getName());
logger.info(user.toString());
userService.updateUser(user);
model.addAttribute("user", userService.findById(user.getId()));
return "redirect:/user/" + id;
}
and my html page
<form action="#" th:action="#{/user/__${user.id}__}" method="put"
th:object="${user}">
<div class="form-group">
<label for="txtUserName">User-name</label> <input
class="form-control" id="txtUserName" placeholder="User Name"
th:feild="${user.userName}" />
</div>
<div class="form-group">
<label for="txtName">First Name</label> <input
class="form-control" id="txtName" placeholder="Full Name"
th:feild="${user.name}" />
</div>
<div class="form-group">
<label for="calDob">Date of Birth</label> <input
class="form-control" id="calDob" placeholder="dd/MM/yyyy" />
</div>
<button type="submit" th:method="put" class="btn btn-success">Update</button>
<a href="#" th:href="#{/user/__${user.id}__}"
class="btn btn-primary">Cancel</a> <a th:method="delete"
href="javascript:deleteUser('${user.id}');" class="btn btn-danger">Delete</a>
</form>
any help will be usefull thanks
PUT is not a valid argument for method attibute of the form tag. See HTML specification.
Valid methods are GET and POST. And as it's not a REST API, you can use POST method to update.
So just update your mapping from:
#PutMapping("/{id}/edit")
to
#PostMapping("/{id}/edit")
And form tag to:
<form action="#" th:action="#{/user/__${user.id}__}/edit" method="post" th:object="${user}">

Controller doesn't redirect after form submit

I'm new to ASP.net MVC and I am struggling to make this work at the moment. I have a controller method called Add, it looks like this:
public ActionResult Add()
{
// check user is authenticated
if (Request.IsAuthenticated)
{
return View();
}
return RedirectToAction("Index", "Home");
}
//
// POST: /Home/Add
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add(string title, string description, string priority, string color, FormCollection collection)
{
if (ModelState.IsValid)
{
// create instance of todo object
todo obj = new todo();
try
{
// gather fields
obj.priority = Convert.ToInt32(priority);
obj.color = Convert.ToInt32(color);
obj.title = title;
obj.description = description;
todosDataContext objLinq = new todosDataContext();
// get the users id, convert to string and store it
var userid = Membership.GetUser().ProviderUserKey;
obj.userid = userid.ToString();
// save
objLinq.todos.InsertOnSubmit(obj);
objLinq.SubmitChanges();
return RedirectToAction("Index", "Home");
}
catch
{
return View(obj);
}
}
return RedirectToAction("Index", "Home");
}
If data is sent via POST to the method, it should add the data to the database. That is working fine and everything is added correctly. However, the RedirectToAction is not firing, and the application gets stuck at /Home/Add, when it should redirect to /Home/Index. The view loads however, so it shows /Home/Index but the URL says /Home/Add.
Here is a copy of the partial view that contains the form:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<todo_moble_oauth.Models.todo>" %>
<% using (Html.BeginForm()) { %>
<%: Html.AntiForgeryToken() %>
<%: Html.ValidationSummary(true) %>
<fieldset>
<h3>Title:</h3>
<div class="editor-field">
<input type="text" name="title" />
</div>
<h3>Description:</h3>
<div class="editor-field">
<input type="text" name="description" />
</div>
<h3>Priority:</h3>
<div class="editor-field">
<select name="priority">
<option value="1">Low</option>
<option value="2">Medium</option>
<option value="3">High</option>
</select>
</div>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<h3>Color:</h3>
<input type="radio" name="color" id="radio-choice-1" value="0" checked="checked" />
<label for="radio-choice-1">None</label>
<input type="radio" name="color" id="radio-choice-2" value="1" />
<label for="radio-choice-2">Red</label>
<input type="radio" name="color" id="radio-choice-3" value="2" />
<label for="radio-choice-3">Blue</label>
<input type="radio" name="color" id="radio-choice-4" value="3" />
<label for="radio-choice-4">Yellow</label>
</fieldset>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
So data is being sent to the database and stored, however the redirect is broken.
Turns out it is an issue with jQuery mobile, this threads solution resolved the issue for me:
jQuery Mobile/MVC: Getting the browser URL to change with RedirectToAction

Submitting a form to MVC

My form code is not generating correct HTML. Here's my code.
Here's the form code:
#using (Html.BeginForm("SendEmail", "PropertyDetails", FormMethod.Post))
{
<fieldset>
<div class="left">
<label for="Name">Your Name</label>
<input type="text" required name="Name" />
<label for="Phone">Your Phone Number</label>
<input type="text" required name="Phone" />
<label for="Email">Your Email</label>
<input type="email" class="text" required name="Email" />
</div>
<div class="right">
<label for="Message">Your Message</label>
<textarea name="Message">
</textarea>
<input type="submit" name="submit" value="send" />
<div class="clear"></div>
</div>
<div class="clear"></div>
</fieldset>
}
Here's my Controller. I have a breakpoint on the first line of the SendMail message which isn't being hit:
public class PropertyDetailsController : Controller
{
[HttpPost]
public ActionResult SendEmail(EmailData email)
{
if (ModelState.IsValid) // BREAKPOINT ON THIS LINE ISN'T BEING HIT
{
etc.
Here's the class that should get populated with the form data and passed into the method (I'm not doing this myself. I assume it's happening automatically under the covers).
public class EmailData
{
private string _name;
private string _email;
private string _phone;
private string _message;
[Required]
[StringLength(50, MinimumLength = 1)]
public string Name
{
get { return _name; }
set { _name = value == null ? string.Empty : value.Trim(); }
}
[Required]
[RegularExpression(RegEx.Email, ErrorMessage = "Invalid e-mail address.")]
public string Email
{
get { return _email; }
set { _email = value == null ? string.Empty : value.Trim(); }
}
public string Phone
{
get { return _phone; }
set { _phone = value == null ? string.Empty : HtmlHelper.StripIllegalXmlChars(value.Trim()); }
}
[StringLength(500, MinimumLength = 1)]
public string Message
{
get { return _message; }
set { _message = value == null ? string.Empty : HtmlHelper.StripIllegalXmlChars(value.Trim()); }
}
}
Here's the HTML that's being generated:
<form action="" method="post">
<fieldset>
<div class="left">
<label for="Name">Your Name</label>
<input type="text" required name="Name" />
<label for="Phone">Your Phone Number</label>
<input type="text" required name="Phone" />
<label for="Email">Your Email</label>
<input type="email" class="text" required name="Email" />
</div>
<div class="right">
<label for="Message">Your Message</label>
<textarea name="Message">
</textarea>
<input type="submit" name="submit" value="send" />
<div class="clear"></div>
</div>
<div class="clear"></div>
</fieldset>
</form>
Any ideas why the action is empty?
Change your <form> declaration to this:
<% using (Html.BeginForm("SendEmail", "[Controller]")) { %>
<!-- Form data -->
<% } %>
Where [Controller] is the name of your Controller minus "Controller". In other words, if the controller name is HomeController, you would use "Home".
Try changing the form declaration within your view to this (using Razor syntax):
#using (this.Html.BeginForm("SendEmail", "[your controller name]", FormMethod.Post))
{
[form HTML]
}
The using statement will ensure that your form is closed correctly.
Also the HtmlHelper.BeginForm extension method is flexible enough that it generates the URI for the action based on the routes defined in your application's RouteCollection, such that if your routes change the form does not need to be updated; the change in URI is handled gracefully and automatically.
You need to add an action to your form
<form action="/SendEmail/" method="post">
But really this should be done using the MVC3 BeginForm helper.
You need to have your HTML rendered by a controller. So put your HTML in a View called "SendEmail" and write a controller action with an [HttpGet] attribute.
Call the Action "SendEmail" and in it just do return View().
Like this
[HttpGet]
public ActionResult SendEmail()
{
return View();
}
That will cause the BeginForm to render the action="" properly.
Then once that's working you are going to have a problem when you do post the data back because the input fields aren't bound to you model. You need to add #model yournamespace.EmailData to the very top of your View and then you need to change your inputs to bind to the model properties.
I've no idea how good this link is but it's the first one I found that looks like it might guide you through a similar process http://geekswithblogs.net/WinAZ/archive/2010/10/30/an-mvc-3-contact-form.aspx

Resources