Browse Source

Document XsltView in reference doc

And delete all references to the deprecated AbstractXsltView.

Issue: SPR-6599
pull/832/head
Brian Clozel 11 years ago
parent
commit
5b47504dd4
  1. 200
      src/asciidoc/web-view.adoc

200
src/asciidoc/web-view.adoc

@ -1853,134 +1853,92 @@ XSLT in a Spring Web MVC application. @@ -1853,134 +1853,92 @@ XSLT in a Spring Web MVC application.
This example is a trivial Spring application that creates a list of words in the
`Controller` and adds them to the model map. The map is returned along with the view
name of our XSLT view. See <<mvc-controller>> for details of Spring Web MVC's
`Controller` interface. The XSLT view will turn the list of words into a simple XML
`Controller` interface. The XSLT Controller will turn the list of words into a simple XML
document ready for transformation.
[[view-xslt-beandefs]]
==== Bean definitions
Configuration is standard for a simple Spring application. The dispatcher servlet config
file contains a reference to a `ViewResolver`, URL mappings and a single controller
bean...
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<bean id="homeController"class="xslt.HomeController"/>
----
... that encapsulates our word generation logic.
[[view-xslt-controllercode]]
==== Standard MVC controller code
The controller logic is encapsulated in a subclass of `AbstractController`, with the
handler method being defined like so...
Configuration is standard for a simple Spring application.
The MVC configuration has to define a `XsltViewResolver` bean and
regular MVC annotation configuration.
[source,java,indent=0]
[subs="verbatim,quotes"]
----
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
Map map = new HashMap();
List wordList = new ArrayList();
@EnableWebMvc
@ComponentScan
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
wordList.add("hello");
wordList.add("world");
map.put("wordList", wordList);
return new ModelAndView("home", map);
@Bean
public XsltViewResolver xsltViewResolver() {
XsltViewResolver viewResolver = new XsltViewResolver();
viewResolver.setPrefix("/WEB-INF/xsl/");
viewResolver.setSuffix(".xslt");
return viewResolver;
}
}
----
So far we've done nothing that's XSLT specific. The model data has been created in the
same way as you would for any other Spring MVC application. Depending on the
configuration of the application now, that list of words could be rendered by JSP/JSTL
by having them added as request attributes, or they could be handled by Velocity by
adding the object to the `VelocityContext`. In order to have XSLT render them, they of
course have to be converted into an XML document somehow. There are software packages
available that will automatically 'domify' an object graph, but within Spring, you have
complete flexibility to create the DOM from your model in any way you choose. This
prevents the transformation of XML playing too great a part in the structure of your
model data which is a danger when using tools to manage the domification process.
And we need a Controller that encapsulates our word generation logic.
[[view-xslt-subclassing]]
==== Convert the model data to XML
In order to create a DOM document from our list of words or any other model data, we
must subclass the (provided)
`org.springframework.web.servlet.view.xslt.AbstractXsltView` class. In doing so, we must
also typically implement the abstract method `createXsltSource(..)` method. The first
parameter passed to this method is our model map. Here's the complete listing of the
`HomePage` class in our trivial word application:
[[view-xslt-controllercode]]
==== Standard MVC controller code
The controller logic is encapsulated in a `@Controller` class, with the
handler method being defined like so...
[source,java,indent=0]
[subs="verbatim,quotes"]
----
package xslt;
// imports omitted for brevity
@Controller
public class XsltController {
public class HomePage extends AbstractXsltView {
protected Source createXsltSource(Map model, String rootName,
HttpServletRequest request, HttpServletResponse response) throws Exception {
@RequestMapping("/")
public String home(Model model) throws Exception {
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = document.createElement(rootName);
Element root = document.createElement("wordList");
List words = (List) model.get("wordList");
for (Iterator it = words.iterator(); it.hasNext();) {
String nextWord = (String) it.next();
List<String> words = Arrays.asList("Hello", "Spring", "Framework");
for (String word : words) {
Element wordNode = document.createElement("word");
Text textNode = document.createTextNode(nextWord);
Text textNode = document.createTextNode(word);
wordNode.appendChild(textNode);
root.appendChild(wordNode);
}
return new DOMSource(root);
model.addAttribute("wordList", root);
return "home";
}
}
----
A series of parameter name/value pairs can optionally be defined by your subclass which
will be added to the transformation object. The parameter names must match those defined
in your XSLT template declared with `<xsl:param
name="myParam">defaultValue</xsl:param>`. To specify the parameters, override the
`getParameters()` method of the `AbstractXsltView` class and return a `Map` of the
name/value pairs. If your parameters need to derive information from the current
request, you can override the `getParameters(HttpServletRequest request)` method instead.
So far we've only created a DOM document and added it to the Model map. Note that you
can also load an XML file as a `Resource` and use it instead of a custom DOM document.
Of course, there are software packages available that will automatically 'domify'
an object graph, but within Spring, you have complete flexibility to create the DOM
from your model in any way you choose. This prevents the transformation of XML playing
too great a part in the structure of your model data which is a danger when using tools
to manage the domification process.
[[view-xslt-viewdefinitions]]
==== Defining the view properties
The views.properties file (or equivalent xml definition if you're using an XML based
view resolver as we did in the Velocity examples above) looks like this for the one-view
application that is 'My First Words':
[literal]
[subs="verbatim,quotes"]
----
home.(class)=xslt.HomePage
home.stylesheetLocation=/WEB-INF/xsl/home.xslt
home.root=words
----
Here, you can see how the view is tied in with the `HomePage` class just written which
handles the model domification in the first property `'.(class)'`. The
`'stylesheetLocation'` property points to the XSLT file which will handle the XML
transformation into HTML for us and the final property `'.root'` is the name that will
be used as the root of the XML document. This gets passed to the `HomePage` class above
in the second parameter to the `createXsltSource(..)` method(s).
Next, `XsltViewResolver` will resolve the "home" XSLT template file and merge the
DOM document into it to generate our view.
[[view-xslt-transforming]]
==== Document transformation
Finally, we have the XSLT code used for transforming the above document. As shown in the
above `'views.properties'` file, the stylesheet is called `'home.xslt'` and it lives in
the war file in the `'WEB-INF/xsl'` directory.
Finally, the `XsltViewResolver` will resolve the "home" XSLT template file and merge the
DOM document into it to generate our view. As shown in the `XsltViewResolver`
configuration, XSLT templates live in the war file in the `'WEB-INF/xsl'` directory
and end with a `"xslt"` file extension.
[source,xml,indent=0]
[subs="verbatim,quotes"]
@ -1995,60 +1953,40 @@ the war file in the `'WEB-INF/xsl'` directory. @@ -1995,60 +1953,40 @@ the war file in the `'WEB-INF/xsl'` directory.
<head><title>Hello!</title></head>
<body>
<h1>My First Words</h1>
<xsl:apply-templates/>
<ul>
<xsl:apply-templates/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="word">
<xsl:value-of select="."/><br/>
<li><xsl:value-of select="."/></li>
</xsl:template>
</xsl:stylesheet>
----
This is rendered as:
[[view-xslt-summary]]
=== Summary
A summary of the files discussed and their location in the WAR file is shown in the
simplified WAR structure below.
[literal]
[source,html,indent=0]
[subs="verbatim,quotes"]
----
ProjectRoot
|
+- WebContent
|
+- WEB-INF
|
+- classes
| |
| +- xslt
| | |
| | +- HomePageController.class
| | +- HomePage.class
| |
| +- views.properties
|
+- lib
| |
| +- spring-*.jar
|
+- xsl
| |
| +- home.xslt
|
+- frontcontroller-servlet.xml
----
You will also need to ensure that an XML parser and an XSLT engine are available on the
classpath. JDK 1.4 provides them by default, and most Java EE containers will also make
them available by default, but it's a possible source of errors to be aware of.
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello!</title>
</head>
<body>
<h1>My First Words</h1>
<ul>
<li>Hello</li>
<li>Spring</li>
<li>Framework</li>
</ul>
</body>
</html>
----
[[view-document]]
== Document views (PDF/Excel)

Loading…
Cancel
Save