BindigResult.hasErrors It doesn't work Spring frameworkd validation - java

I am working with the Spring Framework, I have a model mapped to a controller with which I am trying to do some validations with the annotations offered by Spring, I use the BindingResult hasErrors() interface and also the #Validate annotation, however although I leave fields empty in my models (and specifies the #NotEmpty annotation) I can't get the hasErrors to change its state, it stays false. Am I forgetting something?
#Entity
#Table(name = "Clientes")
public class Cliente {
#Id
#Column(name= "ID_cliente")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer idCliente;
#Column(name= "Productos_cliente", nullable = true)
private String productosCliente;
#Column(name= "Primer_nombre")
#NotEmpty(message = "El nombre no puede estar vacio")
private String primerNombre;
#Column(name= "Segundo_nombre")
#NotEmpty
private String segundoNombre;
#Column(name= "Primer_apellido")
#NotEmpty
private String primerApellido;
#Column(name= "Segundo_apellido")
#NotEmpty
private String segundoApellido;
#Column(name= "Ciudad_cliente")
private String ciudadCliente;
#Column(name= "Direccion_cliente")
private String direccionCliente;
#Column(name= "Correo_electronico")
#NotEmpty
private String email;
#Column(name= "Contraseña")
#NotEmpty
private String contraseña;
public Cliente(String productosCliente, String primerNombre, String segundoNombre, String primerApellido, String segundoApellido, String email, String contraseña ){
this.productosCliente = productosCliente;
this.primerNombre = primerNombre;
this.segundoNombre = segundoNombre;
this.primerApellido = primerApellido;
this.segundoApellido = segundoApellido;
this.email = email;
this.contraseña = contraseña;
}
/**
* #return Integer return the idCliente
*/
public Integer getIdCliente() {
return idCliente;
}
/**
* #param idCliente the idCliente to set
*/
public void setIdCliente(Integer idCliente) {
this.idCliente = idCliente;
}
/**
* #return String return the productosCliente
*/
public String getProductosCliente() {
return productosCliente;
}
/**
* #param productosCliente the productosCliente to set
*/
public void setProductosCliente(String productosCliente) {
this.productosCliente = productosCliente;
}
/**
* #return String return the primerNombre
*/
public String getPrimerNombre() {
return primerNombre;
}
/**
* #param primerNombre the primerNombre to set
*/
public void setPrimerNombre(String primerNombre) {
this.primerNombre = primerNombre;
}
/**
* #return String return the segundoNombre
*/
public String getSegundoNombre() {
return segundoNombre;
}
/**
* #param segundoNombre the segundoNombre to set
*/
public void setSegundoNombre(String segundoNombre) {
this.segundoNombre = segundoNombre;
}
/**
* #return String return the primerApellido
*/
public String getPrimerApellido() {
return primerApellido;
}
/**
* #param primerApellido the primerApellido to set
*/
public void setPrimerApellido(String primerApellido) {
this.primerApellido = primerApellido;
}
/**
* #return String return the segundoApellido
*/
public String getSegundoApellido() {
return segundoApellido;
}
/**
* #param segundoApellido the segundoApellido to set
*/
public void setSegundoApellido(String segundoApellido) {
this.segundoApellido = segundoApellido;
}
/**
* #return String return the ciudadCliente
*/
public String getCiudadCliente() {
return ciudadCliente;
}
/**
* #param ciudadCliente the ciudadCliente to set
*/
public void setCiudadCliente(String ciudadCliente) {
this.ciudadCliente = ciudadCliente;
}
/**
* #return String return the direccionCliente
*/
public String getDireccionCliente() {
return direccionCliente;
}
/**
* #param direccionCliente the direccionCliente to set
*/
public void setDireccionCliente(String direccionCliente) {
this.direccionCliente = direccionCliente;
}
/**
* #return String return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return String return the contraseña
*/
public String getContraseña() {
return contraseña;
}
/**
* #param contraseña the contraseña to set
*/
public void setContraseña(String contraseña) {
this.contraseña = contraseña;
}
}
Controller:
#Controller
#Validated
public class FormController {
#Autowired
ClienteServices service;
#GetMapping("/register")
public String formLoggin(Model model, Cliente cliente, BindingResult result)
{
model.addAttribute("Title", "Registro");
model.addAttribute("cliente", cliente);
return "register";
}
#PostMapping("/register")
public String sendForm(#Valid Cliente cliente, BindingResult send, Model model)
{
model.addAttribute("data", "Registro");
if(send.hasErrors()){ <-- Does not evaluate this condition
return "register";
}
model.addAttribute("cliente", cliente);
return "dataUser";
}
}
register.html:
<body>
<div style="display: flex; flex-direction: column; min-width: 500; min-height: 800; align-items: center; justify-content: center;">
<h3 th:text="${Title}"></h3>
<form th:action="#{/register}" th:object="${cliente}" method="post">
<div>
<label for="Primer nombre">Primer nombre</label>
<div>
<input id="username" name="username" type="text" th:field="*{primerNombre}">
<div th:if="${#fields.hasErrors('primerNombre')}" th:errors="*{primerNombre}"></div>
</div>
</div>
<div>
<label for="Primer apellido">Segundo nombre</label>
<div>
<input id="Secondname" name="Secondname" type="text" th:field="*{segundoNombre}">
<div th:if="${#fields.hasErrors('segundoNombre')}" th:errors="*{segundoNombre}"></div>
</div>
</div>
<div>
<label for="Primer apellido">Primer apellido</label>
<div>
<input id="Surname" name="Surname" type="text" th:field="*{primerApellido}">
</div>
</div>
<div>
<label for="Segundo apellido">Segundo apellido</label>
<div>
<input id="secondSurname" name="secondSurname" type="text" th:field="*{segundoApellido}">
</div>
</div>
<div>
<label for="Email">Correo electrónico</label>
<div>
<input id="Email" name="email" type="email" th:field="*{email}">
</div>
</div>
<div>
<label for="contraseña">Contraseña</label>
<div>
<input id="contraseña" name="password" type="password" th:field="*{contraseña}">
</div>
</div>
<div>
<label for="contraseña">Ciudad</label>
<div>
<input id="City" name="City" type="text" th:field="*{ciudadCliente}">
</div>
</div>
<div>
<label for="contraseña">Dirección</label>
<div>
<input id="Dir" name="Dir" type="text" th:field="*{direccionCliente}">
</div>
</div>
<div class="card-footer">
<button type="submit">Enviar</button>
</div>
</form>
</div>

Every thing seems to be fine. Try changing your controller this way . Create a new object when sending it to the form like below instead of sending it through parameter as it might not be able to bind object properly:
#GetMapping("/register")
public String formLoggin(Model model, BindingResult result)
{
model.addAttribute("Title", "Registro");
model.addAttribute("cliente",new cliente()); //change this line
return "register";
}
#PostMapping("/register")
public String sendForm(#Valid #ModelAttribute("cliente") Cliente cliente, BindingResult send, Model model)
{
model.addAttribute("data", "Registro");
if(send.hasErrors()){ <-- Does not evaluate this condition
return "register";
}
model.addAttribute("cliente", cliente);
return "dataUser";
}

This is generally a result from only including the javax.validation API and not an implementation. You probably have something like the following in your depenendencies list.
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
This is only the API not an implementation. This is much like including the JPA jakarta.persistence-api and expect JPA to work (but you still need an implementation like Hibernate ORM). For the validation this is the same you need an implementation, mostly used is hibernate-validator. So you could add
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.5.Final</version>
</dependency>
NOTE: You have to use version 6.x as 7+ is for the new Jakarta Validation API which isn't supported yet (as of Spring Framework 6 / Spring Boot 3 it will).
However as you are already using Spring Boot I would strongly encourage you to use.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
This will include both the API and an implementation (the aformentioned hibernate-validator one). It will make sure you have a compatible version for this version of Spring / Spring Boot.

Instead of annotating with '#NotEmpty' you can follow this method:
#Column(name= "Correo_electronico", nullable = false)
private String email;
When you use this method either Jpa or Hibernate will throw an error if the value is empty.

Related

Add an object using SpringBoot and Thymeleaf

I am building an event website using Springboot and I am trying to make the new_event page where you should create a new event. But aftetr completing the form and click the button "Add Event", there is nothing happening. What is the issue?
new_event HTML is:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layouts/default}">
<head>
<title>Create event</title>
</head>
<body>
<div layout:fragment="content">
<h1>Create a new event</h1>
<p> Complete the following fields to add an event . * - required field </p>
<form action="#" th:action="#{/events}" th:object="${events}" method="post">
<div class="form-group" th:classappend="${#fields.hasErrors('name')}? has-error">
<label for="name">Name *:</label>
<input class="form-control" type="text" th:field="*{name}" name="name" id="name" placeholder="Max 250 chars" autofocus="autofocus" required/>
<p class="text-danger" th:if="${#fields.hasErrors('name')}" th:errors="*{name}">errors</p>
<label for="ev_venue">Venue *:</label>
<input class="form-control" type="text" th:field="*{venue}" name="ev_venue" id="ev_venue" autofocus="autofocus" />
<label for="ev_date">Date *:</label>
<input class="form-control" type="date" th:field="*{date}" name="ev_date" id="ev_date" autofocus="autofocus" />
<label for="ev_time">Time :</label>
<input class="form-control" type="time" th:field="*{time}" name="ev_time" id="ev_time" autofocus="autofocus" />
<label for="ev_descr">Description :</label>
<input class="form-control" type="text" th:field="*{description}" name="ev_descr" id="ev_descr" placeholder="Max 500 chars" autofocus="autofocus" />
</div>
</form>
<button class="btn btn-primary" type="submit"><i class="fas fa-plus" aria-hidden="true"></i> Add Event</button>
<a class="btn btn-warning" role="button" href="/events"><i class="fas fa-ban" aria-hidden="true"></i> Cancel</a>
</form>
</div>
</body>
</html>
Event Controller is :
#Controller
#RequestMapping(value = "/events", produces = { MediaType.TEXT_HTML_VALUE })
public class EventsController {
#Autowired
private EventService eventService;
#GetMapping("/new_event")
public String newEvent(Model model) {
if (!model.containsAttribute("events")) {
model.addAttribute("events", new Event());
}
return "events/new_event";
}
#PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String createEvent(#RequestBody #Valid #ModelAttribute Event event, BindingResult errors,
Model model, RedirectAttributes redirectAttrs) {
if (errors.hasErrors()) {
model.addAttribute("events", event);
return "events/new_event";
}
eventService.save(event);
redirectAttrs.addFlashAttribute("ok_message", "New event added.");
return "redirect:/events";
}
}
EventController API is:
#RestController
#RequestMapping(value = "/api/events", produces = { MediaType.APPLICATION_JSON_VALUE, MediaTypes.HAL_JSON_VALUE })
public class EventsControllerApi {
private static final String NOT_FOUND_MSG = "{ \"error\": \"%s\", \"id\": %d }";
#Autowired
private EventService eventService;
#Autowired
private EventModelAssembler eventAssembler;
#GetMapping("/new_event")
public ResponseEntity<?> newEvent() {
return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).build();
}
#PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> createEvent(#RequestBody #Valid Event event, BindingResult result) {
if (result.hasErrors()) {
return ResponseEntity.unprocessableEntity().build();
}
Event newEvent = eventService.save(event);
EntityModel<Event> entity = eventAssembler.toModel(newEvent);
return ResponseEntity.created(entity.getRequiredLink(IanaLinkRelations.SELF).toUri()).build();
}
}
And the Event class:
#Entity
#Table(name = "events")
public class Event {
#Id
private long id;
#JsonFormat(shape = JsonFormat.Shape.STRING)
#DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate date;
#JsonFormat(shape = JsonFormat.Shape.STRING)
#DateTimeFormat(pattern = "HH:mm")
private LocalTime time;
#Persistent
#NotEmpty(message = "The event must have a name.")
#Size(max = 250, message = "The name of the event must have 250 characters or less.")
private String name;
#ManyToOne
#Persistent
private Venue venue;
private String description;
public Event() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public LocalTime getTime() {
return time;
}
public void setTime(LocalTime time) {
this.time = time;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Venue getVenue() {
return venue;
}
public void setVenue(Venue venue) {
this.venue = venue;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

Invalid property 'xxx' of bean class. Does the return type of the getter match the parameter type of the setter?

I am aware that this question has been asked before but after looking through all of the examples, non of the solutions helped me.
I am simply trying to render a video form on my application via spring controller, but I keep
getting the aforementioned error on every field except two. Below is my html
<form th:action="#{/upload-video}" method="POST" enctype="multipart/form-data" th:object="${video}">
<input id="i_file" type="file" name="file" accept="video/*">
<div class="video_container">
<label for="video_name">Video Name</label>
<input class="textInput" id="video_name" type="text" th:field="*{videoName}" placeholder="Example: image.png">
<label for="videoDesc">Video Description</label>
<input id="videoDesc" type="text" placeholder="Enter a description..." th:field="*{video_Description}">
<label for="file_path">File Path</label>
<input id="file_path" class="file_path_input textInput" type="text" placeholder="File Path..."><br>
<video src="">
Enter a video...
</video>
</div>
<button type="submit">Upload</button>
</form>
The error is now being generated on the videoDescription input tag. Below is my GET controller:
#RequestMapping(value = "/upload-video", method = RequestMethod.GET)
private String uploadVideoPage(Model model) {
model.addAttribute("video", new Video());
return "upload-video";
}
Here is my video class:
#Entity()
#Table(name = "user_videos")
public class Video {
#Id
#GeneratedValue
private Long videoId;
private String videoName;
private String videoTagLine;
private String video_Description;
private Date uploadDate;
#Transient
private String uploadDateStr;
public String getVideoName() {
return videoName;
}
public void setVideoName(String videoName) {
this.videoName = videoName;
}
public String getVideoTagLine() {
return videoTagLine;
}
public void setVideoTagLine(String videoTagLine) {
this.videoTagLine = videoTagLine;
}
public String getVideo_Description() {
return video_Description;
}
public void setVideo_Description(String videoDescription) {
this.video_Description = videoDescription;
}
public Date getUploadDate() {
return uploadDate;
}
public void setUploadDate(Date uploadDate) {
this.uploadDate = uploadDate;
}
public String getUploadDateStr() {
return uploadDateStr;
}
public void setUploadDateStr(String uploadDateStr) {
this.uploadDateStr = uploadDateStr;
}
}
I've google and googled and googled and non of the solutions have worked. Any help would be appreciated.

org.springframework.beans.NullValueInNestedPathException: auto-grow nested property path in Spring MVC 3.2.8

I have a project based in Spring Web model-view-controller (MVC) framework. The version of the Spring Web model-view-controller (MVC) framework is 3.2.8.
This class
public class DeviceForm {
Device device;
List<String> selectedItems = Collections.emptyList();
public DeviceForm() {
super();
}
public Device getDevice() {
return device;
}
public void setDevice(Device device) {
this.device = device;
}
public List<String> getSelectedItems() {
return selectedItems;
}
public void setSelectedItems(List<String> selectedItems) {
this.selectedItems = selectedItems;
}
}
and this
public class Device implements java.io.Serializable {
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "CRITERIA")
private BaseCriteria criteria;
public BaseCriteria getCriteria() {
return criteria;
}
public void setCriteria(BaseCriteria criteria) {
this.criteria = criteria;
}
}
and this
#Entity
#Table(name = "CRITERIA")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING)
#SequenceGenerator(name = "seqCriteria", sequenceName = "SEQ_CRITERIA", allocationSize = 1)
public abstract class BaseCriteria {
public BaseCriteria() {
super();
}
private Long id;
private String code;
private Date adoptionDate;
private Date expirationDate;
#Transient
public abstract String getGroupKey();
#Transient
public abstract Long getGroupId();
#Transient
public abstract String getRefColumnName();
#Id
#Column(name = "ID", unique = true, nullable = true)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqCriteria")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "CODE")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#Column(name = "ADOPTION_DATE")
#Temporal(TemporalType.TIMESTAMP)
public Date getAdoptionDate() {
return adoptionDate;
}
public void setAdoptionDate(Date adoptionDate) {
this.adoptionDate = adoptionDate;
}
#Column(name = "EXPIRATION_DATE")
#Temporal(TemporalType.TIMESTAMP)
public Date getExpirationDate() {
return expirationDate;
}
#Transient
public boolean isExpired() {
return getExpirationDate().before(new Date());
}
public void setExpirationDate(Date expirationDate) {
this.expirationDate = expirationDate;
}
#Override
public String toString() {
return "BaseCriteria [id=" + id + ", code=" + code + ", adoptionDate="
+ adoptionDate + ", expirationDate=" + expirationDate + "]";
}
}
and the JSP
<form:form commandName="deviceForm"
name="deviceForm"
id="deviceFormId"
method="post"
action="${contextPath}/newdesign/manage/device/${deviceForm.device.id}"
htmlEscape="yes">
<div class="col-sm-6 text-right">
<button class="btn btn-primary" type="submit">Save device</button>
</div>
</div>
<c:forEach items="${deviceForm.device.productGroup.criteria}" var="criteria">
<div class="row">
<div class="col-md-3">
<form:radiobutton path="device.criteria.id" value="${criteria.id}"/>
<label for="basic-url">Criteria:</label>
<input value="${criteria.code}" disabled="disabled" class="form-control"/>
</div>
<div class="col-md-3">
<label for="basic-url">Adoption date:</label>
<input value="<fmt:formatDate type="date" value="${criteria.adoptionDate}" />" disabled="disabled" class="form-control"/>
</div>
<div class="col-md-3">
<label for="basic-url">Expiration Date:</label>
<input value="<fmt:formatDate type="date" value="${criteria.expirationDate}" />" disabled="disabled" class="form-control"/>
</div>
</div>
</c:forEach>
</form:form>
The controller:
/**
* #throws Exception
*
*/
#RequestMapping(value = { "/newdesign/manage/device/{appId}",
"/newdesign/manage/device/{appId}/"}, method = {RequestMethod.GET})
public String viewDevicesWithStatus(
#ModelAttribute("deviceForm") DeviceForm deviceForm,
#PathVariable Long appId,
HttpServletRequest request,
Model model ) throws Exception {
Device device = manageLicenseService.getDeviceById(appId, true);
if (device.getCriteria()==null) {
device.setCriteria(device.getProductGroup().getCriteria().get(0));
}
deviceForm.setDevice(device);
fillModel (model, request, device);
return "cbViewDeviceInfo";
}
/**
* #throws Exception
*
*/
#RequestMapping(value = { "/newdesign/manage/device/{appId}",
"/newdesign/manage/device/{appId}/"}, method = {RequestMethod.POST})
public String saveDevicesWithStatus(
#ModelAttribute("deviceForm") DeviceForm deviceForm,
#PathVariable Long appId,
HttpServletRequest request,
Model model ) throws Exception {
Device device = manageLicenseService.getDeviceById(deviceForm.getDevice().getId());
if (device.getCriteria()==null) {
device.setCriteria(device.getProductGroup().getCriteria().get(0));
}
//TODO: audit
device.updateDevice(deviceForm.getDevice());
manageLicenseService.saveDevice(device);
if (device.getCriteria()==null) {
device.setCriteria(device.getProductGroup().getCriteria().get(0));
}
deviceForm.setDevice(device);
fillModel (model, request, device);
return "cbViewDeviceInfo";
}
But I got following error when I submitted the form, on GET method I got same page without error
org.springframework.beans.NullValueInNestedPathException: Invalid property 'device.criteria' of bean class [com.tdk.iot.controller.newdesign.manage.DeviceForm]: Could not instantiate property type [com.tdk.iot.domain.criteria.BaseCriteria] to auto-grow nested property path: java.lang.InstantiationException
You get the error because in your form you have this:
<form:radiobutton path="device.criteria.id" value="${criteria.id}"/>
and in your POST handler you have this:
public String saveDevicesWithStatus(#ModelAttribute("deviceForm") DeviceForm deviceForm){
}
which means that the MVC framework will try to automatically set the property
deviceForm.device.criteria.id.
Now, because there is no existing DeviceForm in any scope then it will create a new one and of course device.getCriteria() returns null,
hence the exception.
You may think that the DeviceForm you created and populated in the GET handler will be used however Spring MVC is stateless so you
would need to store it in Session scope between requests for it to be re-used or otherwise rework your logic.
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib-method-args
.... Given the above example where can theinstance come from? There
are several options.....[in the absence of any other option] It may
be instantiated using its default constructor
A better approach however is to change your form to be as below:
<form:radiobutton path="device.criteria" value="${criteria.id}"/>
and register a converter that would convert the submitted parameter and bind the corresponding entity instance.
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html#core-convert
#Component
public class StringToCriteriaConverter implements Converter<String, BaseCriteria> {
#Autowired
private CriteriaService service;
//source is the ID passed by the page
public BaseCriteria convert(String source) {
// lookup and return item with corresponding ID from the database
}
}

