#RequestParam custom object - spring-mvc

I use Spring MVC 3.1 in my app. Say I have a methods in controller as follows:
#RequestMapping(value = "/assignUser", method = RequestMethod.GET)
public String assignUserToCompany(ModelMap map){
List<CompanyDetails> companies = //companies list from DAO
List<UserDetails> users = //users list from DAO
map.addAttribute("companiesList",companies);
map.addAttribute("usersList",users);
return "someView";
}
#RequestMapping(value = "/assignUser", method = RequestMethod.POST)
public String assignUserToCompany(#RequestParam("user")UserDetails user,
#RequestParam("company")CompanyDetails company){
if(user!=null && company!=null){
// some operations with entities
}
return "someView";
}
and I have a form on the view side:
<form method="post" action="assignUser.html">
<label for="select-users"><spring:message code="assignUser.label.users"/> </label>
<select id="select-users" name="user">
<c:forEach items="${usersList}" var="user">
<option value="${user}">${user.firstName} ${user.legalName}</option>
</c:forEach>
</select>
<label for="select-companies"><spring:message code="assignUser.label.companies"/> </label>
<select id="select-companies" name="company">
<c:forEach items="${companiesList}" var="company">
<option value="${company}">${company.name}</option>
</c:forEach>
</select>
<input type="submit" value="<spring:message code="assignUser.label.submit"/>"/>
</form>
I want to pass object I select in input as request parameters and perform some operations with them but standart #RequestParam permit me only primitive types and wrappers as we know.
Can I customize this in order to pass my objects? Thank you.

