How to call JSP from a java Controller - spring-mvc

I have a simple J2EE application with Spring.
Now I want from Java controller call another page. For example, I'm in registrazione.jsp, I click on one button, and I call a method in registrazioneController.java.
Now I want from registrazioneController.java, call another page, for example
home.jsp and I want pass any parameter in get.
It is possible?
this is the method that I use when I click the button
registrazioenControlle.java
public ModelAndView internalLoadPage(HttpServletRequest request, HttpServletResponse response, Map model) throws Exception
{
//to do
//call another page for example home.html
request.getRequestDispatcher("home.jsp").forward(request, response);
return new ModelAndView("home", model);
}
I'm try to use this code but no found.

In addition to the answer provided in the comments, you can also use RedirectAttributes, and addAttribute method if you want to append a parameter to URL upon redirect. This will also give you the addFlashAttribute that will store the attributes in the flash scope which will make it available to the redirected page. You can also return a simple string as the view name e.g. like
public String internalLoadPage(RedirectAttributes redirectAttributes) throws Exception
{
redirectAttributes.addAttribute("paramterKey", "parameter");
redirectAttributes.addFlashAttribute("pageKey", "pageAttribute");
return "redirect:/home";
}
this assumes that the view suffix is configured in you view resolver configuration

Related

Spring mvc: is there a way to call another controller, get the response and fill it to a model attribute?

I have two mvc style endpoints returning templatefile names as view names, in the same classpath: /source and /target. The source_template has a variable which needs to be filled by contents of another template, say target_template.
#RestController
class SomeController {
#GetMapping("/source")
public String source(Model model) {
model.addAttribute("attr1", /*call endpoint /target and add the response of parsed template 'target_template' here */);
return "source_template";
}
#GetMapping("/target")
public String target(Model model) {
model.addAttribute("attr2", "good");
//may be continue the nested invocation n number of times
return "target_template";
}
}
given the source_template.html:
Hai, $attr1
and the target_template.html:
this has been a $attr2 day
having said, i invoke the url /source, I should get "Hai, this has been a good day".
I can just call the target() method directly, but that would not render the template. Or I should directly use the templating engine apis to link the template file, put the context object, parse the template and return the string , which defeats the whole purpose of spring mvc. Or I can use resttemplate, but that requires an absolute url, and performance would take a hit. So, is there any other way to do it ?

Return spring mvc Model on Ajax response

I am having a controller that return model objects like below
model.addAttribute("list", list);
When i click a button ajax call happens and it is goes to controller executing everything and it returns. But i don't know how to access this model object in my jsp on ajax response. When i use alert for success ajax response , I am just seeing a html kind of page.
Please give me some example or reference to achieve this
Thanks in advance
Please find my sample code snippet
Controller.java
#RequestMapping(value='/ajax' value="POST")
Public #ResponseBody String displayDropdown(MyForm myform,Model model) {
//logic to fetch details from DB
List<String> list = fetchFromDB();
model.addAttribute("list" list);
return "ajaxResponse";
}
My JSP
In a button click, having the below ajax call
$.ajax {
url:'/ajax',
type:'POST',
data: $("#myform").serialize();
success:function(data) {
alert(response);
}
}
I want to get my model from this ajax response and use it in my jsp.
I am not sure, but from JSP all model attribute variables are accessible simply using ${attribute_name}. In your case it is ${list}
Maybe you can use
console.info(model)
I am not sure that you can access response with JSP. JSP is the server side and response you receive when the page is already sent to client. The only thing you can try is to use COOKIES. Set response in cookies and then access it from the server.
Yes You can easily get Model data from controller, simply
#RequestMapping(value='/ajax' value="POST")
Public String displayDropdown(MyForm myform,Model model) {
//logic to fetch details from DB
List<String> list = fetchFromDB();
model.addAttribute("list" list);
return "yourjsppage";
}
$.ajax {
url:'/ajax',
type:'POST',
data: $("#myform").serialize();
success:function(data) {
$("#page-wrapper").html( data );
}
}
page-wrapper is your content div in jsp page. this returns all jsp page including your model. in this scenario it is also useful when you want (partial rendering) not wanting to refresh whole page but targeting specific page.

