Why the value in model.put is appended in URL - spring

I am building a Spring MVC Web App. In one Controller, I used model.put method to pass some information to a jsp file.
The following is the snippet of controller
#RequestMapping(value = "/login" , method= RequestMethod.POST)
public String loginPost(HttpSession session,ModelMap model, #RequestParam(value = "username") String username, #RequestParam(value = "password") String password) throws Exception {
User user = getUser(username, password);
if(user !=null){
session.setAttribute("username",username);
model.put("message","login successful ");
return "redirect:/index";
}else{
model.put("message","login failed");
return "redirect:/login";
}
}
The index.jsp and login.jsp:
<%# page contentType="text/html; charset=UTF-8" %>
<html>
<body>
Click to upload page
</body>
</html>
<%--
Created by IntelliJ IDEA.
User: cbl
Date: 2016/1/6
Time: 15:34
To change this template use File | Settings | File Templates.
--%>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>${message}</h1>
<form method = "POST" action = "/login">
<label for="username">Username</label>
<input id="username" type="text" name = "username">
<label for="password">Password</label>
<input id="password"type="password" name="password">
<input type="submit" value="login">
</form>
</body>
</html>
The ${message} is extected to be display within body, however, it is appended after URl:http://localhost:8000/login?message=login+failed and http://localhost:8000/index?message=login+successful++
Any response is appreciated

Since you are returning a redirect, a new GET request is created under the covers, that is why is getting attached to the url.
If you want to keep the data in the model only, you can use the flash scope with RedirectAttributes
#RequestMapping(value = "/login" , method= RequestMethod.POST)
public String loginPost(HttpSession session,
RedirectAttributes ra,
#RequestParam(value = "username") String username,
#RequestParam(value = "password") String password) throws Exception {
User user = getUser(username, password);
if(user !=null){
session.setAttribute("username",username);
ra.addFlashAttribute("message","login successful ");
return "redirect:/index";
}else{
ra.addFlashAttribute("message","login failed");
return "redirect:/login";
}
}

Related

Showing input parameter on same page in Thymeleaf

I am trying to show the results on the same page as the form in Thymleaf and Spring and this is what I have tried till now:
Controller:
#Controller
public class ThymeleafController {
#GetMapping("/hello")
public String getHello() {
return "hello";
}
#PostMapping("/test")
public String test(#RequestParam("text1")String str, Model model) {
model.addAttribute("sample", str);
return "test";
}
}
test.html page:
<!DOCTYPE html>
<html xmlns:th ="http://www.thymeleaf.org" >
<head>
<meta charset ="UTF-8" ></meta>
<title> Hello World</title>
</head>
<body>
<h1> Hello World</h1>
<form method ="post" action ="/test" >
Enter: <input type ="text" name ="text1" />
<input type ="submit" value ="click" />
</form>
<span th:text ="${sample == null} ? 'null' : ${sample}" ></span>
</body>
</html>
When i go on test page i see this error:
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'GET' not supported
org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
Can someone give me an ideea or an example how I could display a value on the same page as the form / input ? Thanks
Ref : https://hellokoding.com/handling-form-submission-example-with-java-spring-boot-and-freemarker/
Add for get , so this issue will get solved.
#Controller
public class ThymeleafController {
#GetMapping("/hello")
public String getHello() {
return "hello";
}
#GetMapping("/test")
public String testfrm() {
return "test";
}
#PostMapping("/test")
public String test(#RequestParam("text1")String str, Model model) {
return "test";
}
}

Spring mvc form submission bindingresult throws error