Spring form doesn't submit to database correctly

I have a form where a user fills everything out in a settings page. All of it works except two fields. I'm not sure if it's the form or Controller or my table set up.
Here are the forms that aren't working.
<form:input path="minimumCost" type="text" class="form-control" id="exampleInputAmount" placeholder=""></form:input>
and
<form:input path="rate" type="text" class="form-control" id="exampleInputAmount" placeholder=""></form:input>
but this one DOES work
<form:input path="houseSize" type="text" class="form-control" id="exampleInputAmount" placeholder=""></form:input>
Here is the JPA i configured with them
#Column(name = "minimum_Cost")
private String minimumCost;
#Column(name = "rate")
private String rate;
#Column(name = "house_size")
private String houseSize;
public String getMinimumCost() {
return minimumCost;
}
public void setMinimumCost(String minimumCost) {
this.minimumCost = minimumCost;
}
public String getRate() {
return rate;
}
public void setRate(String rate) {
this.rate = rate;
}
public String getHouseSize() {
return houseSize;
}
public void setHouseSize(String houseSize) {
this.houseSize = houseSize;
}
Why are the minimumCost and rate showing up as null and houseSize works? They're all in the same form so it's not like they're being left out.
remove id="exampleInputAmount" and try it again~

Request syntactically incorrect