RequestMapping in Controller in Spring MVC in getting changed sometimes

I am trying to implement Spring MVC in my web application and I have a controller class.
#Controller<br>
public class ContactController {
#Autowired<br>
private ContactService contactService;
#RequestMapping("/login")
public String displayLoginPage(HttpServletRequest httpReq, #ModelAttribute("login") Login login, BindingResult result){
return "login";
}
/*Spring will automatically calls this method whenever it encounters "/home" url in request.*/
#RequestMapping("/login/home")
public String displayHomePage(HttpServletRequest httpReq, Map<String, Object> map){
map.put("contact", new Contact());
map.put("contactList", contactService.listContact());
return "contact";
}}
After launching the application, login screen comes up and then upon click of button, I am observing that value for RequestMapping is getting changed sometimes. Sometimes it is "/login/home" or sometimes it is "/home". Why this is not constant ? Is there any way so that I may know what will be the requestMapping so that I can forward it to corresponding method in controller ?
PS: In the login.jsp, I have code like below:
form action="home" commandName="login"
If form action doesn't begin with a slash (/), form is submitted to address relative to the current one.
If you are already on the login page (i.e. your current address already ends with /login) and you have specified form action="home", form is submitted to current address with home appended at the end - so the result is /login/home, which maps to one of your controller methods.

how to pass an object to the GET handler with Post-Redirect-Get with Spring MVC?