So my bindingresult throws an error but I'm not able to see it for some reason and I'm not able to figure out what the problem is. I'm guessing the problem lies with the variable targetDate where there is a problem the type. I've pasted my controller and JSP code below. Any help is appreciated!
#Controller
public class ToDoController {
#Autowired
private ToDoService service;
// All date parameters displayed as mm/DD/yyyy
#InitBinder
protected void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("mm/DD/yyyy");
binder.registerCustomEditor(Date.class, new CustomDateEditor(
dateFormat, false));
}
#RequestMapping(value = "/list-todo", method= RequestMethod.GET)
// HttpSession allows access to the session
public String showToDo(ModelMap model, HttpSession httpSession) {
String user = (String) httpSession.getAttribute("name");
model.addAttribute("todos", service.retrieveTodos(user));
return "list-todos";
}
// redirect to update form
#RequestMapping(value = "/update-todo", method= RequestMethod.GET)
public String getUpdateForm(ModelMap model, #RequestParam int id) {
System.out.println("ID " + id);
// To work with command bean
model.addAttribute("id", id);
model.addAttribute("todo", service.retrieveTodo(id-1));
return "updateToDo";
}
// What does Valid do?
#RequestMapping(value = "/update-todo", method= RequestMethod.POST)
public String submitUpdate(ModelMap model, #Valid ToDo todo, BindingResult result) {
if (result.hasErrors()) {
System.out.println("ERROR" + result.getAllErrors());
// Redirect and pass on the id value
return "redirect:/update-todo?id=" + todo.getId();
}
System.out.println("Update todo" + todo);
service.updateToDo(todo);
model.clear();
return "redirect:/list-todo";
}
// Will be executed first
#RequestMapping(value = "/add-todo", method= RequestMethod.GET)
public String showAddForm(ModelMap model) {
model.addAttribute("todo", new ToDo());
return "addToDo";
}
/*
* Will be executed after form is submitted
* #Valid ToDo - command bean from addToDo.jsp.
* #Valid to validate the information
* #BindingResult showcases the result of the validation
*/
#RequestMapping(value = "/add-todo", method= RequestMethod.POST)
public String submitAddForm(ModelMap model , #Valid ToDo todo, HttpSession httpSession, BindingResult result) {
System.out.println("running" + result);
// If there is validation error , return to addToDos page for user to fix the error
if (result.hasErrors()) {
return "redirect:/showAddForm?id=?" + todo.getId();
}
String user = (String) httpSession.getAttribute("name");
service.addTodo(user, todo.getDescription(), todo.getTargetDate(), false);
// Clears the url e.g. name?=jyj123
model.clear();
// return to the url which executes the showToDO
return "redirect:/list-todo";
}
// delete to do entry
#RequestMapping(value = "/delete-todo", method= RequestMethod.GET)
public String deleteToDo(ModelMap model, #RequestParam int id) {
service.deleteTodo(id);
model.clear();
return "redirect:/list-todo"; }
}
My JSP
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%# include file = "common/header.jspf" %>
<%# include file = "common/nav.jspf" %>
<div class="container">
<H1>Update your task!</H1>
<form:form method="POST" commandName="todo">
<!-- Carry on the id value -->
<form:hidden path = "id"/>
<form:hidden path = "user"/>
<fieldset class="form-group">
<form:label path="description">Description:</form:label>
<form:input path="description" type="text" class="form-control"
required="required" />
<form:errors path="description" cssClass="text-warning" />
</fieldset>
<fieldset class="form-group">
<form:label path="targetDate">Target Date</form:label>
<form:input path="targetDate" type="text" class="form-control"
required="required" />
<form:errors path="targetDate" cssClass="text-warning" />
</fieldset>
<fieldset class="form-group">
<form:radiobutton path="completion" value="true" />
<form:radiobutton path="completion" value="false" />
</fieldset>
<button type="submit" class="btn btn-success" >Submit Update</button>
</form:form>
<spring:hasBindErrors htmlEscape="true" name="todo">
<c:if test="${errors.errorCount gt 0}">
<h4>The error list :</h4>
<font color="red">
<c:forEach items="${errors.allErrors}" var="error">
<spring:message code="${error.code}"
arguments="${error.arguments}"
text="${error.defaultMessage}"/><br/>
</c:forEach>
</font>
</c:if>
</spring:hasBindErrors>
</div>
<%# include file = "common/footer.jspf" %>
EDIT: bindingresult throws this
ERROR[Field error in object 'todo' on field 'targetDate': rejected value [Tue Jan 05 00:00:00 SGT 2021]; codes [typeMismatch.todo.targetDate,typeMismatch.targetDate,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [todo.targetDate,targetDate]; arguments []; default message [targetDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'targetDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value 'Tue Jan 05 00:00:00 SGT 2021'; nested exception is java.lang.IllegalArgumentException]]
In your jsp you submit the form to "todo", not "update-todo". It would be nice to see your ToDo bean. Also: result.getAllErrors().

Spring RequestMethod "POST" not supported while File Upload

I am including File Upload feature in my Spring Security, Spring MVC application.
Here is my JSP page:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# page session="false" %>
<html>
<head>
<title>Upload File Request Page</title>
</head>
<body>
<form method="POST" action="uploadFile" enctype="multipart/form-data">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
File to upload: <input type="file" name="file"><br />
Name: <input type="text" name="name"><br /> <br />
<input type="submit" value="Upload"> Press here to upload the file!
</form>
</body>
</html>
Here is my Controller Method:
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public #ResponseBody
String uploadFileHandler(#RequestParam("name") String name,
#RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
// Creating the directory to store file
String rootPath = System.getProperty("catalina.home");
File dir = new File(rootPath + File.separator + "tmpFiles");
if (!dir.exists())
dir.mkdirs();
// Create the file on server
File serverFile = new File(dir.getAbsolutePath()
+ File.separator + name);
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(serverFile));
stream.write(bytes);
stream.close();
System.out.println("Server File Location="
+ serverFile.getAbsolutePath());
return "You successfully uploaded file=" + name;
} catch (Exception e) {
return "You failed to upload " + name + " => " + e.getMessage();
}
} else {
return "You failed to upload " + name
+ " because the file was empty.";
}
}
MultipartResolver Bean has been declared as shown below:
#Bean(name = "multipartResolver")
public CommonsMultipartResolver createMultipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
//resolver.setDefaultEncoding("utf-8");
resolver.setMaxUploadSize(1000000);
resolver.setMaxInMemorySize(1000000);
return resolver;
}
And my Spring Security HttpSecurity Configuration is:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/css/**").permitAll()
.antMatchers("/testDecorator").permitAll()
.antMatchers("/uploadFile").permitAll()
.antMatchers("/home")
.authenticated().and().formLogin().loginPage("/login")
.failureUrl("/login?error")
.successHandler(customSuccessHandler)
.usernameParameter("username").passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout").and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied");
}
When I chose file and submit the form. It is throwing below error:
org.springframework.web.servlet.PageNotFound handleHttpRequestMethodNotSupported
WARNING: Request method 'POST' not supported
When I use the same code in another project. It is working fine. I am not getting to know where I went wrong.
Can someone please guide me where can be the problem?
Regards,
Manju Raghavendra.
Have you configured a multipartResolver in your config files? It might look something like this:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="78643200"/>
<property name="maxInMemorySize" value="78643200"/>
</bean>

how to pass binding result object in RedirectView

I am new to spring and I am trying to redirect to the same page if the form has errors. I am successful redirecting that but the problem is the form has a dynamic drop down and the values are not rendered when I return a model object. or when I do ModelAndView(new RedirectView("lookup")) I am able to render the dropdown values but I am unable to display the error messages.
code: jsp: lookup.jsp
<form:form name="lookupForm" method="POST" action="search.html" enctype="multipart/form-data" >
<div style= "color:red">
<form:errors path="empId" /></br>
<form:errors path="companyName" />
</div>
<form:label path="companyName">Company</form:label>
<select name= "companyList" path="companyName">
<option value="Select">Select</option>
<c:forEach var="element" items="${listCompany}">
<option value="${element.companyName}">${element.companyName}</option>
</c:forEach>
</select>
<form:label path="empId">Employee ID</form:label>
<form:textarea name="empId" path="empId" rows="5" cols="30"/>
<input type="submit" name="search" value="Search"/>
Controller:
#RequestMapping(value = "/lookup", method = RequestMethod.GET)
public ModelAndView lookupFormView(ModelAndView model,BindingResult result) {
List<Employee> listCompany = employeeDAO.getCompany();
Employee newContact = new Employee();
model.addObject("listCompany", listCompany);
model.addObject("command", newContact);
model.setViewName("lookup");
return model;
}
#RequestMapping(value = "/search", params = "search", method = RequestMethod.POST)
public ModelAndView lookupEmployee(HttpServletRequest request,HttpServletResponse response, #ModelAttribute("command") Employee emp,BindingResult result) throws Exception{
empValidator.validate(emp, result);
String lookupEmpId = null;
if (result.hasErrors()) {
return new ModelAndView(new RedirectView("lookup"));
//return new ModelAndView("lookup");
}
else{
-----
if i use this return new ModelAndView(new RedirectView("lookup")); its redirecting to lookup.jsp ,rendering the drop down valus but the error messages are not getting displayed.
if i use this return new ModelAndView("lookup"); its redirecting to lookup.jsp ,errors are displayed but the dynamic dropdown values are not rendered.
Please help me in finding which part of my code is wrong or Is their a way to display error messages and render dynamic dropdown values
Just return the view name and set the error message in the Model itself. Simply check the error message in the JSP if found then show it.
sample code:
#RequestMapping(value = "/search", params = "search", method = RequestMethod.POST)
public String lookupEmployee(HttpServletRequest request,HttpServletResponse response,
#ModelAttribute("command") Employee emp,BindingResult result) throws Exception{
empValidator.validate(emp, result);
String lookupEmpId = null;
if (result.hasErrors()) {
emp.setErrorMessage("Your error message.");
return "lookup";
}else{
...
return "successPage";
}
}

Getting error when submitting form using SpringMVC and REST

Created an online form in JSP using SpringMVC tag libraries. The controller for my form is a RESTful web service.
The RESTful web service has two calls:
(1) http://localhost:8080/myapp/applications/new
This brings up the online form in the browser (this works).
(2) http://localhost:8080/myapp/applications/create
This saves the form data to a database (handles submit). This is where it breaks.
Followed the conventions from the sample demo petclinic app which comes with the Spring Framework.
Online form:
<%# page contentType="text/html;charset=UTF-8" language="java"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<body>
<form:form modelAttribute="application" method="POST" action="create">
<table>
<tr>
<td>Name:</td>
<td><form:input path="name" size="30" maxlength="80"/></td>
</tr>
<tr>
<td>Description:</td>
<td><form:input path="description" size="30" maxlength="80"/></td>
</tr>
<tr>
<td>Image URL:</td>
<td><form:input path="imgUrl" size="30" maxlength="80"/></td>
</tr>
</table>
<input type="submit" value="Save" />
</form:form>
</body>
</html>
The RESTful web service which serves as form controller:
#Controller
#Path(ApplicationsResource.APPLICATION_URL)
public class ApplicationsResource
{
private final Logger log =
LoggerFactory.getLogger(ApplicationsResource.class);
public static final String APPLICATION_URL = "/applications";
#Autowired
private ApplicationManager applicationManager;
#Autowired
private ProfileManager profileManager;
#POST
#Path("create")
#Produces(MediaType.TEXT_HTML)
public Model getNewApplication(#Context HttpServletRequest request,
#RequestAttribute Model model)
{
Application app = new Application();
model.addAttribute("application", app);
try
{
if ("POST".equalsIgnoreCase(request.getMethod()))
{
if (app != null)
{
applicationManager.save(app);
log.info("Added application: " + app.getName());
}
else
{
log.info("Application not added");
}
}
}
catch (Exception e)
{
log.info("Exception: ", e);
throw new
WebApplicationException(Response.status(
RestError.SERVER_ERROR_HTTP_RESP).
type("application/json;charset=utf-8").
entity(new ErrorOutput(RestError.SERVER_ERROR_CODE, RestError.SERVER_ERROR_MSG, e.toString())).build());
}
return model;
}
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder)
{
dataBinder.setDisallowedFields(new String[] {"id"});
}
#GET
#Path("new")
#Produces( { MediaType.TEXT_HTML })
public ModelAndView getNewApplicationForm()
{
log.info("ApplicationsResource - Inside getNewApplicationForm");
ModelAndView mv = new ModelAndView("/applications/applications_new");
mv.addObject("application", new Application());
return mv;
}
}
Exception thrown when I click on submit:
Failed executing POST /applications/create
org.jboss.resteasy.spi.BadRequestException:
Could not find message body reader for type:
interface org.springframework.ui.Model of content type:
application/x-www-form-urlencoded at
org.jboss.resteasy.core.MessageBodyParameterInjector$1
createReaderNotFound(MessageBodyParameterInjector.java:73)
Does anyone know why I am getting this exception?
Would really appreciate it if someone could help me with this issue...
Happy programming and thank you for taking the time to read this.
It was a RESTEasy problem... The fix was putting the #Form Application App inside the parameter list and prepending the domain model object's setters with #FormParam("name").
See: Integrating RESTEasy with SpringMVC
You haven't told your controller what mime types it accepts and how to map them, it needs a Reader associated with that mime type to map it and send it into your method.

Resources