Browse Source

Revised documentation for PDF, Excel and JSON views

Issue: SPR-17180
Issue: SPR-17182
pull/1929/head
Juergen Hoeller 6 years ago
parent
commit
c0c9e08bf9
  1. 2
      spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java
  2. 211
      src/docs/asciidoc/web/webmvc-view.adoc

2
spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java

@ -149,7 +149,7 @@ public class MappingJackson2JsonView extends AbstractJackson2View { @@ -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
*/

211
src/docs/asciidoc/web/webmvc-view.adoc

@ -22,8 +22,8 @@ extensive set of features that will make such a transition easier. Thymeleaf is @@ -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 @@ -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: @@ -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 @@ -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 @@ -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. @@ -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));
}
}
}
----
[[mvc-view-document-pdf]]
=== PDF views
And the following is a view generating the same Excel file, now using JExcelApi:
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 excel;
public class PdfWordList extends AbstractPdfView {
// imports omitted for brevity
public class HomePage extends AbstractJExcelView {
protected void buildExcelDocument(Map model, WritableWorkbook wb,
protected void buildPdfDocument(Map<String, Object> model, Document doc, PdfWriter writer,
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)));
List<String> words = (List<String>) model.get("wordList");
for (String word : words) {
doc.add(new Paragraph(word));
}
}
}
----
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.
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-configsubclasspdf]]
=== 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
`buildPdfDocument()` method as follows:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
package pdf;
// imports omitted for brevity
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)));
}
}
[[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.
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.
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. @@ -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. @@ -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. @@ -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 @@ -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. @@ -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 { @@ -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. @@ -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... @@ -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... @@ -2140,7 +2014,6 @@ handler method being defined like so...
model.addAttribute("wordList", root);
return "home";
}
}
----

Loading…
Cancel
Save