I started to working on thymeleaf, so after submitting the form I end up getting this URL:
URL
http://localhost:8080/submit?name=xyz&age=20&dropdown=male
so how should I get the value of individual elements to java controller?
In java part, I should be able to load them into their respective datatypes.
To grab GET parameters (URL parameters), use request.getParameter
String name = request.getParameter("name");
String age = request.getParameter("age");
String dropdown = request.getParameter("dropdown");
Note that these are all strings, if you want other datatypes you will need to parse them and handle any errors.
So, yes later I was able to solve it
Step1Create an HTML plage GetDetails.HTML
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Details</title>
</head>
<body>
<form action="#" th:action="#{PATH OF ACTION}" method="get" th:object="${details}">
<input type="text" name="name" th:field="*{name}"/>
<input type="text" name="age" th:field="*{age}"/>
<select name="option" th:field="*{option}">
<option value="male">male</option>
<option value="female">female</option>
</select>
<input type="submit" value="search"/>
</form>
</body>
</html>
Step2 Create a Model class in java (POJO)
class Details{
private String name;
private int age;
//getters and setters
//constructors
}
NOTE: Class name must be same as the object name given in HTML page
Step3 Controller part in Java
#RequestMapping("/")
public String search(Model model){
model.addAttribute("details", new Details());
return "GetDetails";
}
Step4 REST controller
#GetMapping(value = "PATH OF ACTION")
public List<Details> getAll(#ModelAttribute Details details) {
// Business service
}
Related
I have two hidden input fields to implement Friend system. I pass user and friend's ids in Model and then use them in thymeleaf page to pass them in form to PostMapping and save changes. However, PostMapping cannot see my second #RequestParam.
Both customer and friend are properly passed to model as I tried to output them on website using th:text
Snippets of code:
Adding both users to model:
#GetMapping("/customer/{customerId}")
public String getCustomer(Model theModel, #PathVariable int customerId, #AuthenticationPrincipal MyUserDetails user) {
Customer currUser = customerService.findById(user.getCustomer().getId());
Customer foundCustomer = customerService.findById(customerId);
theModel.addAttribute("friend", foundCustomer);
theModel.addAttribute("customer", currUser);
return "customerdetails";
Snippet of Thymeleaf code:
<form action="#" th:action="#{/home/addFriend}" th:object="${friend}" method="post">
<input type="hidden" th:field="${friend.id}" th:attr="name='friendId'" />
<input type="hidden" th:field="${customer.id}" th:attr="name='customerId'" />
<input type="submit" value="Add Friend" class="btn btn-primary flex-grow-1" />
</form>
PostMapping (where issue occurs):
#PostMapping("/addFriend")
public String getPost(#RequestParam("friendId") int friendId, #RequestParam("customerId") int customerId) {
Customer friendCustomer = customerService.findById(friendId);
Customer currCustomer = customerService.findById(customerId);
System.out.println(currCustomer.getFirstName());
System.out.println(friendCustomer.getFirstName());
return "redirect:/home";
}
Code of error:
[org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'friendId' for method parameter type int is not present]
It will be a lot easier to implement using a custom form object.
For example, create this class:
public class AssignFriendFormData {
private String friendId;
private String customerId;
// getter and setters here
}
Use this in your #GetMappping:
#GetMapping("/customer/{customerId}")
public String getCustomer(Model theModel, #PathVariable int customerId, #AuthenticationPrincipal MyUserDetails user) {
Customer currUser = customerService.findById(user.getCustomer().getId());
Customer foundCustomer = customerService.findById(customerId);
AssignFriendFormData formData = new AssignFriendFormData();
formData.setFriendId(foundCustomer.getId());
formData.setCustomerId(currUser.getId());
theModel.addAttribute("formData", formData);
return "customerdetails";
Change the form to this:
<form action="#" th:action="#{/home/addFriend}" th:object="${formData}" method="post">
<input type="hidden" th:field="*{friendId}" />
<input type="hidden" th:field="*{customerId}" />
<input type="submit" value="Add Friend" class="btn btn-primary flex-grow-1" />
</form>
Finally, update the #PostMapping to use the form data object:
#PostMapping("/addFriend")
public String getPost(#Valid #ModelAttribute("formData") AssignFriendFormData formData) {
Customer friendCustomer = customerService.findById(formData.getFriendId());
Customer currCustomer = customerService.findById(formData.getCustomerId());
System.out.println(currCustomer.getFirstName());
System.out.println(friendCustomer.getFirstName());
return "redirect:/home";
}
See Form handling with Thymeleaf for a more in-depth tutorial on this.
I am having some trouble getting form data in my controller when the form in my jsp contains the attribute enctype="multipart/form-data" . The attribute is needed because i am uploading a file. I simplified my code to make it easier to understand but assume I have the following.
My model:
public class EmployeeUpdateForm {
private String name;
private ContactInfo info;
//standard getters and setters
}
public class ContactInfo {
private String streetName;
private MultipartFile image;
//standard getters and setters
}
My controller is
#Controller
public class EmployeeController {
#RequestMapping(value = "/employee", method = RequestMethod.GET)
public ModelAndView showForm() {
//assume this sends you to updateEmployee.jsp
}
#RequestMapping(value = "/submit", method = RequestMethod.POST)
public String submit(#ModelAttribute("EmployeeUpdateForm")EmployeeUpdateForm form ) {
//here I expect form.getInfo().getStreetName() and form.getInfo().getImage() to return something but they are both null values.
}
}
updateEmployee.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
</head>
<body>
<h3>Update Employee Details</h3>
<form:form action="submit" method="post" enctype="multipart/form-data" id="EmployeeUpdateForm" modelAttribute="EmployeeUpdateForm">
<div>
Street Name: <form:input path="info.streetName" />
</div>
<div>
New Image: <form:input type="file" path="info.image"/>
</div>
</form:form>
</body>
</html>
When I submit my form and check the value of form.getInfo().getStreetName() and form.getInfo().getImage() within submit() in my controller, both values are null.
However if I remove method="post" enctype="multipart/form-data" from my form in jsp and also remove <form:input type="file" path="info.image"/> from my jsp and then proceed to submit, if I do form.getyInfo().getStreetName() it returns the value I filled in.
How do I get form data in my controller when the form in my jsp has the attribute method="post" enctype="multipart/form-data"??
A resolver was missing. Adding
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
fixed the issue.
I am working on a usecase to upload student details along with his image in spring boot. The entity class looks like
below.
public class Student{
private int rollNo;
private String name;
// few more fields
#Lob
private byte[] picture;
// getters setters
}
JSP file
<!DOCTYPE html>
<html>
<head>
<title>Student Registration</title>
</head>
<body>
<form action="save" method="post" enctype="multipart/form-data">
<input type="text" name="rollNo"/>
<input type="text" name="name"/>
<!-- some more fields -->
<input type="file" name="picture"/>
<input type="submit" value="Registration">
</form>
</body>
</html>
How should i handle the form data in my controller method? In a nutshell how to write controller method to handle both form data and image?
the very basic idea could be as follows
#RestController
public class ImageUploadController {
#RequestMapping(value="/upload", method=RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Object> uploadFile(#RequestParam(required=true, value="picture") MultipartFile file, #RequestParam(name = "rollNo") String rollNo, #RequestParam(name = "name") String name) {
}
}
I have a page where I get a list of entries. Now, I want to be able to search from those list.
my current url for retrieving list is this /show/products. I want to add a search form in this page so that I can search with request parameter.
Yes, I can use ajax but I have to do it with request parameters.
So if I search for a product name, then - /show/products?name=someName
<form ui-jp="parsley" th:action="#{/show/products(name=${pName})}" th:object="${pName}" method="get">
<div class="row m-b">
<div class="col-sm-6">
Search by Name:
<input id="filter" type="text" th:field="*{pName}" class="form-control input-sm w-auto inline m-r"/>
<button class="md-btn md-fab m-b-sm indigo">
<i class="material-icons md-24"></i>
</button>
</div>
</div>
</form>
And this is what I tried in controller:
#GetMapping("/show/products")
public String getProduct(Model model,
#RequestParam(required = false) String name,
#ModelAttribute String pName) {
List<Product> products = this.productService.getAllProducts(name)
model.addAttribute("products", products);
return "show_product";
}
I am getting this error:
Neither BindingResult nor plain target object for bean name 'pName' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153)
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:897)
You are trying to use variable pName (Model attribute) as a form object.
In your view you are passing a model attribute to form like this th:object="${pName}" but instead you need to pass a form object.
A form object is not a class but rather a simple java object (POJO). You can think of form object as your form but on server side.
Before you can use form object in your view, you need to create it and add it to the Model.
you will define it like this
public class MyFormObject{
private String pName;
public String getPName(){
return pName;
}
public void setPName(String pName){
this.pName = pName;
}
}
now your controller method will become
#GetMapping("/show/products")
public String getProduct(Model model,
#ModelAttribute("myFormObject") MyFormObject myFormObject,
BindingResult result) {
List<Product> products = this.productService.getAllProducts(myFormObject.getPName());
model.addAttribute("products", products);
return "show_product";
}
Then you can pass the form object to your form like this
<form ui-jp="parsley" th:action="#{/show/products}" th:object="${myFormObject}" method="get">
<div class="row m-b">
<div class="col-sm-6">
Search by Name: <input id="filter" type="text" th:field="*{pName}" class="form-control input-sm w-auto inline m-r"/>
<button class="md-btn md-fab m-b-sm indigo"><i class="material-icons md-24"></i></button>
</div>
</div>
</form>
You need to read the documentation, all these are explained there in detail.
I used angular in my jsp page but I'm confused how to bind values to inputbox
Here My is my Controller
#RequestMapping(value="/customer" , method = RequestMethod.GET)
public String getCustomerPage(Model model,HttpSession session){
CustomerBean customerBean = getCustomerById(id);
model.addAttribute("customer", customerBean);
return "addCustomer"
}
My jsp code
<input type="text" name="customerName" value="${customer.name}" ng-model="cust.name" required/>
Unable to bind value
But if i removed ng-model then value bind to control
i.e
<input type="text" name="customerName" value="${customer.name}" required/>
this works
Help!