I am not able to get the file name in spring controller
<form:form method="post" modelAttribute="sampleDetails"
enctype="multipart/form-data">
<input type="file" name="uploadedFileName" id="fileToUpload" required="" >
<input type="submit" name="import_file" value="Import File" id="" />
</form:form>
Its my post method in controller
#RequestMapping(method = RequestMethod.POST)
public String importQuestion(#Valid #RequestParam("uploadedFileName")
MultipartFile multipart, #ModelAttribute("sampleDetails") SampleDocumentPojo sampleDocument, BindingResult result, ModelMap model) {
logger.debug("Post method of uploaded Questions ");
logger.debug("Uploaded file Name : " + multipart.getName());
return "importQuestion";
}
After submit get the warning message.
warning [http-nio-8080-exec-9] WARN
org.springframework.web.servlet.PageNotFound - Request method 'POST' not
supported
[http-nio-8080-exec-9] WARN
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
- Handler execution resulted in exception: Request method 'POST' not
supported
You can also use MutlipartFile in order to upload file as follow.
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
#ResponseBody
public String uploadFile(#RequestParam("file") MultipartFile file) {
try {
String uploadDir = "/uploads/";
String realPath = request.getServletContext().getRealPath(uploadDir);
File transferFile = new File(realPath + "/" + file.getOriginalFilename());
file.transferTo(transferFile);
} catch (Exception e) {
e.printStackTrace();
return "Failure";
}
return "Success";
}
You don't need to use spring form for file upload, you can do it with plain HTML
<html>
<body>
<h2>Spring MVC file upload using Annotation configuration Metadata</h2>
Upload File :
<form name="fileUpload" method="POST" action="uploadFile" enctype="multipart/form-data">
<label>Select File</label> <br />
<input type="file" name="file" />
<input type="submit" name="submit" value="Upload" />
</form>
</body>
</html>
You need to configure MultipartResolver object in yours application configuration as follow
#Bean(name="multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multi = new CommonsMultipartResolver();
multi.setMaxUploadSize(100000);
return multi;
}
You can follow complete tutorial on how to upload file in Spring Framework Upload File in Spring MVC framework
in your controller you need to specify that you are expecting mutlipart
using
consumes = {"multipart/form-data"}
and to ge the file name using getOriginalFileName()
#RequestMapping(method = RequestMethod.POST, consumes = {"multipart/form-data"})
public String importQuestion(#Valid #RequestParam("uploadedFileName")
MultipartFile multipart, BindingResult result, ModelMap model) {
logger.debug("Post method of uploaded Questions ");
logger.debug("Uploaded file Name : " + multipart.getOriginalFilename());
return "importQuestion";
}
Also in your html the name of your input of type file should be the same as the RequestParam "uploadedFileName"
<input type="file" name="uploadFileName" id="fileToUpload" required="" >
change it to
<input type="file" name="uploadedFileName" id="fileToUpload" required="" >
I think you form is not handled by the method importQuestion,you can remove method = RequestMethod.POST to make sure it.
your model name not reference to MultipartFile
can have cross reference in yours mappings
try this:
<form:form method="post" action="testcontrol" enctype="multipart/form-data">
<input type="file" name="uploadedFileName" id="fileToUpload" required="" >
<input type="submit" name="import_file" value="Import File" id="" />
and set in your controller
#RequestMapping(method = RequestMethod.POST,path="/testcontrol")
public String importQuestion(#RequestParam("uploadedFileName")
MultipartFile multipart, BindingResult result, ModelMap model) {
logger.debug("Post method of uploaded Questions ");
logger.debug("Uploaded file Name : " + multipart.getName());
return "importQuestion";
}
package com.form.demo.Controll;
import com.form.demo.Repo.CustoRepo;
import com.form.demo.Serv.CustoSevice;
import com.form.demo.model.Customer;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
#Controller
#RequestMapping("/")
public class SimpleWebController {
private CustoSevice custoSevice;
public SimpleWebController(CustoSevice custoSevice) {
this.custoSevice = custoSevice;
}
public static String uploadDirectory = System.getProperty("user.dir")+"/uploads";
#RequestMapping(value={"/","/form"}, method=RequestMethod.GET)
public String customerForm(Model model) {
model.addAttribute("customer", new Customer());
return "form";
}
#RequestMapping(value="/form", method=RequestMethod.POST)
public String customerSubmit(#ModelAttribute Customer customer,Model model,#RequestParam("files") MultipartFile[] files) {
StringBuilder fileNames = new StringBuilder();
String path1 = "";
for (MultipartFile file : files) {
Path fileNameAndPath = Paths.get(uploadDirectory, file.getOriginalFilename());
fileNames.append(file.getOriginalFilename()+" ");
try {
Files.write(fileNameAndPath, file.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
path1=fileNameAndPath.toString();
}
customer.setImage(path1);
model.addAttribute("customer", customer);
custoSevice.save(customer);
return "result";
}
#RequestMapping(value = "/vewall")
public String vew(Model model){
List<Customer>customers=custoSevice.findAll();
model.addAttribute("cus",customers);
return "vewall";
}
#RequestMapping(value={"/","/update/{id}"}, method=RequestMethod.GET)
public String showUpdateForm(#PathVariable("id") long id, Model model) {
Customer customer = custoSevice.findById(id);
model.addAttribute("user", customer);
return "update";
}
#RequestMapping(value={"/","/update/{id}"}, method=RequestMethod.POST)
public String updateUser(#Valid Customer customer,Model model) {
custoSevice.save(customer);
model.addAttribute("cus", custoSevice.findAll());
return "vewall";
}
#RequestMapping(value = "/delete/{id}",method = RequestMethod.GET)
public String deleteUser(#PathVariable("id") long id, Model model) {
Customer customer = custoSevice.findById(id);
custoSevice.delete(customer);
model.addAttribute("cus", custoSevice.findAll());
return "vewall";
}
}
package com.form.demo.model;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;
#Entity
#Table(name = "cust4")
public class Customer implements Serializable {
#Id
// #GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "firstname")
private String firstname;
#Column(name = "lastname")
private String lastname;
#Column(name = "image")
private String image;
public Customer() {
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
this.image = image;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
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;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return id == customer.id &&
Objects.equals(firstname, customer.firstname) &&
Objects.equals(lastname, customer.lastname) &&
Objects.equals(image, customer.image);
}
#Override
public int hashCode() {
return Objects.hash(id, firstname, lastname, image);
}
#Override
public String toString() {
return "Customer{" +
"id=" + id +
", firstname='" + firstname + '\'' +
", lastname='" + lastname + '\'' +
", image='" + image + '\'' +
'}';
}
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<meta>
<meta charset="UTF-8"></meta>
<title>Title</title>
</head>
<body>
<h1>Customer Form</h1>
<form action="#" th:action="#{/form}" th:object="${customer}" method="post" enctype="multipart/form-data">
<p>First Name: <input type="text" th:field="*{firstname}" /></p>
<p>Last Name: <input type="text" th:field="*{lastname}" /></p>
<p>Image: <input type="file" name="files" multiple></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
<br>
Viewall
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Title</title>
</head>
<body>
<h2>List of cities</h2>
<table>
<tr>
<th>ID</th>
<th>FName</th>
<th>LName</th>
<th>Path</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<tr th:each="city : ${cus}">
<td th:text="${city.id}">Id</td>
<td th:text="${city.firstname}">Name</td>
<td th:text="${city.lastname}">Population</td>
<td th:text="${city.image}">Path </td>
<td><a th:href="#{/update/{id}(id=${city.id})}">Edit</a></td>
<td><a th:href="#{/delete/{id}(id=${city.id})}">Delete</a></td>
</tr>
</table>
</body>
</html>
spring.datasource.url=jdbc:mysql://localhost:3306/new1
spring.datasource.username=root
spring.datasource.password=root
spring.servlet.multipart.max-file-size=15MB
spring.servlet.multipart.max-request-size=15MB
//
package com.example.demo;
import java.io.File;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import controller.FileUploadController;
#Configuration
#EnableAutoConfiguration
#ComponentScan({"demo","controller"})
public class FileUploadApplication {
public static void main(String[] args) {
new File(FileUploadController.uploadDirectory).mkdir();
SpringApplication.run(FileUploadApplication.class, args);
}
}
Related
I have problem with Spring MVC project. I want to insert in to values to database but when I click the submit button shows error HTTP Status 500 - Request processing failed; nested exception is org.hibernate.exception.ConstraintViolationException: could not insert: [sample.entity.Details]
I don't know what's the problem.
please help me?
the program given below
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Student Event Co-Ordinators/Organizer Details</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="//cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css">
<style>
body{
display: flex;
}
#submit
{
background-color: orange;
color:white;
height: 30px;
width:200px;
border: none;
}
input[type=text] input[type=email] input[type=number]{
transition: width 0.4s ease-in-out;
}
table {
border-collapse: collapse;
border: 1px solid black;
table-layout: auto;
width: 100%;
}
th,td {
border: 1px solid black;
width:16%
}
.btn {
border: none;
background-color: inherit;
padding: 14px 28px;
font-size: 16px;
cursor: pointer;
display: inline-block;
}
.btn-add
{
background-color: orange;
color:white;
height: 40px;
width:200px;
border: none;
font-size: 12px;
}
/* On mouse-over */
.btn:hover {background: #eee;}
.btn-warning {color: orange;}
.btn-danger {color: red;}
.btn-info{
color:blue;
}
</style>
</head>
<body>
<div class="container">
<h3>Student Event Co-Ordinators/Organizer Details</h3>
<form id="studentevent" name="studentevent" action="/index.htm" method="post">
<input type="hidden" id="id" name="id" >
<div>
<div>
<input type="text" placeholder="Event name" name="name" required="" id="name">
<input type="email" placeholder="Event email id" name="email" required="" id="email">
<input type="number" placeholder="Registration fee" name="fee" required="" id="fee">
<input type="text" placeholder="Student name" name="sname" required="" id="sname">
<input type="number" placeholder="Student contact no" name="contactno" required="" id="contactno">
</div>
<br>
<div>
<input type="button" id="submit" value="submit" onclick="return addstudentevent();">
</form>
<br>
<br>
<table class="data-table" id="data-table">
<thead>
<th>Event Name</th>
<th>Email Id</th>
<th>Registration Fee</th>
<th>Student Name</th>
<th>Contact No</th>
<th> </th>
</thead>
<tbody id="displayBody">
</tbody>
</table>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js" type="text/javascript"></script>
<script>
getall();
var isNew = true;
var studentid= null;
function addstudentevent()
{
var addId = $("#id").val();
var url = "";
var data = "";
var method;
if (isNew===true)
{
url = 'insert.htm';
data = $("#studentevent").serialize()+ "&Id=" + addId;
method = 'POST';
}
else
{
url = 'update.htm';
data = $("#studentevent").serialize() + "&Id=" + addId;
method = 'POST';
}
$.ajax({
type: method,
url : url,
dataType: 'JSON',
data : data,
success:function(data)
{
getall();
// $('id').val("");
$('#name').val("");
$('#email').val("");
$('#fee').val("");
$('#sname').val("");
$('#contactno').val("");
if(isNew === true)
{
alert("Data Inserted");
}
else
{
alert("Data Updated");
}
}
});
}
function getall()
{
$('#data-table').dataTable().fnDestroy();
$.ajax ({
url: "fetch.htm",
type: "GET",
dataType:"JSON",
success: function(data)
{
$("#data-table").dataTable({
"aaData":data,
"scrollX": true,
"aoColumns":
[
{"mData": "name"},
{"mData": "email"},
{"mData": "fee"},
{"mData": "sname"},
{"mData": "contactno"} ,
{ // " mData": "id",
mData:"id",
"render" : function(mData,type,row,meta)
{
return '<button class="btn btn-warning" onclick="get_details('+ mData +')">Edit</button><button class="btn btn-danger" onclick="get_delete('+ mData +')">Delete</button>';
}}
]
}); }
});
}
function get_details(id)
{
$.ajax({
type: "POST",
url: "edit.htm",
data: {"id": id},
success: function(data)
{
isNew = false;
var obj = JSON.parse(data);
studentid = obj[0].id;
$('#name').val(obj[0].name);
$('#email').val(obj[0].email);
$('#fee').val(obj[0].fee);
$('#sname').val(obj[0].sname);
$('#contactno').val(obj[0].contactno);
}
});
}
function get_delete(id)
{
$.ajax({
type:'POST',
url: 'delete.htm',
dataType: 'JSON',
data:{'id':id},
success:function (data)
{
alert("Data deleted");
getall();
}
});
}
</script>
</body>
</html>
studentcontroller.java
package sample.controller;
import com.google.gson.Gson;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import sample.dao.studentDao;
import sample.entity.Details;
/**
*
* #author admin
*/
#Controller
public class studentController {
#Autowired
studentDao stDao;
#RequestMapping(value ="index.htm", method = RequestMethod.GET)
public String index()
{
System.out.println("at index");
return "index";
}
#RequestMapping(value ="insert.htm", method = RequestMethod.POST)
public #ResponseBody String insert
(
#RequestParam("id") Integer id,
#RequestParam("name") String name,
#RequestParam("email") String email,
#RequestParam("fee") String fee,
#RequestParam("sname") String sname,
#RequestParam("contactno") String contactno
)
{
Details ei= new Details();
ei.setName(name);
ei.setEmail(email);
ei.setFee(fee);
ei.setSname(sname);
ei.setContactno(contactno);
stDao.save(ei);
Gson ob = new Gson();
return "success";
}
#RequestMapping(value="fetch.htm", method = RequestMethod.GET)
public #ResponseBody String display()
{
List<Details> listdetails = (List<Details>) stDao.display();
return new Gson().toJson(listdetails);
}
#RequestMapping(value = "delete.htm")
public #ResponseBody String delete(#RequestParam("id") Integer id)
{
stDao.delete(id);
return "successful";
}
#RequestMapping(value = "edit.htm")
public #ResponseBody String edit(#RequestParam("id") Integer id)
{
List editlist;
editlist = stDao.getDetailsForEdit(id);
return new Gson().toJson(editlist);
}
#RequestMapping(value = "update.htm", method = RequestMethod.POST)
public #ResponseBody String update
(
#RequestParam(value="id",required=false) Integer id,
#RequestParam("name") String name,
#RequestParam("email") String email,
#RequestParam("fee") String fee,
#RequestParam("sname") String sname,
#RequestParam("contactno") String contactno
)
{
Details st = new Details();
st.setName(name);
st.setEmail(email);
st.setFee(fee);
st.setSname(sname);
st.setContactno(contactno);
System.out.println("st");
stDao.update(st);
Gson ob = new Gson();
return "success";
}
}
studentDao.java
package sample.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import sample.entity.Details;
/**
*
* #author admin
*/
#Transactional
#Repository
public class studentDao {
#Autowired
private SessionFactory sessionFactory;
public void save(Details stdinfo) {
Session session = sessionFactory.openSession();
session.save(stdinfo);
session.close();
}
public List display() {
Session session = sessionFactory.openSession();
Criteria criteria = session.createCriteria(Details.class);
criteria.setProjection(Projections.projectionList().add(Projections.property("id"), "id")
.add(Projections.property("name"), "name")
.add(Projections.property("email"), "email")
.add(Projections.property("fee"), "fee")
.add(Projections.property("sname"), "sname")
.add(Projections.property("contactno"), "contactno"));
criteria.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List list = criteria.list();
session.close();
return list;
}
public void delete(Integer id){
Session session = sessionFactory.openSession();
Transaction trx = session.beginTransaction();
Details stdtl = new Details(id);
session.delete(stdtl);
trx.commit();
session.close();
}
public List getDetailsForEdit(Integer id) {
Session session = sessionFactory.openSession();
Criteria criteria = session.createCriteria(Details.class);
criteria.setProjection(Projections.projectionList()
.add(Projections.property("id"), "id")
.add(Projections.property("name"), "name")
.add(Projections.property("email"), "email")
.add(Projections.property("fee"), "fee")
.add(Projections.property("sname"), "sname")
.add(Projections.property("contactno"), "contactno")
);
criteria.add(Restrictions.eq("id", id));
criteria.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List list = criteria.list();
session.close();
return list;
}
public void update(Details Stdinfo){
Session session = sessionFactory.openSession();
Transaction trx = session.beginTransaction();
session.update(Stdinfo);
trx.commit();
session.close();
}
}
Details.java
package sample.entity;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;
/**
*
* #author admin
*/
#Entity
#Table(name = "studentevent")
#NamedQueries({
#NamedQuery(name = "studentevent.findAll", query = "SELECT d FROM studentevent d")})
public class Details implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Column(name = "name")
private String[] name;
#Column(name = "email")
private String mail;
#Column(name = "fee")
private String fee;
#Column(name = "sname")
private String sname;
#Column(name = "contactno")
private String contactno;
public Details() {
}
public Details(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String[] getName() {
return name;
}
public void setName(String stdname) {
this.name = name;
}
public String getEmail() {
String email = null;
return email;
}
public void setEmail(String email) {
this.mail = email;
}
public String getFee() {
String fee = null;
return fee;
}
public void setFee(String fee) {
this.fee= fee;
}
public String getSname() {
String sname = null;
return sname;
}
public void setSname(String sname) {
this.sname= sname;
}
public String getContactno() {
return contactno;
}
public void setContactno(String contactno) {
this.contactno = contactno;
}
}
As #Lalit Mehra mentioned in the comments, HTML is sending a POST request and the controller is expecting a GET:
<form id="studentevent" name="studentevent" action="/index.htm" method="post">
#RequestMapping(value ="index.htm", method = RequestMethod.GET)
Make them match with the same request method and it will work.
--> when i am Updating it was not saving the entered details insted it was saving null. when deleting it throws error.
DataBase : restonetoone
application.properties
/*****************************/
crm.rest.url=http://localhost:8080/restonetoone/api/details
-->when i use to update it was taking null value insted of inserted data.
Details [id=25, city=null, mobileno=0, student=Student [id=25, name=null, clas=0]]
->when i was deleting it throws this error.
Mar 06, 2021 4:09:53 PM org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping for GET /restclient/student/delete
the Details.java class Onetoone with student.java class
Details.java
/******************/
package com.rest.entity;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name="details")
public class Details {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String city;
private long mobileno;
#OneToOne(cascade=CascadeType.ALL)
#JoinColumn(name="student_id")
private Student student;
public Details(){
}
public Details(int id, String city, long mobileno, Student student) {
super();
this.id = id;
this.city = city;
this.mobileno = mobileno;
this.student = student;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public long getMobileno() {
return mobileno;
}
public void setMobileno(long mobileno) {
this.mobileno = mobileno;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
#Override
public String toString() {
return "Details [id=" + id + ", city=" + city + ", mobileno=" + mobileno + ", student=" + student + "]";
}
}
student.java class
Student.java
/******************/
package com.rest.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="student")
public class Student {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
private int clas;
public Student() {
}
public Student(int id, String name, int clas) {
super();
this.id = id;
this.name = name;
this.clas = clas;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getClas() {
return clas;
}
public void setClas(int clas) {
this.clas = clas;
}
#Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", clas=" + clas + "]";
}
}
DetailsServImpl.java class(service layers)
DetailsServImpl.java
/******************/
package com.rest.service;
import java.util.List;
import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.rest.entity.Details;
#Service
public class DetailsServImpl implements DetailsServ {
private RestTemplate restTemplate;
private String crmRestUrl;
private Logger logger = Logger.getLogger(getClass().getName());
#Autowired
public DetailsServImpl(RestTemplate theRestTemplate,
#Value("${crm.rest.url}") String theUrl) {
restTemplate = theRestTemplate;
crmRestUrl = theUrl;
logger.info("Loaded property: crm.rest.url=" + crmRestUrl);
}
#Override
public List<Details> getDetails() {
logger.info("in getDetails(): Calling REST API " + crmRestUrl);
// make REST call
ResponseEntity<List<Details>> responseEntity =
restTemplate.exchange(crmRestUrl, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Details>>() {});
// get the list of customers from response
List<Details> theDetails = responseEntity.getBody();
logger.info("in getDetails(): details" + theDetails);
return theDetails;
}
#Override
public Details getDetails(int theId) {
logger.info("in getDetails(): Calling REST API " + crmRestUrl);
// make REST call
Details theDetails =
restTemplate.getForObject(crmRestUrl + "/" + theId,
Details.class);
logger.info("in saveDetails(): theDetails=" + theDetails);
return theDetails;
}
#Override
public void saveDetails(Details theDetails) {
logger.info("in saveSt(): Cudentalling REST API " + crmRestUrl);
int detailsId = theDetails.getId();
// make REST call
if (detailsId == 0) {
// add employee
restTemplate.postForEntity(crmRestUrl, theDetails, String.class);
} else {
// update employee
restTemplate.put(crmRestUrl, theDetails);
}
logger.info("in saveDetails(): success");
}
#Override
public void deleteDetails(int theId) {
logger.info("in deleteDetails(): Calling REST API " + crmRestUrl);
// make REST call
restTemplate.delete(crmRestUrl + "/" + theId);
logger.info("in deleteDetails(): deleted Details theId=" + theId);
}
}
StudentServImpl.java class
StudentServImpl.java
/******************/
package com.rest.service;
import java.util.List;
import java.util.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.rest.entity.Details;
import com.rest.entity.Student;
#Service
public class StudentServImpl implements StudentServ {
private RestTemplate restTemplate;
private String crmRestUrl;
private Logger logger = Logger.getLogger(getClass().getName());
#Autowired
public StudentServImpl(RestTemplate theRestTemplate,#Value("${crm.rest.url}") String theUrl){
restTemplate = theRestTemplate;
crmRestUrl = theUrl;
logger.info("Loaded property: crm.rest.url=" + crmRestUrl);
}
#Override
public List<Student> getStudent() {
logger.info("in getCustomers(): Calling REST API " + crmRestUrl);
// make REST call
ResponseEntity<List<Student>> responseEntity =
restTemplate.exchange(crmRestUrl, HttpMethod.GET, null,
new ParameterizedTypeReference<List<Student>>() {});
// get the list of customers from response
List<Student> theStudent = responseEntity.getBody();
logger.info("in getCustomers(): customers" + theStudent);
return theStudent;
}
#Override
public void saveStudent(Student theStudent) {
logger.info("in saveSt(): Cudentalling REST API " + crmRestUrl);
int studentId = theStudent.getId();
// make REST call
if (studentId == 0) {
// add employee
restTemplate.postForEntity(crmRestUrl, theStudent, String.class);
} else {
// update employee
restTemplate.put(crmRestUrl, theStudent);
}
logger.info("in saveStudent(): success");
}
#Override
public Student getStudent(int theId) {
logger.info("in getCustomer(): Calling REST API " + crmRestUrl);
// make REST call
Student theStudent =
restTemplate.getForObject(crmRestUrl + "/" + theId,
Student.class);
logger.info("in saveCustomer(): theCustomer=" + theStudent);
return theStudent;
}
#Override
public void deleteStudent(int theId) {
logger.info("in deleteStudent(): Calling REST API " + crmRestUrl);
// make REST call
restTemplate.delete(crmRestUrl + "/" + theId);
logger.info("in deleteStudent(): deleted Student theId=" + theId);
}
}
Now the controller class(here i am using single controller for multiple entites).
ClientController.java
/******************/
package com.rest.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.rest.entity.Details;
import com.rest.entity.Student;
import com.rest.service.DetailsServ;
import com.rest.service.StudentServ;
#Controller
#RequestMapping("/cont")
public class ClientController {
#Autowired
private DetailsServ detailsServ;
#Autowired
private StudentServ studentServ;
#GetMapping("/showForm")
public String showForm(Model theModel){
Details theDetails = new Details();
Student theStudent = new Student();
theDetails.setStudent(theStudent);
theModel.addAttribute("for",theDetails);
return "the-for";
}
#PostMapping("/saveForm")
private String saveForm(#ModelAttribute("for") Details theDetails) {
detailsServ.saveDetails(theDetails);
return "redirect:/cont/list";
}
#GetMapping("/list")
public String showList(Model theModel) {
List<Details> theDetails = detailsServ.getDetails();
theModel.addAttribute("details", theDetails);
return "list-table";
}
#GetMapping("/update")
public String updateDetails(#RequestParam("detailsId") int theId, Model theModel) {
Details theDetails =detailsServ.getDetails(theId);
theModel.addAttribute("for",theDetails);
return "the-for";
}
#GetMapping("/delete")
public String deleteDetails(#RequestParam("detailsId") int theId) {
detailsServ.deleteDetails(theId);
return "redirect:/cont/list";
}
}
I use this form for both saving and updating.
the-for.jsp
/******************/
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# page import="java.sql.*"%>
<!DOCTYPE html>
<html>
<head>
<title>Save Customer</title>
<link type="text/css"
rel="stylesheet"
href="${pageContext.request.contextPath}/resources/css/style.css">
<link type="text/css"
rel="stylesheet"
href="${pageContext.request.contextPath}/resources/css/add-customer-style.css">
</head>
<body>
<div id="wrapper">
<div id="header">
<h2>Form</h2>
</div>
</div>
<div id="container">
<h3>Save StudentDetails</h3>
<form:form action="saveForm" modelAttribute="for" method="POST">
<!-- need to associate this data with customer id -->
<form:hidden path="id" />
<table>
<tbody>
<tr>
<td><label>City name:</label></td>
<td><form:input path="city" /></td>
</tr>
<tr>
<td><label>mobileno:</label></td>
<td><form:input path="mobileno" /></td>
</tr>
<tr>
<td><label>name:</label></td>
<td><form:input path="student.name" /></td>
</tr>
<tr>
<td><label>class:</label></td>
<td><form:input path="student.clas" /></td>
</tr>
<tr>
<td><label></label></td>
<td><input type="submit" value="Save" class="save" /></td>
</tr>
</tbody>
</table>
</form:form>
<div style="clear; both;"></div>
<p>
Back to List
</p>
</div>
</body>
</html>
Now the table which shows the CRUD dynamically.
list-table.jsp
/******************/
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# page import = "java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<title>List</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous">
</head>
<body>
<div class="container">
<h2 class="pt-2">Student Manager</h2>
<!-- put new button: Add Student -->
<input type="button" value="Add Student"
onclick="window.location.href='showForm'; return false;"
class="btn btn-primary btn-sm mb-3" />
<!-- add our html table here -->
<table class="table table-bordered table-striped">
<thead class="table-dark">
<tr>
<th>city</th>
<th>mobileno</th>
<th>name</th>
<th>class</th>
<th>Action</th>
</tr>
</thead>
<!-- loop over and print our students -->
<tbody>
<c:forEach var="tempDetails" items="${details}">
<!-- construct an "update" link with student id -->
<c:url var="updateLink" value="/cont/update">
<c:param name="detailsId" value="${tempDetails.id}" />
</c:url>
<!-- construct an "delete" link with student id -->
<c:url var="deleteLink" value="/student/delete">
<c:param name="studentId" value="${tempStudent.id}" />
</c:url>
<tr>
<td>${tempDetails.city}</td>
<td>${tempDetails.mobileno}</td>
<td>${tempDetails.student.name}</td>
<td>${tempDetails.student.clas}</td>
<td>
<!-- display the update link -->
Update
|
<a href="${deleteLink}"
onclick="if (!(confirm('Are you sure you want to delete this student?'))) return false">Delete</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</body>
</html>
For more clearity sake i am shering the link of my project which include Both client side and backend code files with database.
LINK( https://drive.google.com/file/d/128pvCd6bYdCNhOiG6ERRXbPRUlnhZlTp/view?usp=sharing )
Hey I've got a problem with updating my object. I've got a table of movies where can i delete it or go to details. In details i wanted to have my "update" option. Im giving whole object to movieDetailPage, it shows object details in input fields but i cant update it. My "updateMovie" method doesnt see what i typed in input. For example im changing name from "Movie1" to "Movie2" and method still see "Movie1"
Here's my movieDetailsPage.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form th:object="${movieToUpdate}" method=post >
<p>Movie name: <input type="text" th:field="*{name}"></p>
<p>Movie description: <input type="text" th:field="*{description}"></p>
<img th:src="${movieToUpdate.getImageUrl()}" th:width="300" th:height="300"><br>
<p>Nowy image url: <input type="text" th:field="*{imageUrl}" class="cloudinary-fileupload"></p>
<a th:href="${'/movie/update/'+movieToUpdate.getId()}">Update</a><br>
</form>
</body>
</html>
and my controller class
package pl.fsaaa.filmapp.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import pl.fsaaa.filmapp.model.Movie;
import pl.fsaaa.filmapp.service.CloudinaryImageUploader;
import pl.fsaaa.filmapp.service.MovieService;
import java.io.IOException;
import java.util.List;
#Controller
public class MovieController {
private CloudinaryImageUploader cloudinaryImageUploader;
private MovieService movieService;
#Autowired
public MovieController(MovieService movieService, CloudinaryImageUploader cloudinaryImageUploader) {
this.movieService = movieService;
this.cloudinaryImageUploader = cloudinaryImageUploader;
}
#GetMapping("/addmovie")
public String getNewMovie(Model model) {
model.addAttribute("newMovie",new Movie());
// model.addAttribute("newImage",new File(""));
return "addMoviePage";
}
#PostMapping("/add-movie")
public String addMovie(#ModelAttribute Movie movie) throws IOException {
cloudinaryImageUploader.saveImageToCloudinary(movie.getImageUrl());
movie.setImageUrl(cloudinaryImageUploader.getCloudinaryImageUrl());
movieService.addMovie(movie);
return "redirect:/addmovie";
}
#GetMapping("/movies")
public String getAllMovies(Model model) {
List<Movie> movieList = movieService.getAllMovies();
model.addAttribute("allMovies",movieList);
return "moviesPage";
}
#GetMapping("/movie/{id}")
public String getMovieDetail(Model model, #PathVariable Long id) {
Movie movieToUpdate = movieService.getMovieById(id);
System.out.println(movieToUpdate);
model.addAttribute("movieToUpdate", movieToUpdate);
return "movieDetailsPage";
}
#RequestMapping(value = "/movie/update/{id}", method = {RequestMethod.GET,RequestMethod.PUT})
// #PutMapping("movie/update/{id}")
public String updateMovie(#PathVariable Long id, #ModelAttribute Movie movieToUpdate){
// movieToUpdate = movieService.getMovieById(id);
// System.out.println(movieToUpdate);
movieService.addMovie(movieToUpdate);
return "redirect:/movies";
}
#RequestMapping(value = "/movie/delete/{id}", method = {RequestMethod.DELETE,RequestMethod.GET})
public String deleteMovie(#PathVariable Long id){
movieService.deleteMovie(id);
return "redirect:/movies";
}
}
Problem solved.
I've added submit button to details page instead of link:
<form th:action="'/movies/update/'+*{id}" th:object="${movieToUpdate}" method=put >
<p>Movie name: <input type="text" th:field="*{name}"></p>
<p>Movie description: <input type="text" th:field="*{description}"></p>
<img th:src="${movieToUpdate.getImageUrl()}" th:width="300" th:height="300"><br>
<p>New image url: <input type="text" th:field="*{imageUrl}" class="cloudinary-fileupload"></p>
<p><input type="submit" value="Update"></p>
</form>
and changed update edited "movie" method a little bit, because previous one wasn't uploading changed image to cloudinary.
#RequestMapping(value = "/update/{id}", method = {RequestMethod.GET,RequestMethod.PUT})
public String updateMovie(#PathVariable Long id, #ModelAttribute Movie movieToUpdate) throws IOException {
movieToUpdate.setId(id);
cloudinaryImageUploader.saveImageToCloudinary(movieToUpdate.getImageUrl());
movieToUpdate.setImageUrl(cloudinaryImageUploader.getCloudinaryImageUrl());
movieService.addMovie(movieToUpdate);
return "redirect:/movies/all";
}
I try to write simple Spring MVC CRUD webapp and I got a problem updating my rows. I have a table with some users and I can edit any of them clicking "Edit" button in the table (look at the picture). Then I can change its fields in a form, but when I click "Edit" under the form, the id of user entity, that is conveyed to the addUser() method, is 0, though, when I got the entity from db, it wasn't. Also "createdDate" field becomes null. I can't find out the reason of it, so I need some help... This is my code and the picture with my app:
The picture
user.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%#page isELIgnored="false" %>
<%# page session="false" %>
<html>
<head>
<title>Users</title>
<style type="text/css">
.tg {border-collapse:collapse;border-spacing:0;border-color:#ccc;}
.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#fff;}
.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#ccc;color:#333;background-color:#f0f0f0;}
.tg .tg-4eph{background-color:#f9f9f9}
</style>
</head>
<body>
<h1>
Add a user
</h1>
<c:url var="addAction" value="/user/add" />
<form:form action="${addAction}" commandName="user">
<table>
<c:if test="${!empty user.name}">
<tr>
<td>
<form:label path="id">
<spring:message text="ID"/>
</form:label>
</td>
<td>
<form:input path="id" readonly="true" size="8" disabled="true" />
</td>
</tr>
</c:if>
<tr>
<td>
<form:label path="name">
<spring:message text="Name"/>
</form:label>
</td>
<td>
<form:input path="name" />
</td>
</tr>
<tr>
<td>
<form:label path="age">
<spring:message text="Age"/>
</form:label>
</td>
<td>
<form:input path="age" />
</td>
</tr>
<tr>
<td>
<form:label path="isAdmin">
<spring:message text="Is admin"/>
</form:label>
</td>
<td>
<form:input path="isAdmin"/>
</td>
</tr>
<tr>
<td colspan="2">
<c:if test="${!empty user.name}">
<input type="submit"
value="<spring:message text="Edit"/>" />
</c:if>
<c:if test="${empty user.name}">
<input type="submit"
value="<spring:message text="Add"/>" />
</c:if>
</td>
</tr>
</table>
</form:form>
<br>
<h3>Users list</h3>
<table class="tg">
<tr>
<th width="80">ID</th>
<th width="120">Name</th>
<th width="120">Age</th>
<th width="60">IsAdmin</th>
<th width="120">Created date</th>
<th width="60">Edit</th>
<th width="60">Delete</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.age}</td>
<td>${user.isAdmin}</td>
<td>${user.createdDate}</td>
<td><a href="<c:url value='/edit/${user.id}' />" >Edit</a></td>
<td><a href="<c:url value='/remove/${user.id}' />" >Delete</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
UserController
package com.mihusle;
import com.mihusle.model.User;
import com.mihusle.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Created by MHSL on 16.06.2017.
*/
#Controller
public class UserController {
private UserService userService;
#Autowired
#Qualifier("userService")
public void setUserService(UserService userService) {
this.userService = userService;
}
#RequestMapping(value = "/users", method = RequestMethod.GET)
public String showUsersList(Model model) {
model.addAttribute("user", new User());
model.addAttribute("users", userService.getUsers());
return "user";
}
#RequestMapping(value = "/user/add", method = RequestMethod.POST)
public String addUser(#ModelAttribute("user") User user) {
if (user.getId() == 0) {
userService.addUser(user);
} else {
userService.updateUser(user);
}
return "redirect:/users";
}
#RequestMapping("/remove/{id}")
public String removeUser(#PathVariable("id") int id) {
userService.removeUser(id);
return "redirect:/users";
}
#RequestMapping("/edit/{id}")
public String editUser(#PathVariable("id") int id, Model model) {
model.addAttribute("user", userService.getUserById(id));
model.addAttribute("users", userService.getUsers());
return "user";
}
}
UserDAOImpl
package com.mihusle.dao;
import com.mihusle.model.User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.List;
/**
* Created by MHSL on 16.06.2017.
*/
#Repository
public class UserDAOImpl implements UserDAO {
private static final Logger LOGGER = LoggerFactory.getLogger(UserDAOImpl.class);
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
#Override
public void addUser(User user) {
Session session = sessionFactory.getCurrentSession();
Calendar calendar = Calendar.getInstance();
Timestamp currentTime = new Timestamp(calendar.getTimeInMillis());
user.setCreatedDate(currentTime);
session.persist(user);
LOGGER.info(user + " was added successfully");
}
#Override
public void updateUser(User user) {
Session session = sessionFactory.getCurrentSession();
session.update(user);
LOGGER.info(user + " was updated successfully");
}
#SuppressWarnings("unchecked")
#Override
public List<User> getUsers() {
Session session = sessionFactory.getCurrentSession();
List<User> users = session.createQuery("FROM User").list();
users.forEach(user -> LOGGER.info(user + " is in the list"));
return users;
}
#Override
public User getUserById(int id) {
Session session = sessionFactory.getCurrentSession();
User user = session.load(User.class, id);
LOGGER.info(user + " was loaded successfully");
return user;
}
#Override
public void removeUser(int id) {
Session session = sessionFactory.getCurrentSession();
User user = session.load(User.class, id);
if (user != null)
session.delete(user);
LOGGER.info(user + " was deleted successfully");
}
}
User
package com.mihusle.model;
import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;
/**
* Created by MHSL on 16.06.2017.
*/
#Entity
#Table(name = "user", schema = "test")
public class User {
private int id;
private String name;
private Integer age;
private Boolean isAdmin;
private Timestamp createdDate;
#Id
#Column(name = "id", nullable = false)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "name", nullable = true, length = 25)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "age", nullable = true)
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
#Basic
#Column(name = "isAdmin", nullable = true, columnDefinition = "BIT", length = 1)
public Boolean getIsAdmin() {
return isAdmin;
}
#Column(name = "isAdmin", columnDefinition = "BIT", length = 1)
public void setIsAdmin(Boolean admin) {
isAdmin = admin;
}
#Basic
#Column(name = "createdDate", nullable = true)
public Timestamp getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Timestamp createdDate) {
this.createdDate = createdDate;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User that = (User) o;
return id == that.id &&
Objects.equals(name, that.name) &&
Objects.equals(age, that.age) &&
Objects.equals(createdDate, that.createdDate);
}
#Override
public int hashCode() {
return Objects.hash(id, name, age, createdDate);
}
#Override
public String toString() {
return "User{" +
"id = " + id +
", name = '" + name + '\'' +
", age = " + age +
", isAdmin = " + isAdmin +
", createdDate = " + createdDate +
'}';
}
}
I have no idea where the problem may be, so if you need more code, I'm ready to write it. Thanks
I solved this. I had to add <form:hidden path="id" /> to the id input field. I suppose I need to do the same with createdDate field.
I have an issue with form processing using Thymeleaf and Spring-MVC.
This is my view:
<html xmlns:th="http://www.thymeleaf.org">
<head>
</head>
<body>
<div class="container" id="containerFragment" th:fragment="containerFragment">
<form
action="#"
th:action="#{/search}"
th:object="${searchInfo}"
method="post" >
<fieldset id="search-query">
<input
type="text"
name="search"
value=""
id="search"
placeholder="Search for user"
required="required"
th:value="*{searchQuery}" />
<input
type="submit"
value="Search"
name="submit"
class="submit"/>
</fieldset>
</form>
</div>
</body>
</html>
this is my controller:
/** Search form */
#RequestMapping(value = "/search", method = RequestMethod.GET)
public String search(Model model) {
model.addAttribute("searchInfo", new SearchForm());
return "search";
}
/** Search form */
#RequestMapping(value = "/search", method = RequestMethod.POST)
public ModelAndView search(BindingResult result,
#Valid #ModelAttribute("searchInfo") SearchForm searchForm) {
String login = searchForm.getSearchQuery();
User user = userService.findUserByLogin(login);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("search-results");
modelAndView.addObject("user", user);
return modelAndView;
}
and the search form is:
public class SearchForm {
String searchQuery;
public String getSearchQuery() {
return searchQuery;
}
public void setSearchQuery(String searchQuery) {
this.searchQuery = searchQuery;
}
#Override
public String toString() {
return "SearchForm [searchQuery=" + searchQuery + "]";
}
}
The issue is that login is null at this point of controller:
String login = searchForm.getSearchQuery();
It looks like a new SearchForm object created for POST method, but there are already one, which was created at GET step and should contains the search query.
I can't understand such behaviour.
Spring should map HTML form attributes to your model: SearchForm.
Spring MVC build accordions with request parameters and your model object properties and set matching properties into your model Object before pass object into your controller method.
You named HTML property(and request parameter name automatically) as id="search". But SearchForm hasn't such property. Instead it has searchQuery property. So after Spring MVC unable to set searchQuery value into your SearchForm it pass model with null attribute.
Please Change th:value="{searchQuery}" to th:field="{searchQuery}".
I hope it'll work.
It worked for me:
FormTestController.java
#Controller
public class FormTestController {
#RequestMapping(value = "/form-test-1.jhtml", method = RequestMethod.GET)
public String formTest1(#ModelAttribute("form1") Form1TestVO form1TestVO, Model model){
System.out.println("You've submited: " + form1TestVO.getName())
model.addAttribute("form1", new Form1TestVO("Form 1 test"));
return "form-test-1";
}
}
form-test-1.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.thymeleaf.org" >
<head>
<title>Form test 1</title>
</head>
<body >
<form th:object="${form1}" th:action="#{/form-test-1.jhtml}" >
<input th:field="*{name}" />
<button>Send</button>
</form>
</body>
</html>
Form1TestVO
public class Form1TestVO {
private String name;
public Form1TestVO() {
}
public Form1TestVO(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Reference