Render partial JSP fragments in Spring MVC?
I am quite new to Spring MVC, and trying to figure out how to render a partial view without refreshing the whole page. I thought:
if I can post a request to the backend, in this case, a Spring controller method
And if this method fills in model attribute, and then return ModelAndView object with specified view name mapping to a JSP file, and JSP is able to generat the necessary HTML fragment.
The returned HTML fragment will be inserted into a DIV placeholder.
This probably wouldn't work, but I am not sure what's wrong with it? I got as far as the JSP is called upon to render the view, but for some reason, the model attribut I put into the s开发者_如何学Cession doesn't seem to be there.
I'd appreciate if anyone with similar experience can provide some examples on this subject, or point to me where it potentially went wrong.
I read something from Spring web flow to handle Ajax request with fragmented view, but I am not sure I get the idea on how it actually works.
I wouldn't say my answer below necessarily answers your question, but I arrived at this page via Google while I was attempting to replicate the Spring AjaxEventDecoration (that only loads fragments of a page), so here is what I have now discovered in case anyone else ever arrives here:
The quick answer is to ensure you set the 'Accept' property of the XMLHttpRequest to 'text/html;type=ajax' which then tells the Spring MVC that only (comma separated) fragments specified by the URL parameter 'fragments' should be returned.
I am using Tiles server-side and jQuery client side, this is a rough overview of my setup:
An example webmvc-config.xml
...
<bean id="tilesViewResolver" class="org.springframework.js.ajax.AjaxUrlBasedViewResolver">
<property name="viewClass" value="org.springframework.js.ajax.tiles2.AjaxTilesView" />
</bean>
...
An example page's Tiles configuration
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<definition name="eventPage" extends="twoColumnLayout">
<put-attribute name="title" value="My Event Page" />
<put-attribute name="view" value="/WEB-INF/jsp/viewText.jsp" />
<put-attribute name="objectViewer" value="/WEB-INF/jsp/viewEvent.jsp" />
</definition>
</tiles-definitions>
I have a Java controller class that returns an instance of ModelMap that is mapped to the request 'eventPage' (.html in my case).:
@Controller
public class EventPageController
{
/**
* Method to handle main my events page.
*/
@RequestMapping(value = "/eventPage.html", method = RequestMethod.GET)
public ModelMap pageDisplayHandlerForEvents(ModelMap model, HttpServletRequest req)
{
...
}
}
And then my JavaScript client-side code (that for examples sake always loads the 'objectViewer' fragment):
Note: Your HTML elements that are loaded as fragments must have an ID attribute matching that of the fragment ID.
$(".springFragmentLoader").click(function()
{
$.ajax(__contextRoot + "/eventPage.html?fragments=objectViewer", {
beforeSend: function(req) {
req.setRequestHeader("Accept", "text/html;type=ajax");
},
complete : function(jqXHR)
{
$("#objectViewer").html(jqXHR.responseText);
}
});
}
For more detail see Handling Ajax Requests.
Hope that helps.
Addition to Ed's answer: I added the following to my layouts.xml, which configure layouts
<tiles-definitions>
....
<definition name="partial" template="/WEB-INF/layouts/partial.jspx">
</definition>
....
</tiles-definitions>
partial.jspx is
<div xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:tiles="http://tiles.apache.org/tags-tiles">
<jsp:directive.page contentType="text/html;charset=UTF-8"/>
<jsp:directive.page pageEncoding="UTF-8"/>
<jsp:output omit-xml-declaration="yes"/>
<tiles:insertAttribute name="partialView"/>
</div>
configuration for partial view:
<tiles-definitions>
<definition extends="partial" name="partial/listOfProcessesPartial">
<put-attribute name="partialView" value="/WEB-INF/views/partial/listOfProcessesPartial.jspx"/>
</definition>
then you just return some view from your controller and get the only html piece in response
As you thought you'll need Ajax to get the new HTML content and insert it in your current HTML page. To load it this content you can use the jquery library, specially its function load(). In this link there are examples of its use.
You need as well a controller method that returns the HTML code from a JSP as you were doing. The method must be mapped with an url that you should use in the load() function of ajax. If you have problems with trendering the attributes in the JSP with Spring add some code to the question to see what can be wrong.
精彩评论