Revised documentation for PDF, Excel and JSON views
Issue: SPR-17180 Issue: SPR-17182
This commit is contained in:
parent
de38af6843
commit
c0c9e08bf9
|
@ -149,7 +149,7 @@ public class MappingJackson2JsonView extends AbstractJackson2View {
|
|||
* Filter out undesired attributes from the given model.
|
||||
* The return value can be either another {@link Map} or a single value object.
|
||||
* <p>The default implementation removes {@link BindingResult} instances and entries
|
||||
* not included in the {@link #setModelKeys renderedAttributes} property.
|
||||
* not included in the {@link #setModelKeys modelKeys} property.
|
||||
* @param model the model, as passed on to {@link #renderMergedOutputModel}
|
||||
* @return the value to be rendered
|
||||
*/
|
||||
|
|
|
@ -22,8 +22,8 @@ extensive set of features that will make such a transition easier. Thymeleaf is
|
|||
developed and maintained. For a more complete introduction see the
|
||||
http://www.thymeleaf.org/[Thymeleaf] project home page.
|
||||
|
||||
The Thymeleaf integration with Spring MVC is managed by the Thymeleaf project. The
|
||||
configuration involves a few bean declarations such as
|
||||
The Thymeleaf integration with Spring MVC is managed by the Thymeleaf project.
|
||||
The configuration involves a few bean declarations such as
|
||||
`ServletContextTemplateResolver`, `SpringTemplateEngine`, and `ThymeleafViewResolver`.
|
||||
See http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring] for more details.
|
||||
|
||||
|
@ -941,9 +941,8 @@ The preceding JSP assumes that the variable name of the form backing object is
|
|||
==== The input tag
|
||||
|
||||
This tag renders an HTML 'input' tag using the bound value and type='text' by default.
|
||||
For an example of this tag, see <<mvc-view-jsp-formtaglib-formtag>>. Starting with Spring
|
||||
3.1 you can use other types such HTML5-specific types like 'email', 'tel', 'date', and
|
||||
others.
|
||||
For an example of this tag, see <<mvc-view-jsp-formtaglib-formtag>>. You may also use
|
||||
HTML5-specific types like 'email', 'tel', 'date', and others.
|
||||
|
||||
|
||||
[[mvc-view-jsp-formtaglib-checkboxtag]]
|
||||
|
@ -1563,12 +1562,12 @@ The corresponding `@Controller` method is shown below:
|
|||
[[mvc-view-jsp-formtaglib-html5]]
|
||||
==== HTML5 tags
|
||||
|
||||
Starting with Spring 3, the Spring form tag library allows entering dynamic attributes,
|
||||
which means you can enter any HTML5 specific attributes.
|
||||
The Spring form tag library allows entering dynamic attributes, which means you can
|
||||
enter any HTML5 specific attributes.
|
||||
|
||||
In Spring 3.1, the form input tag supports entering a type attribute other than 'text'.
|
||||
This is intended to allow rendering new HTML5 specific input types such as 'email',
|
||||
'date', 'range', and others. Note that entering type='text' is not required since 'text'
|
||||
The form input tag supports entering a type attribute other than 'text'. This is
|
||||
intended to allow rendering new HTML5 specific input types such as 'email', 'date',
|
||||
'range', and others. Note that entering type='text' is not required since 'text'
|
||||
is the default type.
|
||||
|
||||
|
||||
|
@ -1801,7 +1800,6 @@ Similar requirements apply for implementing `AbstractRssFeedView`, as shown belo
|
|||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
// implementation omitted
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
@ -1822,7 +1820,7 @@ https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-sp
|
|||
|
||||
|
||||
[[mvc-view-document-intro]]
|
||||
=== Introduction
|
||||
=== Introduction to document views
|
||||
|
||||
Returning an HTML page isn't always the best way for the user to view the model output,
|
||||
and Spring makes it simple to generate a PDF document or an Excel spreadsheet
|
||||
|
@ -1843,166 +1841,45 @@ vulnerability for untrusted PDF content.
|
|||
|
||||
|
||||
|
||||
[[mvc-view-document-config]]
|
||||
=== Configuration
|
||||
|
||||
Document based views are handled in an almost identical fashion to XSLT views, and the
|
||||
following sections build upon the previous one by demonstrating how the same controller
|
||||
used in the XSLT example is invoked to render the same model as both a PDF document and
|
||||
an Excel spreadsheet (which can also be viewed or manipulated in Open Office).
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document-configviews]]
|
||||
=== View definition
|
||||
|
||||
First, let's amend the views.properties file (or xml equivalent) and add a simple view
|
||||
definition for both document types. The entire file now looks like this with the XSLT
|
||||
view shown from earlier:
|
||||
|
||||
[literal]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
home.(class)=xslt.HomePage
|
||||
home.stylesheetLocation=/WEB-INF/xsl/home.xslt
|
||||
home.root=words
|
||||
|
||||
xl.(class)=excel.HomePage
|
||||
|
||||
pdf.(class)=pdf.HomePage
|
||||
----
|
||||
|
||||
__If you want to start with a template spreadsheet or a fillable PDF form to add your
|
||||
model data to, specify the location as the 'url' property in the view definition__
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document-configcontroller]]
|
||||
=== Controller
|
||||
|
||||
The controller code we'll use remains exactly the same from the XSLT example earlier
|
||||
other than to change the name of the view to use. Of course, you could be clever and
|
||||
have this selected based on a URL parameter or some other logic - proof that Spring
|
||||
really is very good at decoupling the views from the controllers!
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document-configsubclasses]]
|
||||
=== Excel views
|
||||
|
||||
Exactly as we did for the XSLT example, we'll subclass suitable abstract classes in
|
||||
order to implement custom behavior in generating our output documents. For Excel, this
|
||||
involves writing a subclass of
|
||||
`org.springframework.web.servlet.view.document.AbstractExcelView` (for Excel files
|
||||
generated by POI) or `org.springframework.web.servlet.view.document.AbstractJExcelView`
|
||||
(for JExcelApi-generated Excel files) and implementing the `buildExcelDocument()` method.
|
||||
|
||||
Here's the complete listing for our POI Excel view which displays the word list from the
|
||||
model map in consecutive rows of the first column of a new spreadsheet:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
package excel;
|
||||
|
||||
// imports omitted for brevity
|
||||
|
||||
public class HomePage extends AbstractExcelView {
|
||||
|
||||
protected void buildExcelDocument(Map model, HSSFWorkbook wb, HttpServletRequest req,
|
||||
HttpServletResponse resp) throws Exception {
|
||||
|
||||
HSSFSheet sheet;
|
||||
HSSFRow sheetRow;
|
||||
HSSFCell cell;
|
||||
|
||||
// Go to the first sheet
|
||||
// getSheetAt: only if wb is created from an existing document
|
||||
// sheet = wb.getSheetAt(0);
|
||||
sheet = wb.createSheet("Spring");
|
||||
sheet.setDefaultColumnWidth((short) 12);
|
||||
|
||||
// write a text at A1
|
||||
cell = getCell(sheet, 0, 0);
|
||||
setText(cell, "Spring-Excel test");
|
||||
|
||||
List words = (List) model.get("wordList");
|
||||
for (int i=0; i < words.size(); i++) {
|
||||
cell = getCell(sheet, 2+i, 0);
|
||||
setText(cell, (String) words.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
And the following is a view generating the same Excel file, now using JExcelApi:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
package excel;
|
||||
|
||||
// imports omitted for brevity
|
||||
|
||||
public class HomePage extends AbstractJExcelView {
|
||||
|
||||
protected void buildExcelDocument(Map model, WritableWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
WritableSheet sheet = wb.createSheet("Spring", 0);
|
||||
|
||||
sheet.addCell(new Label(0, 0, "Spring-Excel test"));
|
||||
|
||||
List words = (List) model.get("wordList");
|
||||
for (int i = 0; i < words.size(); i++) {
|
||||
sheet.addCell(new Label(2+i, 0, (String) words.get(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Note the differences between the APIs. We've found that the JExcelApi is somewhat more
|
||||
intuitive, and furthermore, JExcelApi has slightly better image-handling capabilities.
|
||||
There have been memory problems with large Excel files when using JExcelApi however.
|
||||
|
||||
If you now amend the controller such that it returns `xl` as the name of the view (
|
||||
`return new ModelAndView("xl", map);`) and run your application again, you should find
|
||||
that the Excel spreadsheet is created and downloaded automatically when you request the
|
||||
same page as before.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document-configsubclasspdf]]
|
||||
[[mvc-view-document-pdf]]
|
||||
=== PDF views
|
||||
|
||||
The PDF version of the word list is even simpler. This time, the class extends
|
||||
`org.springframework.web.servlet.view.document.AbstractPdfView` and implements the
|
||||
A simple PDF view for a word list could extend
|
||||
`org.springframework.web.servlet.view.document.AbstractPdfView` and implement the
|
||||
`buildPdfDocument()` method as follows:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
package pdf;
|
||||
public class PdfWordList extends AbstractPdfView {
|
||||
|
||||
// imports omitted for brevity
|
||||
protected void buildPdfDocument(Map<String, Object> model, Document doc, PdfWriter writer,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
public class PDFPage extends AbstractPdfView {
|
||||
|
||||
protected void buildPdfDocument(Map model, Document doc, PdfWriter writer,
|
||||
HttpServletRequest req, HttpServletResponse resp) throws Exception {
|
||||
List words = (List) model.get("wordList");
|
||||
for (int i=0; i<words.size(); i++) {
|
||||
doc.add( new Paragraph((String) words.get(i)));
|
||||
List<String> words = (List<String>) model.get("wordList");
|
||||
for (String word : words) {
|
||||
doc.add(new Paragraph(word));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Once again, amend the controller to return the `pdf` view with `return new
|
||||
ModelAndView("pdf", map);`, and reload the URL in your application. This time a PDF
|
||||
document should appear listing each of the words in the model map.
|
||||
A controller may return such a view either from an external view definition
|
||||
(referencing it by name) or as a `View` instance from the handler method.
|
||||
|
||||
|
||||
|
||||
[[mvc-view-document-pdf]]
|
||||
=== Excel views
|
||||
|
||||
Since Spring Framework 4.2,
|
||||
`org.springframework.web.servlet.view.document.AbstractXlsView` is provided as a base
|
||||
class for Excel views based on POI, with specialized subclasses `AbstractXlsxView`
|
||||
and `AbstractXlsxStreamingView`, superseding the outdated `AbstractExcelView` class.
|
||||
|
||||
The programming model is similar to `AbstractPdfView`, with `buildExcelDocument()`
|
||||
as the central template method and controllers being able to return such a view from
|
||||
an external definition (by name) or as a `View` instance from the handler method.
|
||||
|
||||
|
||||
|
||||
|
@ -2014,16 +1891,16 @@ document should appear listing each of the words in the model map.
|
|||
|
||||
|
||||
[[mvc-view-json-mapping]]
|
||||
=== JSON
|
||||
=== Jackson-based JSON views
|
||||
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same in Spring WebFlux>>#
|
||||
|
||||
The `MappingJackson2JsonView` uses the Jackson library's `ObjectMapper` to render the response
|
||||
content as JSON. By default, the entire contents of the model map (with the exception of
|
||||
framework-specific classes) will be encoded as JSON. For cases where the contents of the
|
||||
map need to be filtered, users may specify a specific set of model attributes to encode
|
||||
via the `RenderedAttributes` property. The `extractValueFromSingleKeyModel` property may
|
||||
also be used to have the value in single-key models extracted and serialized directly
|
||||
rather than as a map of model attributes.
|
||||
via the `modelKeys` property. The `extractValueFromSingleKeyModel` property may also be
|
||||
used to have the value in single-key models extracted and serialized directly rather than
|
||||
as a map of model attributes.
|
||||
|
||||
JSON mapping can be customized as needed through the use of Jackson's provided
|
||||
annotations. When further control is needed, a custom `ObjectMapper` can be injected
|
||||
|
@ -2033,7 +1910,7 @@ serializers/deserializers need to be provided for specific types.
|
|||
|
||||
|
||||
[[mvc-view-xml-mapping]]
|
||||
=== XML
|
||||
=== Jackson-based XML views
|
||||
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same in Spring WebFlux>>#
|
||||
|
||||
The `MappingJackson2XmlView` uses the
|
||||
|
@ -2051,11 +1928,11 @@ serializers/deserializers need to be provided for specific types.
|
|||
|
||||
|
||||
[[mvc-view-xml-marshalling]]
|
||||
== XML
|
||||
== XML marshalling
|
||||
|
||||
The `MarshallingView` uses an XML `Marshaller` defined in the `org.springframework.oxm`
|
||||
package to render the response content as XML. The object to be marshalled can be set
|
||||
explicitly using ``MarhsallingView``'s `modelKey` bean property. Alternatively, the view
|
||||
explicitly using ``MarshallingView``'s `modelKey` bean property. Alternatively, the view
|
||||
will iterate over all model properties and marshal the first type that is supported
|
||||
by the `Marshaller`. For more information on the functionality in the
|
||||
`org.springframework.oxm` package refer to the chapter
|
||||
|
@ -2065,7 +1942,7 @@ by the `Marshaller`. For more information on the functionality in the
|
|||
|
||||
|
||||
[[mvc-view-xslt]]
|
||||
== XSLT
|
||||
== XSLT views
|
||||
|
||||
XSLT is a transformation language for XML and is popular as a view technology within web
|
||||
applications. XSLT can be a good choice as a view technology if your application
|
||||
|
@ -2084,9 +1961,8 @@ document ready for transformation.
|
|||
[[mvc-view-xslt-beandefs]]
|
||||
=== Beans
|
||||
|
||||
Configuration is standard for a simple Spring application.
|
||||
The MVC configuration has to define a `XsltViewResolver` bean and
|
||||
regular MVC annotation configuration.
|
||||
Configuration is standard for a simple Spring web application: The MVC configuration
|
||||
has to define an `XsltViewResolver` bean and regular MVC annotation configuration.
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
|
@ -2103,7 +1979,6 @@ public class WebConfig implements WebMvcConfigurer {
|
|||
viewResolver.setSuffix(".xslt");
|
||||
return viewResolver;
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
@ -2115,7 +1990,7 @@ And we need a Controller that encapsulates our word generation logic.
|
|||
=== Controller
|
||||
|
||||
The controller logic is encapsulated in a `@Controller` class, with the
|
||||
handler method being defined like so...
|
||||
handler method being defined as follows:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
|
@ -2125,7 +2000,6 @@ handler method being defined like so...
|
|||
|
||||
@RequestMapping("/")
|
||||
public String home(Model model) throws Exception {
|
||||
|
||||
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
|
||||
Element root = document.createElement("wordList");
|
||||
|
||||
|
@ -2140,7 +2014,6 @@ handler method being defined like so...
|
|||
model.addAttribute("wordList", root);
|
||||
return "home";
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
|
Loading…
Reference in New Issue