I want to get the querystrting passing value from the given url, like: http://localhost:8080/app?contentid=10 I want to get the value of contentid is: 10 from the above url in my spring controller, how can I get this ?
Please note that if I pass any value there(like 10, 50,100, 200, ...etc - it can be any number), so whatever I am passing to contentid, that value should get into my controller. I want to get this contentid value from that url only, not from my html page or I don't want to pass from my html page. Currently I am getting null from the below code in controller, I am not getting the passing value(like 10 from the url). How can I achieve this ? Thanks in advance for your help !
app.html:
<form action="#" th:action="#{/app}" th:object="${TestData}" method="post">
<div class="form-group">
<label for="firstname">First Name: </label> <input type="text"
class="form-control" id="firstname" name="firstname" ></textarea>
</div>
<div class="form-group">
<label for="secondname">Second Name:</label> <input type="text"
class="form-control" id="secondname" name="secondname" />
</div>
<button type="submit" value="Submit">Submit</button>
</form>
TestData.java:
public class TestData implements Serializable{
private String firstname;
private String secondname;
private int contentid;
//setters and getters
public TestData() {}
public TestData(String firstname, String secondname, int contentid, ){
this.firstname = firstname;
this.secondname = secondname;
this.contentid = contentid;
}
#Override
public String toString() {
return String.format(
"TestData[firstname=%s, secondname=%s, contentid=%d]",
firstname, secondname, contentid);
}
}
Controller:
public class TestDataController {
#Autowired
TestService testDataService;
#RequestMapping(value="/app", method=RequestMethod.POST)
public String testDataSubmit(#RequestParam(required=false) Integer contentid, #ModelAttribute TestData testData, Model model, HttpServletRequest request) {
String id = request.getQueryString();
System.out.println("My Id: "+id);//null
System.out.println("URL Parameter: "+testData.getContentid());//0
System.out.println("URL Parameter passed objectid: "+contentid); //null
testDataService.saveTestDataDetails(testData);
return "app";
}
}
Service:
#Service
public class TestService {
#PersistenceContext
private EntityManager entityManager;
public void saveTestDataDetails(TestData testData) {
StoredProcedureQuery sp = entityManager.createStoredProcedureQuery("APP.TESTDATA");
sp.registerStoredProcedureParameter("firstname", String.class, ParameterMode.IN);
sp.registerStoredProcedureParameter("secondname", Integer.class, ParameterMode.IN);
sp.registerStoredProcedureParameter("contentid", Integer.class, ParameterMode.IN);
sp.setParameter("firstname", testData.getFirstname());
sp.setParameter("secondname", testData.getSecondname());
sp.setParameter("contentid", testData.getContentid());
sp.execute();
}
}
After discussion per chat I will provide you a working solution where you can specifiy any stuff by your own needs.
app.html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
<title></title>
</head>
<body>
<th:block th:if="${contentid != null}">
<div th:text="${'contentId: ' + contentid}"></div>
</th:block>
<form action="#" th:action="#{/app(contentid=${contentid})}" th:object="${TestData}"
method="post">
<div class="form-group">
<label for="firstname">First Name: </label>
<input type="text" class="form-control" id="firstname"
name="firstname" />
</div>
<div class="form-group">
<label for="secondname">Second Name:</label>
<input type="text" class="form-control" id="secondname"
name="secondname" />
</div>
<button type="submit" value="Submit">Submit</button>
</form>
</body>
</html>
Controller:
#Controller
public class MyController {
#GetMapping("/app")
public String getApp(Model model) {
return "app";
}
#PostMapping("/app")
public String postApp(#RequestParam(required=false) Integer contentid, #ModelAttribute TestData testData, Model model, HttpServletRequest request) {
System.out.println(contentid);
if(contentid == null) {
contentid = ThreadLocalRandom.current().nextInt(0, 100 + 1);
}
model.addAttribute("contentid",contentid);
return "app";
}
}
First change your html code th:action="#{/app?contentid=10} and then add setter and getter method for the instance variable in the class TestData.
Related
Here is my form
<form th:action="#{/pages/org/create}" th:object="${org}" method="post" id="createOrgForm">
<div class="row">
<div class="form-group col-sm-12">
<label for="name">Name</label> <input class="form-control" id="name" type="text" th:field="*{name}" />
</div>
</div>
<div class="row">
<div class="form-group col-sm-12">
<label for="uuid">Uuid</label> <input class="form-control" id="uuid" type="text" th:field="*{uuid}" />
</div>
</div>
<div class="row">
<div class="form-group col-sm-12">
<label for="expiryDate">Expiry Date</label>
<input class="form-control" id="expiryDate" type="date" name="expiryDate" th:value="${#temporals.format(org.expiryDate, 'dd/MMM/yyyy HH:mm', 'en')}"/>/>
</div>
</div>
</form>
The object has name and uuid which are strings
It also has an expiryDate which is a zonedDateTime
I want to return expiryDate as a zoneddatetime but I can't find any examples of this
Any one Know how to do this?
If anymore details are needed let me know
I have this error
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='org'. Error count: 1
because org.expiryDate is a string and its expecting a zoneddatetime
public class OrganizationDto extends TemporallyScopedEntityFlatDto {
private static final long serialVersionUID = -2191341305487098272L;
public static OrganizationDto fromEntity(final Organization o) {
if (o == null) {
return null;
}
final OrganizationDto dto = new OrganizationDto();
DtoUtil.copyVersioned(o, dto);
DtoUtil.copyTemporallyScoped(o, dto);
dto.setName(o.getName());
dto.setUuid(o.getUuid());
return dto;
}
#ApiModelProperty(value = "The display name of this organization.")
private String name;
#ApiModelProperty(value = "The unique identifier of this organization.")
private String uuid;
private ZonedDateTime expiryDate;
public String getName() {
return name;
}
public String getUuid() {
return uuid;
}
public void setName(final String name) {
this.name = name;
}
public void setUuid(final String uuid) {
this.uuid = uuid;
}
}
When I go to /add endpoint my Controller creates a Contact object and generates an ID for it. This ID is then properly passed to a Thymeleaf view and showed on the webpage. When the form from the view is submitted (with POST) to another endpoint in my Controller all of the properties are passed except the ID field. I use Spring Model and #ModelAttribute annotation to pass the object to and from the view. Getters and setters for the entity are generated with Lombok.
Controller class:
#Controller
public class PhonebookController {
private final PhonebookService phonebookService;
#Autowired
public PhonebookController(PhonebookService phonebookService) {
this.phonebookService = phonebookService;
}
#GetMapping("/add")
public String addContact(Model model) {
model.addAttribute("contact", new Contact(EntityUtils.generateId()));
return "contact";
}
#PostMapping("/save")
public String validateAndSaveContact(#ModelAttribute("contact") #Valid Contact contact, BindingResult bindingResult) { // contact.getId() returns null
if (bindingResult.hasErrors()) {
return "contact";
}
phonebookService.getContactRepository().save(contact);
return "redirect:/contacts";
}
}
Entity class:
#Data
#NoArgsConstructor
#AllArgsConstructor
#Document(indexName = "contact")
public class Contact implements Comparable<Contact> {
#Id
private String id;
#NotEmpty(message = "Name can not be empty.")
private String name;
#NotEmpty(message = "Number can not be empty.")
#Pattern(regexp = "[0-9]+", message = "Number can contains only numbers.")
private String number;
public Contact(String id) {
this.id = id;
}
#Override
public int compareTo(Contact o) {
return this.getName().compareTo(o.name);
}
}
Thymeleaf view:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css"/>
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/webjars/font-awesome/css/font-awesome.min.css"/>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-12">
<h1>Add new contact</h1>
<form th:action="#{/save}" method="post" th:object="${contact}">
<div class="form-group">
<label for="idText">Identifier (automaticaly generated):</label>
<strong id="idText" th:text="${contact.getId()}"></strong>
</div>
<div class="form-group">
<label for="nameInput">Contact name:</label>
<input type="text" th:field="*{name}" th:value="*{name}" class="form-control" id="nameInput"/>
<div class="alert alert-warning" role="alert" th:if="${#fields.hasErrors()}" th:errors="*{name}"></div>
</div>
<div class="form-group">
<label for="numberInput">Phone number:</label>
<input type="text" th:field="*{number}" th:value="*{number}" class="form-control" id="numberInput"/>
<div class="alert alert-warning" role="alert" th:if="${#fields.hasErrors()}" th:errors="*{number}"></div>
</div>
<div class="form-group text-right">
<button type="submit" class="btn btn-success">Confirm</button>
<a class="btn btn-danger" th:href="#{/contacts}" role="button">Cancel</a>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
You need to have a hidden input field which contains the id value.
<div class="form-group">
<label for="idText">Identifier (automaticaly generated):</label>
<strong id="idText" th:text="${contact.getId()}"></strong>
<input id="id" th:field="*{id}" type="hidden"/>
</div>
I would like to help you, but I don´t know if you are using the same object to save the data in your table (your entity) and for return your view model in your controller. Normally you should use a different objects and mapping this in your service. It is posible that you have problems if you are using the same object.
Can anyone give sample Java code for validating the HTML form (ex: form attributes not null, minimum and maximum size) using via Spring MVC and with thymeleaf-spring4 libraries?
The simplest, you annotate your dao object (in this case user), with the constraints you need:
#Entity
public class User
{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#NotNull
private String login;
#Size(min=2, max=30)
private String firstName;
#Min(18)
private int age;
}
These annotation are from javax.validation.constraints.
After this you need to modify your controller, you need to clarify your controller that the object must be #Valid:
#RequestMapping(method=RequestMethod.POST)
public String registerUser(#Valid final User user, final BindingResult bindingResult)
{
if (bindingResult.hasErrors()) {
return "form";
}
// Your code
return "redirect:/userList";
}
The errors are stored in the BindingResult.
Finally show the errors:
<span th:if="${#fields.hasErrors('login')}" th:errors="*{login}"></span>
Edit:
Return ModelAndView
#RequestMapping(method=RequestMethod.POST)
public ModelAndView registerUser(#Valid final User user, final BindingResult bindingResult)
{
if (bindingResult.hasErrors()) {
ModelAndView mav = new ModelAndView("form");
mav.addObject(bindingResult);
return mav;
}
}
These are latest maven dependencies for java validation API
1.dependency
groupId javax.validation
artifactId validation-api
version 1.1.0.Final
2.dependency
groupId org.hibernate
artifactId hibernate-validator
version 5.0.1.Final
Take a look at this:
First, comes the Object...
public class PruebaFormCommand {
#NotEmpty
#Size(min = 3, max = 50)
private String textoPrueba;
public String getTextoPrueba() {
return textoPrueba;
}
public void setTextoPrueba(String textoPrueba) {
this.textoPrueba = textoPrueba;
}
}
Then, the Controller:
#Controller
public class PruebaFormController {
#RequestMapping("/pruebaform")
public String pruebaForm(Model model){
model.addAttribute("pruebaFormCommand", new PruebaFormCommand());
return "pruebaform";
}
#RequestMapping(value = "/dopruebaform", method = RequestMethod.POST)
public String doPruebaForm(#Valid PruebaFormCommand pruebaFormCommand, BindingResult bindingResult){
if (bindingResult.hasErrors()) {
return "pruebaform";
}
return "pruebaformcomplete";
}
}
Then, the HTML:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<link href="../static/css/bootstrap-3.3.4-dist/css/bootstrap.min.css" rel="stylesheet" media="screen"
th:href="#{/css/bootstrap-3.3.4-dist/css/bootstrap.min.css}"/>
<script src="../static/js/jquery-2.1.4.min.js"
th:src="#{/js/jquery-2.1.4.min.js}"></script>
<link th:href="#{/css/custom.css}" rel="stylesheet" media="screen"/>
<title>Checkout</title>
</head>
<body>
<div class="container">
<h2>PRUEBA Form</h2>
<form class="form-horizontal" th:object="${pruebaFormCommand}" th:action="#{/dopruebaform}" method="post">
<div th:if="${#fields.hasErrors('*')}" class="alert alert-danger">
<p th:text="#{pruebaFormCommand.hasErrors}">Error Message</p>
</div>
<div class="form-group" th:class="${#fields.hasErrors('textoPrueba')} ? 'form-group has-error' : 'form-group'">
<label class="col-sm-2 control-label">Meteme algo payo:</label>
<div class="col-sm-10">
<input type="text" class="form-control" th:field="*{textoPrueba}" th:errorclass="has-error"/>
<span class="help-block" th:if="${#fields.hasErrors('textoPrueba')}">
<ul>
<li th:each="err : ${#fields.errors('textoPrueba')}" th:text="${err}" />
</ul>
</span>
</div>
</div>
<div class="row">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
</div>
</body>
</html>
Finally, include your message.properties:
pruebaFormCommand.hasErrors=Porfa corrige los errores:
NotEmpty.pruebaFormCommand.textoPrueba={0} caracteres mínimo....
Size.pruebaFormCommand.textoPrueba={0} debe tener entre {2} y {1} caracteres
I'm trying to update data from Spring MVC's view. I could update data using tester object but failed when trying update from Spring MVC's view. POST request from view has no problem key/value were posting to server. It updated my table data but with null value (unless for id field).
Please help and thank you.
My Table (tx_surveyrequest)
CREATE TABLE tx_surveyrequest
(
id uuid NOT NULL,
id_person uuid,
id_surveyrequeststatus uuid,
id_validationstatus uuid,
id_employee_assistantgis uuid,
formcode character varying(64),
b_north character varying(32),
b_east character varying(32),
b_south character varying(32),
b_west character varying(32),
hectarage numeric(10,2),
is_priority boolean DEFAULT false,
requestdate date,
surveyplandate date,
surveyplantime time without time zone,
requestedby character varying(32),
requestedprice numeric(14,2),
CONSTRAINT pk_tx_surveyrequest PRIMARY KEY (id)
)
My domain object (SurveyRequest)
#Entity
#Table(name = "tx_surveyrequest")
public class SurveyRequest implements Serializable {
private UUID id;
private Person person;
private String formCode;
private String borderNorth;
private String borderEast;
private String borderSouth;
private String borderWest;
private Double hectarage;
private Boolean priority;
private DateTime requestDate;
private DateTime surveyPlanDate;
private LocalTime surveyPlanTime;
private String requestedBy;
private Double requestedPrice;
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id")
#Type(type="pg-uuid")
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
#Column(name = "hectarage")
public Double getHectarage(){
return hectarage;
}
public void setHectarage(Double hectarage){
this.hectarage = hectarage;
}
#Column(name = "formcode")
public String getFormCode() {
return formCode;
}
public void setFormCode(String formCode) {
this.formCode = formCode;
}
#Column(name="is_priority")
public Boolean getPriority() {
return priority;
}
public void setPriority(Boolean priority) {
this.priority = priority;
}
#Column(name="b_north")
public String getBorderNorth() {
return borderNorth;
}
public void setBorderNorth(String border) {
this.borderNorth = border;
}
#Column(name="b_east")
public String getBorderEast() {
return borderEast;
}
public void setBorderEast(String border) {
this.borderEast = border;
}
#Column(name="b_south")
public String getBorderSouth() {
return borderSouth;
}
public void setBorderSouth(String border) {
this.borderSouth = border;
}
#Column(name="b_west")
public String getBorderWest() {
return borderWest;
}
public void setBorderWest(String border) {
this.borderWest = border;
}
// TODO replace pattern with i18n
#Type(type = "org.joda.time.contrib.hibernate.PersistentDateTime")
#DateTimeFormat(pattern = "dd/MM/yyyy")
#Column(name = "requestdate")
public DateTime getRequestDate() {
return requestDate;
}
public void setRequestDate(DateTime requestDate) {
this.requestDate = requestDate;
}
// TODO replace pattern with i18n
#Type(type = "org.joda.time.contrib.hibernate.PersistentDateTime")
#DateTimeFormat(pattern = "dd/MM/yyyy")
#Column(name = "surveyplandate")
public DateTime getSurveyPlanDate() {
return surveyPlanDate;
}
public void setSurveyPlanDate(DateTime surveyPlanDate) {
this.surveyPlanDate = surveyPlanDate;
}
// TODO replace pattern with i18n
#Type(type = "org.joda.time.contrib.hibernate.PersistentLocalTimeAsTime")
#DateTimeFormat(pattern = "HH:mm")
#Column(name = "surveyplantime")
public LocalTime getSurveyPlanTime() {
return surveyPlanTime;
}
public void setSurveyPlanTime(LocalTime surveyPlanTime) {
this.surveyPlanTime = surveyPlanTime;
}
Update success using SurveyRequestUpdate
public class SurveyRequestUpdate {
public static void main(String[] args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:spring-data-app-context.xml");
ctx.load("classpath:datasource.xml");
ctx.refresh();
SurveyRequestService surveyRequestService = ctx.getBean(
"springJpaSurveyRequestService",SurveyRequestService.class);
UUID uid = UUID.fromString("0cd02976-1864-447b-b540-39d6e7ee3703");
SurveyRequest request = surveyRequestService.findById(uid);
System.out.println("Find by ID");
System.out.println(request);
request.setSurveyPlanDate (new DateTime(2014,7,1,0,0));
request.setSurveyPlanTime (new LocalTime(22,0));
surveyRequestService.save(request);
System.out.println(request);
}
Update Form View
<jsp:directive.page contentType="text/html;charset=UTF-8" />
<jsp:output omit-xml-declaration="yes" />
<spring:message code="l_surveyrequest_list" var="labelSurveyRequestList" />
<spring:message code="l_surveyrequest_title" var="labelSurveyRequestTitle" />
<spring:message code="l_surveyrequest_code" var="labelSurveyRequestCode" />
<spring:message code="l_surveyrequest_requestdate" var="labelSurveyRequestRequestDate" />
<spring:message code="l_surveyrequest_surveydate" var="labelSurveyRequestSurveyDate" />
<spring:message code="l_surveyrequest_surveytime" var="labelSurveyRequestSurveyTime" />
<spring:message code="l_surveyrequest_priority" var="labelSurveyRequestPriority" />
<spring:message code="l_surveyrequest_complete" var="labelSurveyRequestComplete" />
<spring:message code="l_surveyrequest_hectarage" var="labelSurveyRequestHectarage" />
<spring:message code="l_surveyrequest_north" var="labelSurveyRequestNorth" />
<spring:message code="l_surveyrequest_east" var="labelSurveyRequestEast" />
<spring:message code="l_surveyrequest_south" var="labelSurveyRequestSouth" />
<spring:message code="l_surveyrequest_west" var="labelSurveyRequestWest" />
<spring:message code="form_new" var="formNew" />
<spring:message code="form_edit" var="formEdit" />
<spring:message code="btn_save" var="buttonSave" />
<spring:message code="btn_cancel" var="buttonCancel" />
<spring:message code="long_date_format_pattern" var="formatDate" />
<spring:message code="time_format_pattern" var="formatDateTime" />
<spring:message code="short_time_format_pattern" var="formatShortTime" />
<spring:url value="/surveyrequest" var="showSurveyRequestUrl" />
<spring:eval expression="surveyRequest.id == null ? formNew:formEdit" var="formTitle"/>
<div class="row">
<div class="col-md-12">
<h1>${formTitle} ${labelSurveyRequestTitle}</h1>
</div>
</div>
<!-- /top action bar -->
<div class="row">
<div class="col-md-12">
<c:if test="${not empty surveyRequest}">
<form:form class="form-horizontal"
modelAttribute="surveyRequest" commandName="surveyRequest" method="post" enctype="multipart/form-data">
<div class="row">
<div class="col-md-12">
<button type="submit" class="btn btn-primary">${buttonSave}</button>
<button type="reset" class="btn btn-primary">${buttonCancel}</button>
</div>
</div>
<c:if test="${not empty message}">
<div id="message" class="${message.type}">${message.message}</div>
</c:if>
<div class="form-group">
<label class="col-md-3 control-label">${labelSurveyRequestCode}</label>
<div class="col-md-3">
<form:input type="text" class="form-control" path="formCode" />
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">${labelSurveyRequestRequestDate}</label>
<div class='col-md-3 input-group date datepicker'>
<form:input type='text' class="form-control" path="requestDate" />
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">${labelSurveyRequestSurveyDate}</label>
<div class='col-md-3 input-group date datepicker'>
<form:input type='text' class="form-control" path="surveyPlanDate" />
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<div class="form-group">
<form:label class="col-md-3 control-label"
path="surveyPlanTime">${labelSurveyRequestSurveyTime}</form:label>
<div class='col-md-3 input-group date timepicker'>
<form:input type='text' class="form-control" path="surveyPlanTime" />
<span class="input-group-addon"><span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">${labelSurveyRequestHectarage}</label>
<div class="col-md-3">
<form:input type="text" class="form-control" path="hectarage" />
</div>
</div>
<div class="form-group">
<p class="col-md-3"></p>
<div class="col-md-9">
<c:choose>
<c:when test="${surveyRequest.priority == true}">
${labelSurveyRequestPriority}
</c:when>
</c:choose>
</div>
</div>
<div class="form-group">
<p class="col-md-3"></p>
<div class="col-md-9">
<table class="table">
<thead>
<tr>
<th>${labelSurveyRequestNorth}</th>
<th>${labelSurveyRequestEast}</th>
<th>${labelSurveyRequestSouth}</th>
<th>${labelSurveyRequestWest}</th>
</tr>
</thead>
<tbody>
<tr>
<td>${surveyRequest.borderNorth}</td>
<td>${surveyRequest.borderEast}</td>
<td>${surveyRequest.borderSouth}</td>
<td>${surveyRequest.borderWest}</td>
</tr>
</tbody>
</table>
</div>
</div>
</form:form>
</c:if>
</div>
</div>
<script type="text/javascript">
$(function () {
$('.datepicker').datetimepicker({
pickTime: false,
language: 'id',
});
$('.timepicker').datetimepicker({
pickDate: false,
minuteStepping:15,
useSeconds: false,
language: 'id'
});
});
</script>
</div>
My Controller
#RequestMapping("/surveyrequest")
#Controller
public class SurveyRequestController {
private static final int PAGE_SIZE = 10;
private static final Logger logger = LoggerFactory
.getLogger(SurveyRequestController.class);
#Autowired
MessageSource messageSource;
#Autowired
private SurveyRequestService surveyRequestService;
// Others code omitted
#RequestMapping(value="/{id}", method = RequestMethod.GET)
public String show(#PathVariable("id") UUID id, Model model) {
SurveyRequest request = surveyRequestService.findById(id);
model.addAttribute("surveyRequest", request);
return "surveyrequest/show";
}
/*
* Edit a survey request
*/
#RequestMapping(value="/{id}", params="form", method = RequestMethod.GET)
public String updateForm(#PathVariable("id") UUID id, Model model) {
SurveyRequest request = surveyRequestService.findById(id);
model.addAttribute("surveyRequest", request);
return "surveyrequest/edit";
}
/*
* Update a survey request
*/
#RequestMapping(value = "/{id}", params = "form", method = RequestMethod.POST)
public String update(SurveyRequest surveyRequest, BindingResult bindingResult, Model uiModel,
HttpServletRequest httpServletRequest, RedirectAttributes redirectAttributes, Locale locale) {
if (bindingResult.hasErrors()) {
uiModel.addAttribute("message", new Message("error", messageSource.getMessage("surveyrequest_save_fail", new Object[]{}, locale)));
uiModel.addAttribute("surveyRequest", surveyRequest);
return "surveyrequest/update";
}
uiModel.asMap().clear();
redirectAttributes.addFlashAttribute("message", new Message("success", messageSource.getMessage("surveyrequest_save_success", new Object[]{}, locale)));
logger.info("Before paste: " + surveyRequest);
surveyRequestService.save(surveyRequest);
return "redirect:/surveyrequest/" + UrlUtil.encodeUrlPathSegment(surveyRequest.getId().toString(), httpServletRequest);
}
Updated:
I could resolve the problem with removing enctype="multipart/form-data" at edit.jspx. But it raised another issue, how if I'm going to upload file?
Add #ModelAttribute annotation to your model object parameter in the controller method that you're calling, so that Spring knows that's the object that you want to bind the form data to.
/*
* Update a survey request
*/
#RequestMapping(value = "/{id}", params = "form", method = RequestMethod.POST)
public String update(#ModelAttribute("surveyRequest") SurveyRequest surveyRequest,
BindingResult bindingResult, Model uiModel,
HttpServletRequest httpServletRequest,
RedirectAttributes redirectAttributes, Locale locale) {
[...]
}
Think this is an easy one but don't know how to handle it.
I have a form like this.
<c:url value="edit" var="editprofileUrl" />
<form:form class="form" id="signup" action="${editprofileUrl}" method="post" modelAttribute="editProfileForm">
<div class="formInfo">
<s:bind path="*">
<c:choose>
<c:when test="${status.error}">
<div class="text-danger">Unable to change profile. Please fix the errors below and resubmit.</div>
</c:when>
</c:choose>
</s:bind>
</div>
<div class="form-group">
<label for="firstName">First name</label>
<form:errors path="firstName" cssClass="text-danger" />
<form:input class="form-control" path="firstName" />
</div>
<div class="form-group">
<label for="lastName">Last name</label>
<form:errors path="lastName" cssClass="text-danger" />
<form:input class="form-control" id="last-name" path="lastName" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Save profile</button>
</div>
</form:form>
And the java form like this:
public class EditProfileForm {
#NotEmpty
private String firstName;
#NotEmpty
private String lastName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
And a controller like this:
#Controller
#Transactional
public class EditProfileController {
#PersistenceContext
private EntityManager entityManager;
#RequestMapping(value = "/users/{username}/edit", method = RequestMethod.POST)
public String editProfile(#PathVariable String username, Principal currentUser, #Valid EditProfileForm form, BindingResult formBinding) {
if (formBinding.hasErrors()) {
return null;
}
Account user = entityManager.find(Account.class, currentUser.getName());
user.setFirstName(form.getFirstName());
user.setLastName(form.getLastName());
entityManager.persist(user);
return "home";
}
#RequestMapping(value = "/users/{username}/edit", method = RequestMethod.GET)
public ModelAndView editProfileForm(#PathVariable String username, Principal currentUser, WebRequest request, Model model) {
Account account = entityManager.find(Account.class, username);
if (account != null) {
model.addAttribute("account", account);
}
EditProfileForm form = new EditProfileForm();
form.setFirstName(account.getFirstName());
form.setLastName(account.getLastName());
return new ModelAndView("editprofile", "editProfileForm", form);
}
}
Everything works good besides when I don't fill in anything in one of the fields and it should give an error.
Something breaks in this code snippet:
if (formBinding.hasErrors()) {
return null;
}
Instead of returning the same page again with the errors it looks for a view that does not exist:
HTTP Status 404 - /project/WEB-INF/views/users/nilsi/edit.jsp
How do I return the same view again with the errors? Usually it works when i have a shorter #RequestMapping like /signup.
Thanks for any help on this!
In the event of binding errors, return the name of the form view again so that the user can correct the errors.
if (formBinding.hasErrors()) {
return "editprofile";
}
If you return null, Spring tries to guess a view name by looking at the url. Since your url ends with ".../edit", it tries to load edit.jsp.