Need to pass object from one controller to another controller - spring-mvc

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";
}

Related

Pass a simple ViewModel from a View to a Controller via hidden field

I am trying to pass a simple object containing only one field (a DateTime) from my view back to my controller.
I have a ViewModel that looks like this:
public class TheViewModel
{
public DateTime StartTime { get; set; }
}
I have a controller post method that looks like this
[HttpPost]
public async Task<ActionResult> StartNew(TheViewModel viewModel)
{
....
}
In my view, my model is set to TheViewModel, and I am trying to simply send the same value for the StartTime field of the ViewModel back to the Controller:
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.StartTime, new { id = "StartTimeField" })
<input type="submit" value="Start" />
}
However, the value of the StartTime field is always the default date time. I have verified that this is not the value for the time sent to the view (by looking at the page source)
What am I mnissing?
Why are you creating a new object inside the HtmlFor? Why not just #Html.HiddenFor(m=>m.StartTime) ?

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.

Multiple buttons in the same form

I have one simple form with two buttons inside. Each button has to redirect me on different view in my controller. I was looking for some examples over the net, found solutions and implemented them. Unfortunately, it isn't working for me.
Controller:
public class HomeController : Controller
{
private MovieEntities db = new MovieEntities();
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
[Button(ButtonName = "clickButton", ButtonValue = "Send")]
public ActionResult Send()
{
return View();
}
[HttpPost]
[Button(ButtonName = "clickButton", ButtonValue = "Reset")]
public ActionResult Reset()
{
return View();
}
}
Index view:
#model IEnumerable<CustomWizzardMVC.Models.MovieInfo>
#{
ViewBag.Title = "Home";
}
<h1>Insert informations</h1>
#using(Html.BeginForm())
{
<input type="button" name="clickButton" value="Send" />
<input type="button" name="clickButton" value="Reset" />
}
Send and Reset view are just simple views with <p> tags inside.
I have Button class too:
public class Button : ActionNameSelectorAttribute
{
public string ButtonName { get; set; }
public string ButtonValue { get; set; }
public override bool IsValidName(ControllerContext controllerContext, string actionName, System.Reflection.MethodInfo methodInfo)
{
return controllerContext.HttpContext.Request[ButtonName] != null && controllerContext.HttpContext.Request[ButtonName] == ButtonValue;
}
}
What am I doing wrong in here? Also, if you know some other way to do the same functionality without using jQuery, please post some code :)
You can configure a form's target by it's action attribute.
So you can do this by changing your form's action attribute. You need to use client side script to do that.
An another option, you can send a value that contains user's option (like Option = "reset" or Option = "send"). And decide what view you need to go in your default view.
Change your input type="button" to type="submit.
<input type="button" /> buttons will not submit a form - they don't do anything by default. They're generally used in conjunction with JavaScript as part of an AJAX application.
<input type="submit"> buttons will submit the form they are in when the user clicks on them, unless you specify otherwise with JavaScript.
Found how it can be done. <input type="submit" value="Send" formaction="#Url.Action("Send","Home")" /> Just found out that formaction is the new HTML5 attribute that specifies the URL of the form for the HttpPost action. :)

Reading in RouteValues to Controller

so I have a Url Action
Create new teacher & assign to account.
That passes in two routeValues: createAndAssign, and teacherID.
Now when I go to my Teacher/Create page, my URL is like so:
.../Teacher/Create?createAndAssign=True&teacherID=ea817321-5633-4fdc-b388-5dba2c4a728e
Which is good, I want this. Now when I POST to create my teacher, how do I grab createAndAssign and teacherID value?
You can set the Querystring value in a hidden variables in the form and render in your GET action method and accept that in your POST action method.
View rendered by your GET Action
#using (Html.BeginForm())
{
//Other form elements also
#Html.Hidden("teacher",#Request.QueryString["teacherID"] as string)
#Html.Hidden("createAndAssign",#Request.QueryString["createAndAssign"]
as string)
<input type="submit" />
}
and now have a teacher parameter and createAndAssign parameter in your HttpPost action method so that it will be available when you submit the form.
[HttpPost]
public ActionResult Create(string teacher,string createAndAssign)
{
//Save and Redirect
}
If your view is strongly typed (which is my personal preference), it is quite easy,
public ActionResult GET(string teacherID,string createdAndAssing)
{
var yourVMObject=new YourViewModel();
yourVMObject.TeacherID=teacherID;
yourVMObject.CreateAndAssign=createdAndAssing;
return View(createdAndAssing);
}
and in your strongly typed view,
#model YourViewModel
#using (Html.BeginForm())
{
//Other form elements also
#Html.HiddenFor(x=>x.TeacherID)
#Html.HiddenFor(x=>x.CreateAndAssign)
<input type="submit" />
}
And in your POST action
[HttpPost]
public ActionResult Create(YourViewModel model)
{
//look for model.TeacherID
//Save and Redirect
}
you can get the value from the query string or as params of the controller like
var x =Request.QueryString["createAndAssign"];
or
public ActionResult Create(bool createAndAssign, string teacherID){
return View();
}

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