I am trying to post some variables to my controller which are then entered into a DB. But i keep getting an error stating that the request is syntactically incorrect.
Here is the form.
<form:form action="addLink" method="POST" commandName="link" >
<table id="productFinderTable">
<tbody align="left">
<tr align="left">
<td colspan="2">Gender:<input style="width: 798px;" type="number" name="gender" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Garment:<input style="width: 798px;" type="number" name="garment" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Product Class:<input style="width: 798px;" type="number" name="productclass" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Sport:<input style="width: 798px;" type="text" name="sport" value="1" /></td>
</tr>
<tr align="left">
<td colspan="2">Link:<input style="width: 798px;" type="text" name="link" value="http://www.google.ie" /></td>
</tr>
<tr align="left">
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</tbody>
</table>
</form:form>
The Entity Link
package com.wlgore.webapp.fab.pfsa.db;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
#Entity
#Table(name = "LINK")
public class Link implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column
private String hash;
#Column
#NotNull
private String link;
#Column
#NotNull
private Integer garment;
#Column
#NotNull
private Integer productclass;
#Column
#NotNull
private Integer gender;
#Column
private String sport;
/**
* #return the link
*/
public String getLink() {
return link;
}
/**
* #param link the link to set
*/
public void setLink(String link) {
this.link = link;
}
/**
* #return the garment
*/
public Integer getGarment() {
return garment;
}
/**
* #param garment the garment to set
*/
public void setGarment(Integer garment) {
this.garment = garment;
}
/**
* #return the productclass
*/
public Integer getProductclass() {
return productclass;
}
/**
* #param productclass the productclass to set
*/
public void setProductclass(Integer productclass) {
this.productclass = productclass;
}
/**
* #return the gender
*/
public Integer getGender() {
return gender;
}
/**
* #param gender the gender to set
*/
public void setGender(Integer gender) {
this.gender = gender;
}
/**
* #return the sport
*/
public String getSport() {
return sport;
}
/**
* #param sport the sport to set
*/
public void setSport(String sport) {
this.sport = sport;
}
/**
* #return the hash
*/
public String getHash() {
return hash;
}
/**
* #param hash the hash to set
*/
public void setHash(String hash) {
this.hash = hash;
}
}
Controller
#RequestMapping(value = "/addLink", method = RequestMethod.POST)
public #ResponseBody String addNewCommand(#ModelAttribute("link") Link link, BindingResult result)throws Exception{
/***
* Here we receive the relvant variables 1.Gender 2.Garment 3.Product
* Class 4.Sport 5.Link
* */
try {
if (result.hasErrors()) {
throw new Exception("Invalid post!");
} else {
String hash = HashFunction.gen(8);
Link linkExists = dao.getById(hash);
while (null != linkExists) {
hash = HashFunction.gen(8);
linkExists = dao.getById(hash);
}
System.out.println(hash);
link.setHash(hash);
dao.create(link);
return new ObjectMapper().writeValueAsString("Test Message");
}
} catch (Exception e) {
return new ObjectMapper().writeValueAsString(new ErrorJSON(e));
}
}
I don’t think #ModelAttribute is the correct annotation here. For BindingResult to work, you also need #Valid on the form bean.

Categories