I'm new to Spring MVC and trying to get a Post/Redirect/Get pattern working. We're trying to implement a survey where each page can display a variable number of questions. The way I'd like to implement this is a GET handler that prepares the next survey page and then hands that off to the view. In the same Controller, have a Post handler that processes the form's answers to the survey questions, submits that to the survey service, which returns the next page of questions, and then redirects that next surveyPage to the getNextPage GET handler.
Most of it is working, except the problem is that I don't know how to hand that 'next survey page' object from the POST handler to the getNextPage GET handler in the redirect. The redirect is working; it goes from the POST method to the GET method, but the surveyPage ModelAttribute is a new object in the GET method, and not the one that was set at the end of the POST method. As you can see, I've tried using ModelAttribute, but it doesn't work. I also tried using #SessionAttributes above the class, but then got a HttpSessionRequiredException.
We didn't know how to handle the dynamic form containing a variable # of questions with Spring MVC Forms, so we just did straight JSTL. It's funky but it works. That funkiness is what resulted in using the #RequestBody and SurveyPageBean coming back with the Post. Honestly, I don't know how the SurveyPageBean is populated. It looks like some Spring MVC magic, but it's working so I'm leaving it alone for now (another developer did this and then I picked it up, and we're both new to Spring MVC). Please don't get distracted by the unusual form handling, unless that is part of the problem with the empty surveyPage ModelAttribute not being redirected.
Here's the Controller snippet:
#Controller
#RequestMapping("/surveyPage")
public class SurveyPageController{
#RequestMapping(method=RequestMethod.GET)
public String getNextPage(#ModelAttribute("surveyPage") SurveyPage surveyPage, Model model) {
if(surveyPage.getPageId() == null) {
// call to surveyService (defined elsewhere) to start Survey and get first page
surveyPage = surveyService.startSurvey("New Survey");
}
model.addAttribute("surveyPage", surveyPage);
return "surveyPage";
}
#RequestMapping(method=RequestMethod.POST)
public String processSubmit(#RequestBody String body, SurveyPageBean submitQuestionBean, Model model, #ModelAttribute("surveyPage") SurveyPage surveyPage) {
// process form results, package them up and send to service, which
// returns the next page, if any
surveyPage = surveyService.submitPage(SurveyPageWithAnswers);
if (results.getPageId() == null) {
// The survey is done
surveyPage = surveyService.quitSurvey(surveyId);
return "redirect:done";
}
model.addAttribute("surveyPage ", surveyPage );
return "redirect:surveyPage";
}
Use Flash Attributes as shown in Warlock's Thoughts.
#RequestMapping(method = RequestMethod.POST)
public String handleFormSubmission(..., final RedirectAttributes redirectAttrs) {
...
redirectAttrs.addFlashAttribute("AttributeName", value);
return "redirect:to_some_url_handled_by_BController";
}
Your GET takes the surveyPage as a model attribute, which means it is reading it from the URL. In the POST, rather than adding the surveyPage to the model (which is lost because you are telling the client to redirect, which creates a new request and therefore a new model) you should add the surveyPage as a query parameter in your "redirect:surveyPage" You'll have to look at how the surveyPage is constructed from the query params in order to know what to put on the query string.
If, for instance, the surveyPage is constructed from a user, page number, and question count or something, I believe you could do something like "redirect:surveyPage?userId=1234&pageNumber=5678&questionCount=12 in order to pass that model attribute along.

How do I omit ModelAttribute parameters from the ModelAndView returned by a Spring 3 MVC action?

I have a Spring MVC controller with an action that's called using AJAX.
#SessionAttributes({"userContext"})
public class Controller
{
...
#RequestMapping(value = "/my-url", method= { RequestMethods.POST })
public ModelAndView doSomething(#ModelAttribute("userContext") UserContext context,
SessionStatus sessionStatus)
{
BusinessObject obj = doSomeBusinessLogic(context.getUserName());
sessionStatus.setComplete();
ModelAndView mav = new ModelAndView("jsonView");
mav.addObject("someInt", obj.getId());
return mav;
}
}
When I run this action, I get the following exception:
net.sf.json.JSONException: There is a cycle in the hierarchy!
at t.sf.json.util.CycleDetectionStrategy$StrictCycleDetectionStrategy.handleRepeatedReferenceAsObject(CycleDetectionStrategy.java:97)
at net.sf.json.JSONObject._fromBean(JSONObject.java:833)
at net.sf.json.JSONObject.fromObject(JSONObject.java:168)
at org.springframework.web.servlet.view.json.writer.jsonlib.PropertyEditorRegistryValueProcessor.processObjectValue(PropertyEditorRegistryValueProcessor.java:127)
at net.sf.json.JSONObject._fromMap(JSONObject.java:1334)
Truncated. see log file for complete stacktrace
After doing some debugging I found out that Spring is placing the UserContext object onto the ModelAndView that I am returning. If I hard-code my user name and remove the context object from the method's parameters, the action runs successfully. Is there a way to configure Spring to omit the ModelAttribute-annotated parameters from the returned ModelAndView? As you can see, sessionStatus.setComplete() has no effect.
I've had similar problems in the past with #SessionAttributes. By declaring #SessionAttributes({"userContext"}) you're telling Spring that you want "userContext" to always be available in the model, and so Spring has no choice but to send your UserContext object out to the model, just in case you're going to be redirecting or doing something else which might end up at another Controller.
The "solution" (and I didn't like it much, but it worked) was to omit the #SessionAttributes annotation on the controller, add an HttpSession parameter to the necessary methods and "manually" manage what's in it.
I'm interested to see if there's a better way, because it seems #SessionAttributes has tremendous potential to tidy up controller-level code.
I registered a WebArgumentResolver to get to my session variable. This allowed me to keep this session variable out of the response while keeping my action unit testable.
Along with #ModelAttribute, pass #ModelMap as a method argument.
Based on business logic, error conditions -- if you do not need the attribute for certain scenarios, then remove it from the map.
public ModelAndView foo(#ModelAttribute("userContext") UserContext, #ModelMap map){
if(success){
return success.jsp
}
else{
map.remove("userContext");
return "error.jsp"
}
}
Not totally satisfied with having to pass the ModelMap as well, but I did not find any other easier way of doing it.
Cheers!!

Resources