If the pojo relates directly to a form,decalre a spring form in your jsp (assuming yourDTO has a property name...
<form:form id="yourForm" commandName="yourDTO" action="Save" method="POST">
<form:input path="name" maxlength="90" cssStyle="width: 650px;" id="name"/>
and your controller :
#RequestMapping(value = "/Save", method = RequestMethod.POST)
public ModelAndView save(final yourDTO yourDTO) {
Or if converting one field to a complex class you will have to provide a conversion service :
#Component
public class FooConverter implements Converter<String, Foo> {
#Override public Foo convert(String source) {
//do covnersion from string to Foo
Foo foo = new Foo(source)
return Foo;
}
}
and register it
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.yourcompany.controller.converters.FooConverter"/>
</set>
</property>
</bean>

Related

Spring4 Form Validation

I have a situation similar to the followa:
public class Shop {
#NotNull
String name;
#NotNull
String desc;
}
a button to show a form where I have to insert my user:
<form:form method="post" action="saveShop.html" modelAttribute="Shop">
<form:label path="name">Name:</form:label>
<form:input path="name" value="${shop.name}" />
<form:label path="desc">desc:</form:label>
<form:input path="desc" value="${shop.desc}" />
<input type="submit" value="Submit"/>
</form:form>
Controller:
#RequestMapping("/addShop")
public ModelAndView LoadFormPage(#ModelAttribute("Shop")Shop shop) {
ModelAndView model = new ModelAndView();
model.setViewName("/shop/addShop");
return model;
}
#RequestMapping(value = "/saveShop", method = RequestMethod.POST)
public ModelAndView saveShop(#Valid #ModelAttribute("Shop") Shop shop, BindingResult result) {
if (result.hasErrors()) { *do some*
} else { *do someelse* }
}
Even if I leave all fields blank (I have tried even with different data type) and submit the form the controller never recognize errors.
Can you help me?
Make sure to add below configs.
<bean id="myBeansValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
and
<mvc:annotation-driven validator="myBeansValidator">
and
<!-- Hibernate Validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version>
</dependency>
Adapted from Spring MVC form validation not working

Need to pass object from one controller to another controller

I am having 2 controllers in my class :-1st controller return to a jsp page , in that jsp i am using a form ,on submitting that form it calls 2nd controller . I want to pass one object from 1st controller to 2nd controller and dont want to send that object to intermediate jsp page so is there any way to do this .I dont want to use session attribute also
this is my 1st controller
#RequestMapping(value = "/login", method = RequestMethod.GET)
public static String login(final Model model) {
final Studentdata studentdata = new Studentdata();
studentdata.setName("username");
return "Login" ;
}
this is my Login.Jsp
<form action="/loungeHotel/checkLogin" method="post">
<input type="submit" value="submit">
</form>
this is 2nd controller
#RequestMapping(value = "/checkLogin", method = RequestMethod.POST)
public static String checkLogin(final Model model) {
System.out.println("here i want to access studentdata");
return "MyAccount";
}
I think HttpSession is the right choice.
If you don't want to use HttpSession or any server storage such as Database, ... You can use this way - Client storage by using hidden inputs
Modify login to store studentdata in request attribute
#RequestMapping(value = "/login", method = RequestMethod.GET)
public static String login(HttpServletRequest request, final Model model) {
final Studentdata studentdata = new Studentdata();
studentdata.setName("username");
request.setAttribute("studentData", studentdata);
return "Login" ;
}
Modify login jsp
<form action="/loungeHotel/checkLogin" method="post">
<!-- Write all studentdata Properties as Hidden inputs -->
<input type="hidden" name="property1" value="${studentData.property1}"
<input type="hidden" name="property2" value="${studentData.property2}"
<input type="hidden" name="property3" value="${studentData.property3}"
<input type="submit" value="submit">
</form>
Modify checkLogin
RequestMapping(value = "/checkLogin", method = RequestMethod.POST)
public static String checkLogin(HttpServletRequest request, final Model model) {
System.out.println("here i want to access studentdata");
// Recreate StudentData From request.getParameter(...)
Studentdata studentdata = new Studentdata();
studentdata.setProperty1 ( request.getParameter("property1"));
// ... You may have to convert data too
return "MyAccount";
}

Mapping Multiple Controllers in Spring MVC

Define two controllers user and data as follows:
// 1st Controller
#Controller
#RequestMapping(value = {"/", "user"})
public class UserLoginController {
#Autowired
private UserLoginService userLoginService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String showLoginForm(#ModelAttribute UserLogin userLogin) {
//model.addAttribute(new UserLogin());
//System.out.println("showLoginForm() is called");
return "loginForm";
}
}
//Second COntroller
#Controller
#RequestMapping(value = "user/data/")
public class WorkplanController {
#Autowired
private WorkplanService WorkplanService;
#RequestMapping(value = "importForm", method = RequestMethod.GET)
public ModelAndView importForm(#ModelAttribute SheetUpload sheetUpload){
return new ModelAndView("uploadWorkplan");
}
#RequestMapping(value= "doUpload", method = RequestMethod.POST)
public ModelAndView doUpload(#RequestParam CommonsMultipartFile[] uploadFile, SheetUpload fileUpload, Workplan workplan, HttpServletRequest request) {
return new ModelAndView("uploadSucess");
}
}
When i make request to the doUpload(), it shows HTTP Status 400 Error.
My question is two-fold:
1. Why do have i have to include the user like this: #RequestMapping(value = "user/data/") to make request to the 2nd controller why not like this #RequestMapping(value = "data/")?
2. What do i need to change to make a successful call to the 2nd method in the second controller?
Here is the form am trying to submit:
<form:form action="doUpload" modelAttribute="sheetUpload" method="post"
enctype="multipart/form-data">
<form:select class="createusers_select_menu" path="From">
<form:option value="">Select...</form:option>
<form:option value="A">A</form:option>
<form:option value="B">B</form:option>
<form:option value="C">C</form:option>
</form:select>
<form:input class="browse_btn" path="uploadFile" type="file" />
<input type="submit" class="selct_workplan_2_btn" name="" value=" "/>
</form:form>
Why do have i have to include the user like this: #RequestMapping(value = "user/data/") to make request to the 2nd controller why not like this #RequestMapping(value = "data/")?
You don't have to. Change it to #RequestMapping(value="/data")
What do i need to change to make a successful call to the 2nd method in the second controller?
Try to get it working with a single file field only, then report back. There are lots of tutorials on the web to show how to upload files with Spring.

spring mvc multiple value selection drop down. The values being the domain objects. How to implement this

The below code is for single value selection which is working absolutely fine. But when I add attribue multiple="true" to form:select tag, then country object parameter in save() method is having null value when I select multiple value in Jsp. What will be the change that I have to do in jsp so that I can get the list of country objects in controller method. Please advise.
JSP Code
<form:form modelAttribute="country">
<li>
<form:label cssClass="mandatory" path="state">Select State</form:label>
<form:select path="state" cssErrorClass="error">
<form:option value="" label="Please Select..." />
<!-- Collection<State> listOfStates; This value holds the list of State objects by using controller method.-->
<c:forEach items="${listOfStates}" var="s">
<form:option value="${s.stateUniqueCode}" label="${s.stateName}"/>
</c:forEach>
</form:select>
</li>
</form>
Controller method
#RequestMapping(params = "_save", method = RequestMethod.POST)
public ModelAndView save(#ModelAttribute("country") Country country, BindingResult result, SessionStatus status) {
//some busines logic....
return new ModelAndView(mavString.toString());
}
Country and state classes
_________________________
/** Country object**/
public class Country{
private State state;
//getter and setters
}
/** State object**/
public class State{
private long stateUniqueCode;
private String stateName;
//getter and setters
}
If I convert country variable to List country in Country class. How should be the jsp and controller method be changed.
As per given jsp your model(Java classes of Country and state should be as follows)
public class Country{
private List<State> stateList;
//getter and setters
}
/** State object**/
public class State{
private long stateUniqueCode;
private String stateName;
//getter and setters
}
and you should bind stateList attribute in your path as follows.
<form:form modelAttribute="country">
<li>
<form:label cssClass="mandatory" path="stateList">Select State</form:label>
<form:select path="stateList" cssErrorClass="error">
<form:option value="" label="Please Select..." />
<c:forEach items="${listOfStates}" var="s">
<form:option value="${s.stateUniqueCode}" label="${s.stateName}"/>
</c:forEach>
</form:select>
</li>

Spring3 MVC - how to impliment CRUD correctly on the same controller?

I am trying to create simple CRUD controller and view using Spring mvc.
I am able to:
Get the document list
Upload document
Deleted Document
If I would like to send the request using FORM,
How do i implement Download Document?
Should I use for every document?
Another thing - am i using the MVC framework correctly?
<html>
<body>
<!-- the list: -->
<c:forEach items="${documentList}" var="documentRow">
<Generate table here>
<!-- upload part -->
<form:form modelAttribute="uploadDocument" method="post" enctype="multipart/form-data">
<form:input path="fileData" type="file"/>
<input type="hidden" id="actUploadocument" name="action" value="uploadDocument" />
</form:form>
<!-- delete part -->
<form:form method="post" enctype="multipart/form-data">
<input type="hidden" id="documentId" value="" />
<input type="hidden" id="actUploadocument" name="action" value="deleteDocument" />
</form:form>
</body>
</html>
The CRUD controller?
#Controller
#RequestMapping("/documents")
public class DocumentsController
{
#Autowired
private MainService mainService;
#RequestMapping(method = RequestMethod.GET)
public String listDocuments(Model model) {
List<Document> docs = mainService.getAllDocuments();
model.addAttribute("documentList",docs);
model.addAttribute(new UploadDocument());
return "admin/documents";
}
#RequestMapping(method = RequestMethod.POST , params="action=uploadDocument")
public String uploadDocument(UploadDocument uploadDocument){
savedocument(uploadDocument);
return "redirect:/admin/documents.do";
}
#RequestMapping(method = RequestMethod.POST , params="action=removeDocument")
public String removeDocument(#RequestParam(value="documentId", required=true) String documentId){
savedocument(documentId);
return "redirect:/admin/documents.do";
}
#RequestMapping(method = RequestMethod.POST , params="action=downloadDocument")
public String downloadDocument(#RequestParam(value="documentId", required=true) String documentId,
HttpServletRequest request,HttpServletResponse response ) {
writeDocToResponse(documentId,response);
return null;
}
Basically all you need to open file download dialog is a set response properties to identify HTTPresponce as attachment.
For instance:
response.reset();
response.setContentType(getYourFileContentType());
response.setHeader("Content-Disposition","attachment; filename=\""+getYourFileName()+"\"");
Then you may call your service method to stream file.

Resources