Override velocity view and output an image instead - servlets

I have hijacked the normal processing of velocity templates by calling response.getOutputStream in my controller, and I do get an image, but there is an exception "java.lang.IllegalStateException: getOutputStream() has already been called for this response" whenever an image is generated. Is there a way to tell velocity not to parse the file for a certain controller?

Return null from your Controller's handleRequest() (or handleRequestInternal()) method to indicate that you have already handled the response and view should not be rendered.
API documentation

Related

Write ModelandView to a file

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.

Spring MVC retain error meesage after redirect

I have a jsp with 2 input boxes that searches on 2 different scenarios. So , i have two different Get requests mapping to /search1 and /search2 but have created only one POJO for this.
As soon as user submits a search, I check if there is any results for that, and if not i add error message in model and "redirect:"(redirection because if i simply return a page and now make a new search the url will be /search1/search2) to the same basic page.
But everytime i load the page the error message persists.
Any workaround for this? how do i display the messaeg only on search.
Use Flash Attributes.
http://viralpatel.net/blogs/spring-mvc-flash-attribute-example/
Add RedirectAttributes parameter to your controller's handler method.
then redirectAttributes.addFlashAttribute("modelAttributeName", "value");
then redirect
The controller handler that you redirect to should have "modelAttributeName" model attribute available to it.
Essentially your a putting a value into session which is removed as soon as it is read on the next request.
Another solution would be
you can use request parameter to pass message id and write utility to read message from properties file using message id in the get request of redirected controller.
Controller 1
return "redirect:your_redirection_url?messageId=1";
Controller 2 (where redirected)
if (messageid != null && !(messageid.equals(""))) { MessageUtility.addMessage(Integer.parseInt(messageid), model, locale); }

ErrorBinding Spring portlet MVC

Disclaimer: I wished I had a through understanding before starting working with the framework.
But as it is of now, I'm lacking on that front, and hence the question.
I am working with Spring-Portlet MVC.
I have a flow, where in I take an input on a screen, validate the input, depending upon its result it either render same screen or next screen.
Implementation detail:
I have an action method which takes form backed command object. It checks whether entered input is valid or not. If it is not valid, it populate error message in BindingResult instance it takes as another argument.
We have different render method, to render different screen.
I'm taking command object as an argument in these render method. This command object I'm receiving is same as one passed to action.
Problem:
While rerendering a screen spring-mvc should bind the error message populated in action method. Currently when I take command object as argument in render method spring-mvc is somehow unable to bind that error message. But interesting enough it is able to bind the error message if I don't take command object as argument in render method and rather create a new command object altogether there.
can,some one having better understanding of spring-portlet mvc please explain this behaviour, or tell where I am lacking in understanding.
Regards,
Mawia
EDIT: Just to enrich the below answer: Though I didn't exactly isolated the issue which was causing the said behaviour, but the way I met my requirement was using modelattribute. ModelAttribute can be used either on method or a parameter to a method. It ensures that model will made available to all the call till the view is render(that is my understanding!). So we don't need to take command object as parameter in Render method, just annotate the commandObject parameter in action method with ModelAttribute and then you can get the same object returned from model as suggested in the answer below.
I don't think the command/model object should be an argument/parameter in the render method. I have had the same issue trying to get the validation error messages when command/model is defined as argument in render method signature. I typically have the command/object creation/populate in a separate method, like this:
#ModelAttribute(value="address")
public Address getAddress(#RequestParam Integer id){
Address address = null;
if(id != null){
address = myService.getAddress(id);
}else{
address = new Address();
}
return address;
}
If I still need to access the ModelAttribute/command object from the render method, I typically get it by:
#RenderMapping
public String showAddressPage(ModelMap modelMap){
Address address = modelMap.get("address");
//make any additional changes to address
}
I used this example as reference article

Asynchronous action for strongly-typed partial view in _Layout

So, here's the rundown...
I've got a master layout page for my MVC 4 app that has some dynamic information and needs to be strongly typed to a specific domain entity to get that information. To keep my files cleaner, I've extracted out the typed fields to a partial view.
To grab the entity I need and map it to the partial's view-model, I have a LayoutController with an action that returns a Task<PartialViewResult>. This action uses a service layer to make an async call out to a Web API project, awaiting the entity. It massages that entity into the view-model and then returns PartialView("_LayoutPartial", viewModel).
From within the _Layout page, the partial is called via:
#{Html.RenderAction("LayoutInfo", "Layout", new { /*entity primary key*/ });}
I've stepped through the code and it does indeed get the correct entity back, but then after returning the partial view task, I get everybody's favorite Server Error page with the following error:
HttpServerUtility.Execute blocked while waiting for an asynchronous operation to complete.
I've done some Googling and SO searching and have no idea what this actually means. Am I thinking through this correctly?
That error message means that you're trying to invoke (and wait on!) an asynchronous method from within a synchronous method. In your specific case, the synchronous method is HtmlHelper.RenderAction, and the asynchronous method is your Task-returning action method. The reason the error occurs is that the point of writing an asynchronous Task-returning method is presumably to avoid blocking a thread, but RenderAction can't return until the Task is complete, so RenderAction ends up blocking while waiting for the operation to finish.
One option is to make the method that RenderAction calls synchronous instead of asynchronous, keeping in mind that this will continue to block the original thread. Another option is to populate the layout data asynchronously from within the original action method, then to pass that via ViewData to the layout page.

Does Velocity template has implicit request object?

I'm rephrasing my existing question to a more generic one. I want to know if Velocity has got implicit object references like JSP does.
I'm particularly interested in knowing about the request object.
In JSP we can get the attribute in the request scope like <%= request.getAttribute("req1") %>
I know that JSP is a servlet and <%= request.getAttribute("req1") %> ends up as a part of _jspService() method which has the request object available to it before the scope of the request ends.
I'm not sure how Velocity works behind the scenes (it may be leaving the request object behind by the time it plays it role)
To test that I did the following thing which was a the part of my previous question.
I have a Spring MVC TestController in which I'm setting a request attribute. I'm using Velocity templates for rendering the views.
#RequestMapping(value="/test", method=RequestMethod.GET)
public ModelAndView display(HttpServletRequest req, HttpServletResponse resp){
...
req.setAttribute("req1", "This should be present for first request");
...
}
In the Velocity template I'm doing something like
Request: $request.getAttribute('req1')
but I'm not getting the value of req1. I know I should have put req1 in model map instead of request but I want to know about implicit request object ref.
I tried $req1 as well but its not working.
When I'm doing the same thing with the model and returning it back, everything is working correctly.
Where am I going wrong?
Update: The same thing is happening with req.getSession().setAttribute("req1", testObject) also.
Salaam,
req.getSession().getAttribute("req1", testObject) == $req1
AFAIK, you cannot access the request object at VelocityViewServlet's templates, unless you explicity set the request object in context or use a v-tool .
Take a look at this question: Velocity + Spring. The Spring folks haven't kept the integration with Velocity very up to date.
Once you've created that extension and set it up to be used properly in your servlet configuration, you'd be able to simply put the object on the ModelAndView and from there do whatever you need with it.

Resources