Write ModelandView to a file - spring-mvc

A spring controller method returns ModelAndView and I want to write the response to a file, how can this be done ?
ModelAndView mv = new ModelAndView(viewName);
mv.addObject("foo",foo);
return mv;
can the to be rendered content accessed in the same controller method ?

The rendered view is not available at the controller level. If you need to access the rendered version in the controller, you could render the content yourself and return the rendered String from the controller method.
You could also get in further up in the stack and use a ServletFilter and wrap the output stream, e.g. with a TeeOutputStream from Apache commons. At the point you do however not really know which controller method was called. What you could do to signal this is to set a RequestAttribute in the controller method that the filter checks to decide whether to write to the file.

Related

Load different view based on url parameter with out changing controller action method in asp mvc

I was wondering if below hack is possible or not.
Tried multiple ways but it will require some conditional statements in action method.
I am looking for solution based on routing most probably but not sure how it is possible.
Suppose I have single Acton Method Index()
public ActionResult Index()
{
return View();
}
above method is under home controller.
In addition inside Views > Home folder there are two view files...
Index.cshtml
Index_New.cshtml.
I believe that it is possible to load different Views using id passed in URL parameter but that will require change in above action method and i don't want that.
Can we do something without changing action method so that
http://example.com/Home/Index should load Index.cshtml
and
http://example.com/Home/New/Index should load Index_New.cshtml?
Create a new action method. Update your route registrations so that the request yourSite/Home/News/Index will be handled by this new aciton method.
The below code uses attribute routing to specify the route pattern for the new action method. You can pass the view name to the view method if you want to return something different than the convention (the action name)
[Route("Home/News/Index")]
public ActionResult NewsIndex()
{
return View("Index_New");
}

Spring MVC: flash attribute vs model attribute

What is the different between flash and model attribute?
I want to store an object and display it in my JSP as well as reuse it in other controller. I have use sessionAttribute and it works fine in the JSP, but the problem is when I try to retrieve that model attribute in other controller.
I lose some data. I searched around and found that flash attribute allows to past past value to different controller, doesn't it?
If we want to pass the attributes via redirect between two controllers, we cannot use request attributes (they will not survive the redirect), and we cannot use Spring's #SessionAttributes (because of the way Spring handles it), only an ordinary HttpSession can be used, which is not very convenient.
Flash attributes provide a way for one request to store attributes intended for use in another. This is most commonly needed when redirecting — for example, the Post/Redirect/Get pattern. Flash attributes are saved temporarily before the redirect (typically in the session) to be made available to the request after the redirect and removed immediately.
Spring MVC has two main abstractions in support of flash attributes. FlashMap is used to hold flash attributes while FlashMapManager is used to store, retrieve, and manage FlashMap instances.
Example
#Controller
#RequestMapping("/foo")
public class FooController {
#RequestMapping(value = "/bar", method = RequestMethod.GET)
public ModelAndView handleGet(Model model) {
String some = (String) model.asMap().get("some");
// do the job
}
#RequestMapping(value = "/bar", method = RequestMethod.POST)
public ModelAndView handlePost(RedirectAttributes redirectAttrs) {
redirectAttrs.addFlashAttribute("some", "thing");
return new ModelAndView().setViewName("redirect:/foo/bar");
}
}
In above example, request comes to handlePost, flashAttributes are added, and retrieved in handleGet method.
More info here and here.

Spring MVC: Session attribute required - not found in session

I am receiving the following error on submitting my form:
org.springframework.web.HttpSessionRequiredException: Session attribute 'rulesForm' required - not found in session
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.raiseSessionRequiredException(AnnotationMethodHandlerAdapter.java:722)
My JSP contains the following:
<form:form id="rulesForm" modelAttribute="rulesForm" action="save.do">
...
</form>
My Controller contains the following:
#Controller
#RequestMapping("/rules")
#SessionAttributes({"rulesForm", "deskForm"})
public class RulesController {
.
.
.
#RequestMapping(value = "/save.do")
public ModelAndView saveRuleAttributesAndRules(#Valid
#ModelAttribute("rulesForm")
RulesFormDTO rulesForm, BindingResult bindingResult, HttpSession session, Principal principal) {
It seems that if I leave my browser open for a while with my form displaying and then I attempt to perform a submit after some time I get this error.
Really what I want to happen in this case is for the new "rulesForm" object to be created...how can I achieve this?
Thanks
As the Javadoc on #SessionAttribute indicates use of the annotation means you want store the specified model attributes in the session, which means you need to add them to the model first. Spring MVC will not create them.
In other words when you add a #ModelAttribute("rulesForm") controller method argument you're telling Spring MVC to look for it in the model or create a new instance if not found. However if you also add #SessionAttributes, Spring MVC will not attempt to create a new instance and will expect the object to be either in the model or in the session. You can use a #ModelAttribute method to add your object initially.

How to configure an endpoint in Spring to accept both form data and XML request body?

I have a small question regarding Spring's MVC data binding capabilities.
I do have the following controller class:
#Controller
#RequestMapping("/foo")
public class FooController() {
// … some init stuff //
#RequestMapping(value = "/{id}/edit.{format}", method = RequestMethod.POST)
public ModelAndView editFoo(#RequestBody FooItem foo, #PathVariable("format") String format) {
// some code here to edit the FooItem //
}
}
I want to be able to post form data as well as XML against this method. For that to work I added two message converters to my applicationContext.xml: The default formHttpMessageConverter and an XStream marshaller.
This works fine, but I have a problem, that if I use #RequestBody and post form data against the URL, the server responds with a 415 Error. If I remove this annotation, form data works well and Spring creates the object for me, but if I post XML against it, I get an empty object.
Is there any way around this or do I need to have 2 methods to be able to handle both of the incoming formats?
Thanks in advance!
I think you need two methods.
FormHttpMessageConverter doesn't have the same databinding capabilities as #ModelAttribute provides, it can't bind request to the specified target class, only to MultiValueMap (see javadoc).

Spring MVC - pass model between controllers

I have created a controller that does some business logic and creates a model. If I pass this model directly to view by returning ModelAndView with view name and model - everything working great. But now I want to display results at another page. So I use "redirect:" prefix to redirect to another controller, but the model is lost.
What Im missing?
Regards,
Oleksandr
you can use the forward: prefix which ultimately does a RequestDispatcher.forward()
insted of The redirect: prefix.
Option 1 :
You might put the model in session and get it back in the controller and nullify it in session.
Option 2 :
You said, you are having two controllers, first one would retrieve the user input and do some business logic and redirect to other one. My suggestion is to move the business logic which is placed in both controllers to a class and have only one controller which would return the model and view to the user.
During redirect: request is sent using GET method with parameters appended to the url. You can right a new method in the controller to receive the request parameters with #RequestParameter annotation.
While redirecting the request simple add all the parameters as string
e.g ModelAndView mv = new ModelAndView();
mv.setViewName(redirect:/your/url);
mv.addObject("param1", string_param);
.
.
.
This way you can redirect successfully.
Since the redirect: prefix runs another controller, you will lose whatever you had in the ModelAndView in the previous controller. Perhaps the business logic controller should not be a controller at all -- maybe you should just make it a regular class, and have the results controller call it. Then the results controller could save the data to the model.
i would not use #SessionAttributes as it may change in future releases of spring. I would stick with the old fashioned way that Oleksandr showed you above
somehow an old post but maybe someone else will find it usefull

Resources