Consider the snippet:
#Controller
#RequestMapping(value = "/spitter")
public class SpittrController {
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String showRegistrationForm() {
return "registerForm";
}
}
where registerForm.jsp is as simple as this:
<form method="post">
<table>
<tr>
<td>First Name:</td>
<td><input type="text" name="firstName" /></td>
</tr>
<tr>
<td>Last Name:</td>
<td><input type="text" name="lastName" /></td>
</tr>
<tr>
<td>User Name:</td>
<td><input type="text" name="userName" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td><input type="submit" value="Register" /></td>
</tr>
</table>
</form>
Whn I type the following URL in my web browser:
http://localhost:8080/web/spitter/register
I see this below page, which is fine, as per the functionality:
Now if I slightly modified the URL, and do something like this
http://localhost:8080/web/spitter/register/
then also the same page is rendered,
Why? Even though the entered address(URL) is not pointing to that request mapped in the controller.
Any suggestions?
EDIT:
The whole problem arises when I have to work with Spring Security.
Consider the snippet:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().and().authorizeRequests().antMatchers("/spitter/")
.authenticated().antMatchers(HttpMethod.GET, "/spitter/register")
.authenticated();
}
Now, when the user enters this in his browser,
http://localhost:8080/web/spitter/register
he is redirected to the login page to authenticate himself, while
http://localhost:8080/web/spitter/register/
doesn't redirects him to the login page, which is a security lapse.
and I have to make this entry to
antMatchers(HttpMethod.GET, "/spitter/register/").authenticated()
in addition to
antMatchers(HttpMethod.GET, "/spitter/register").authenticated()
Is there any cure of this to get rid of it or else it will double the effort just to append the / just to redirect to the login page?
Try this pattern
/spitter/register/**
Related
I have a controller in which I put both the get and post methods. Both methods work fine but when I introduce #ModelAttribute annotation to the POST method, it starts giving me Status 400 -- The request sent by the client was syntactically incorrect.
I do not know what I am doing wrong. The View looks like:
<form:form method="post" action="createIdeaPublic" commandName="idea">
<table class="form">
<tr>
<td align="right"><label for="title">Idea Title</label></td><td align="left"><form:input type="text" path="title" id="title"></form:input></td>
<td align="right"><label for="email">Your Email</label></td><td align="left"><form:input type="text" path="requestorEmail" id="requestorEmail" class="emails"></form:input></td>
</tr>
<tr>
<td align="right"><label for="partnerEmail">CI Contact Email</label></td><td align="left"><form:input type="text" path="cIInitialContact" id="cIInitialContact" class="emails"></form:input></td>
<td align="right"><label for="sponsorEmail">Sponsor Email</label></td><td align="left"><form:input type="text" path="sponsorEmail" id="sponsorEmail" class="emails"></form:input></td>
</tr>
<tr>
<td align="right"><label for="requestedDeliveryDate">Requested Delivery Date</label></td><td align="left"><form:input type="text" path="requestedDeliveryDate" id="requestedDeliveryDate" class="datepicker"></form:input></td>
<td align="right"><label>Classification</label></td><td align="left">
<label for="discretionary" class="radio">Discretionary</label>
<form:radiobutton path="stateDescription" id="discretionary" value="Discretionary"></form:radiobutton>
<label for="mandatory" class="radio">Mandatory</label>
<form:radiobutton path="stateDescription" id="mandatory" value="Mandatory"></form:radiobutton>
<label for="regulatory" class="radio">Regulatory</label>
<form:radiobutton path="stateDescription" id="regulatory" value="Regulatory"></form:radiobutton>
</td>
</tr>
<tr>
<td colspan="4" align="right"><input type="submit" class="ui ui-button ui-corner-all ui-widget" style="margin-top: .6em; margin-right: 1em;font-weight: bold;font-size: 1.2em; width: 150px;" value="Create Idea" /></td>
</tr>
</table>
</form:form>
I tried changing the commandName="idea" to modelAttribute="idea" but no benifit.
The Spring controller looks like
#Controller
#RequestMapping ("/createIdeaPublic")
public class CreateIdeaPublicController{
#RequestMapping(method = RequestMethod.GET)
public ModelAndView view(ModelMap model) {
model.addAttribute("areas",Utils.areas);
return new ModelAndView("createIdeaPublic", "idea", new Idea());
}
#RequestMapping(method = RequestMethod.POST)
public String submit(#ModelAttribute("idea")Idea idea, ModelMap model) {
// System.out.println(idea.getTitle());
System.out.println("Hello World");
return "redirect:createIdeaPublic";
}
}
But as soon as I remove the #ModelAttribute("idea")Idea idea, from the submit method, the form submission starts working.
I figured it out. It was issue with the date field. If I dont enter a value into the date field, I would get 400 page. So here is what I did in the Controller class. Copy as it is if you have this issue (Just change the date format accordingly).
#InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
dateFormat.setLenient(false);
// true passed to CustomDateEditor constructor means convert empty String to null
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
I am trying to run a validator class for my Spring form, but my errors are not showing up on my page. I'm a newbie when it comes to Spring validation, so there are undoubtedly some errors here. Here is my form. (Incidentally, Eclipse is posting warnings on the form:error lines that say, "List is a raw type. References to generic type List should be parameterized.")
<form:form commandName="bulletin" method="post" action="processBulletin">
<table>
<tr>
<td>Name:</td>
<td><form:errors path="name" /></td>
<td><form:input path="name" maxlength="30" /></td>
</tr>
<tr>
<td>Subject:</td>
<td><form:errors path="subject" /></td>
<td><form:input path="subject" maxlength="50" /></td>
</tr>
<tr>
<td valign="top">Message:</td>
<td><form:errors path="note" /></td>
<td><form:textarea path="note" cols="70" rows="20" /></td>
</tr>
<tr>
<td><input type="submit" /></td>
<td> </td>
</tr>
</table>
</form:form>
Here is my controller class. I'm calling the validation class from here, and I'm not sure if that's the right thing to do, so feel free to say so if it's not.
#RequestMapping(value = "/processBulletin", method = RequestMethod.POST)
public String processBulletin(
#ModelAttribute("bulletin") Bulletin bulletin, BindingResult result) {
final BindException errors = new BindException(bulletin, "bulletin");
bulletinValidator.validate(bulletin, errors);
if (errors.hasErrors()) {
return "redirect:/approvedBulletins";
} else {
// rest of method
}
return "redirect:/approvedBulletins";
}
Here is my validation class.
#Override
public boolean supports(Class<?> cls) {
return Bulletin.class.isAssignableFrom(cls);
}
#Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "subject", "Subject is required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "Name is required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "note", "Message is required");
}
}
Try to return view name instead of redirect return "redirect:/approvedBulletins"; when you have errors.
On my 'update user' page I have a hidden field to hold the ID of the current user being edited. I've checked the HTML source and the value populates correctly. However when I submit the form, the userID value ALWAYS comes through as 0 while every other field comes through correctly.
-I've tried setting the type as form:input and submitting it, still 0 on the controller side.
-There are no bindingresult errors.
-Page URL: /admin/update-user.html?uid=3 (I've tried changing the URL variable from uid to userID, no difference.)
So what the heck is going on?! Am I missing something obvious??
JSTL
<form:form commandName="user" method="POST">
<form:hidden path="userID"/>
<table width="400" cellpadding="3" cellspacing="0" border="0" class="datatable">
<tr>
<td>User ID #</td>
<td>${user.userID}</td>
</tr>
<tr>
<td valign="top">Password</td>
<td>****<br />Change Password</td>
</tr>
<tr>
<td>First Name</td>
<td><form:input path="firstName" /></td>
</tr>
<tr>
<td>Last Name</td>
<td><form:input path="lastName" /></td>
</tr>
<tr>
<td>Gender: </td>
<td>
<form:select path="gender">
<form:option value="Male" label="Male" />
<form:option value="Female" label="Female" />
</form:select>
</td>
</tr>
<tr>
<td>Birthday: </td>
<td><form:input path="birthday" id="datepickerpast" readonly="true" /></td>
</tr>
<tr>
<td>Email</td>
<td><form:input path="email" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" value="Update" /> <input type="reset"></td>
</tr>
</table>
</form:form>
Controller
#RequestMapping(value = "admin/update-user", method = RequestMethod.POST)
public String processUpdateUser(ModelMap model, #ModelAttribute("user") User user, BindingResult result) throws SQLException {
if (result.hasErrors()) {
model.addAttribute("user", user);
model.addAttribute("pagetitle", "Admin - Update User Details");
return "admin/users/update-user";
} else {
userDao.updateUser(user);
return "redirect:/admin/user-management.html";
}
}
Object Properties with appropriate getters/setters
private int userID;
private String firstName;
private String lastName;
private String username;
private String email;
private Date birthday;
private String gender;
Realized my getter was type Integer but my setter and property was type int. Made all of them Integer and it worked. If someone can explain why there was no error on compile or why it didn't work the way it was, that'd be greatly appreciated.
Sigh, there goes 3 hours of my life.
You got a compiler error because of autoboxing, which allows for the automatic conversion of primitives to their wrapper class alternatives. As to why it didn't work when the getter was using Integer, I can't help you there.
I am trying to create a jsp form for inputting the user information.
I am using a controller to display the input page.
I have added an User bean object with the modelmap.The controller returns the ModelandView object.
The problem lies here.No model value gets returned to the jsp page. Anybody know why this happens??please help me...
<context:annotation-config/>
<context:component-scan base-package="com.mobilize.rest"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<import resource="configuration/messageConverter.xml"/>
<import resource="configuration/viewResolveContext.xml"/>
The code below shows the controller used to get the view AddUSer.jsp page
While debugging the values are properly stored in the object.
But the problem is that the object doesnt get received at the form page.
#RequestMapping(value = "/AddUser.html", method = RequestMethod.GET)
public ModelAndView addUser(
#RequestParam(value = "reload", required = false, defaultValue = "false")
Boolean reload,
#RequestParam(value = "reset", required = false, defaultValue = "false")
Boolean reset,HttpServletRequest request) {
HttpSession httpSession = request.getSession();
ModelMap modelmap = new ModelMap();
Users users = new Users();
modelmap.addAttribute("users", users);
modelmap.addAttribute("MOB_USER_ADD_STATUS_SUCCESS_MESSAGE","trial");
return new ModelAndView("AddUser", modelmap);
}
[Edited, additional code moved from comment section]
<div id="content" style="height:508px"> <br/>
<c:if test="${MOB_USER_ADD_STATUS_SUCCESS_MESSAGE!=null}">
<div align="center"
id="statusIndicator"
class="successMessage">${MOB_USER_ADD_STATUS_SUCCESS_MESSAGE}
</div>
</c:if>
${MOB_USER_ADD_STATUS_SUCCESS_MESSAGE}
<form:form commandName="users"
method="POST"
action="AddUser.html">
<table>
<tr>
<td> User Name: </td>
<td><form:input path="userName"
id="username">
</form:input>
</td>
</tr>
<tr>
<td></td>
<td><form:errors path="userName"
cssClass="errorMessage">
</form:errors>
</td>
</tr>
<tr>
<td> Password: </td>
<td> <form:textarea path="password" id="password"></form:textarea> </td>
</tr>
<tr>
<td></td>
<td><form:errors path="password" cssClass="errorMessage"></form:errors></td>
</tr>
<tr>
<td></td>
<td> <input type="submit" name="offer" value=" Add "/>
<input type= "reset"
name="Reset"
value=" Reset "
onclick="document.location.href='AddUser.html?reset=true'"/>
</td>
</tr>
</table>
</form:form>
</div>
The mistake was i imported the wrong class. Instead of importing org.springframework.web.servlet.ModelAndView , i imported
org.springframework.web.portlet.ModelAndView. That was the reason for the error. I should have been a bit more careful.
I am having problems getting my form to Post to my Save method in a controller. I am new to MVC, and have followed several examples to try to get this to work. Here is my html markup:
<form action="Edit/Save" method="post">
<fieldset>
<legend>Personal Information</legend>
<table class="editGrid">
<tr>
<td><label for="txtFirstName">First Name:</label></td>
<td><input type="text" id="txtFirstName" value="<%=user.FirstName %>" name="FirstName" /></td>
</tr>
<tr>
<td><label for="txtLastName">Last Name:</label></td>
<td><input type="text" id="txtLastName" value="<%=user.LastName %>" name="LastName" /></td>
</tr>
<tr>
<td><label for="txtNtLogin">NT Login:</label></td>
<td><input type="text" id="txtNtLogin" value="<%=user.NtLogin %>" name="NtLogin" /></td>
</tr>
<tr>
<td><label for="txtHireDate">Hire Date:</label></td>
<td><input type="text" id="txtHireDate" value="<%=string.Format("{0:d}",user.HireDate) %>" name="HireDate" /></td>
</tr>
</table>
</fieldset>
<fieldset>
<legend>Job Information</legend>
<table class="editGrid">
<tr>
<td><label for="CostCenters">Cost Center:</label></td>
<td><%=Html.DropDownList("CostCenters")%></td>
</tr>
<tr>
<td><label for="Managers">Manager:</label></td>
<td><%=Html.DropDownList("Managers")%></td>
</tr>
<tr>
<td><label for="Responsibilities">Responsibility:</label></td>
<td><%=Html.DropDownList("Responsibilities")%></td>
</tr>
<tr>
<td><label for="Departments">Department:</label></td>
<td><%=Html.DropDownList("Departments")%></td>
</tr>
<tr>
<td><label for="Active">Active:</label></td>
<td><%=Html.CheckBox("Active",user.Active) %></td>
</tr>
<tr>
<td><label for="txtHireDate">Hire Date:</label></td>
<td><%=Html.TextBox("txtHireDate",string.Format("{0:d}",user.HireDate)) %></td>
</tr>
<tr>
<td><label for="txtReleaseDate">Release Date:</label></td>
<td><%=Html.TextBox("txtReleaseDate",string.Format("{0:d}",user.ReleaseDate)) %></td>
</tr>
</table>
</fieldset>
<input type="submit" value="Save Changes" />
</form>
This form routes to a Save method in my EditController. Here is the code for my EditController's Save method:
public class EditController : Controller
{
public ActionResult Save()
{
//Save code goes here
}
I have tried using the html form tag, and also the Html helper code:
using (Html.BeginForm("Save", "Edit"))
Here is the entry from my RegisterRoutes method in the Global.asax file:
routes.MapRoute("EditSave", "{controller}/Save",
new { controller = "Edit", action = "Save" });
No matter what I do, the submit button does not trigger the Save method. Yet, if I manually key in the Url, The code breaks right into the Save method.
Edit:
Per Craig Stuntz's comment, I checked the source of the page. The page actually contains 2 forms, although only 1 is coded on the page by myself: Here is the HTML that appears prior to my form tag:
<form name="aspnetForm" method="post" action="44" id="aspnetForm">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJNjM3OTAyNTUzZGQrHhVn9+t78aHxN0vHvKUJ8DQWlQ==" />
</div>
<div id="nav">
<span id="navLinks">
Placeholder Link
</span>
<span id="userName">
<span id="ctl00_lblUserName" class="UserName">Welcome, Test User</span>
</span>
</div>
<div id="Content">
<div id="formContainer">
<form action="Edit/Save" method="post">
I didn't think MVC generated viewstate or additional form tags. I am pulling data and populating it into this form using another method from the same controller. Am I doing something wrong here?
Ok, got the answer. And thanks Craig for having me look at the HTML again! My master page had generated a form tag in it without my knowing it, so I essentially had nested forms on the same page. After I removed the form from the Master Page, everything worked perfectly.