@@ -22,8 +22,8 @@ extensive set of features that will make such a transition easier. Thymeleaf is
22
22
developed and maintained. For a more complete introduction see the
23
23
http://www.thymeleaf.org/[Thymeleaf] project home page.
24
24
25
- The Thymeleaf integration with Spring MVC is managed by the Thymeleaf project. The
26
- configuration involves a few bean declarations such as
25
+ The Thymeleaf integration with Spring MVC is managed by the Thymeleaf project.
26
+ The configuration involves a few bean declarations such as
27
27
`ServletContextTemplateResolver`, `SpringTemplateEngine`, and `ThymeleafViewResolver`.
28
28
See http://www.thymeleaf.org/documentation.html[Thymeleaf+Spring] for more details.
29
29
@@ -941,9 +941,8 @@ The preceding JSP assumes that the variable name of the form backing object is
941
941
==== The input tag
942
942
943
943
This tag renders an HTML 'input' tag using the bound value and type='text' by default.
944
- For an example of this tag, see <<mvc-view-jsp-formtaglib-formtag>>. Starting with Spring
945
- 3.1 you can use other types such HTML5-specific types like 'email', 'tel', 'date', and
946
- others.
944
+ For an example of this tag, see <<mvc-view-jsp-formtaglib-formtag>>. You may also use
945
+ HTML5-specific types like 'email', 'tel', 'date', and others.
947
946
948
947
949
948
[[mvc-view-jsp-formtaglib-checkboxtag]]
@@ -1563,12 +1562,12 @@ The corresponding `@Controller` method is shown below:
1563
1562
[[mvc-view-jsp-formtaglib-html5]]
1564
1563
==== HTML5 tags
1565
1564
1566
- Starting with Spring 3, the Spring form tag library allows entering dynamic attributes,
1567
- which means you can enter any HTML5 specific attributes.
1565
+ The Spring form tag library allows entering dynamic attributes, which means you can
1566
+ enter any HTML5 specific attributes.
1568
1567
1569
- In Spring 3.1, the form input tag supports entering a type attribute other than 'text'.
1570
- This is intended to allow rendering new HTML5 specific input types such as 'email',
1571
- 'date', ' range', and others. Note that entering type='text' is not required since 'text'
1568
+ The form input tag supports entering a type attribute other than 'text'. This is
1569
+ intended to allow rendering new HTML5 specific input types such as 'email', 'date ',
1570
+ 'range', and others. Note that entering type='text' is not required since 'text'
1572
1571
is the default type.
1573
1572
1574
1573
@@ -1801,7 +1800,6 @@ Similar requirements apply for implementing `AbstractRssFeedView`, as shown belo
1801
1800
HttpServletRequest request, HttpServletResponse response) throws Exception {
1802
1801
// implementation omitted
1803
1802
}
1804
-
1805
1803
}
1806
1804
----
1807
1805
@@ -1822,7 +1820,7 @@ https://spring.io/blog/2009/03/16/adding-an-atom-view-to-an-application-using-sp
1822
1820
1823
1821
1824
1822
[[mvc-view-document-intro]]
1825
- === Introduction
1823
+ === Introduction to document views
1826
1824
1827
1825
Returning an HTML page isn't always the best way for the user to view the model output,
1828
1826
and Spring makes it simple to generate a PDF document or an Excel spreadsheet
@@ -1843,166 +1841,45 @@ vulnerability for untrusted PDF content.
1843
1841
1844
1842
1845
1843
1846
- [[mvc-view-document-config]]
1847
- === Configuration
1848
-
1849
- Document based views are handled in an almost identical fashion to XSLT views, and the
1850
- following sections build upon the previous one by demonstrating how the same controller
1851
- used in the XSLT example is invoked to render the same model as both a PDF document and
1852
- an Excel spreadsheet (which can also be viewed or manipulated in Open Office).
1853
-
1854
-
1855
-
1856
- [[mvc-view-document-configviews]]
1857
- === View definition
1858
-
1859
- First, let's amend the views.properties file (or xml equivalent) and add a simple view
1860
- definition for both document types. The entire file now looks like this with the XSLT
1861
- view shown from earlier:
1862
-
1863
- [literal]
1864
- [subs="verbatim,quotes"]
1865
- ----
1866
- home.(class)=xslt.HomePage
1867
- home.stylesheetLocation=/WEB-INF/xsl/home.xslt
1868
- home.root=words
1869
-
1870
- xl.(class)=excel.HomePage
1871
-
1872
- pdf.(class)=pdf.HomePage
1873
- ----
1874
-
1875
- __If you want to start with a template spreadsheet or a fillable PDF form to add your
1876
- model data to, specify the location as the 'url' property in the view definition__
1877
-
1878
-
1879
-
1880
- [[mvc-view-document-configcontroller]]
1881
- === Controller
1882
-
1883
- The controller code we'll use remains exactly the same from the XSLT example earlier
1884
- other than to change the name of the view to use. Of course, you could be clever and
1885
- have this selected based on a URL parameter or some other logic - proof that Spring
1886
- really is very good at decoupling the views from the controllers!
1887
-
1888
-
1889
-
1890
- [[mvc-view-document-configsubclasses]]
1891
- === Excel views
1892
-
1893
- Exactly as we did for the XSLT example, we'll subclass suitable abstract classes in
1894
- order to implement custom behavior in generating our output documents. For Excel, this
1895
- involves writing a subclass of
1896
- `org.springframework.web.servlet.view.document.AbstractExcelView` (for Excel files
1897
- generated by POI) or `org.springframework.web.servlet.view.document.AbstractJExcelView`
1898
- (for JExcelApi-generated Excel files) and implementing the `buildExcelDocument()` method.
1899
-
1900
- Here's the complete listing for our POI Excel view which displays the word list from the
1901
- model map in consecutive rows of the first column of a new spreadsheet:
1902
-
1903
- [source,java,indent=0]
1904
- [subs="verbatim,quotes"]
1905
- ----
1906
- package excel;
1907
-
1908
- // imports omitted for brevity
1909
-
1910
- public class HomePage extends AbstractExcelView {
1911
-
1912
- protected void buildExcelDocument(Map model, HSSFWorkbook wb, HttpServletRequest req,
1913
- HttpServletResponse resp) throws Exception {
1914
-
1915
- HSSFSheet sheet;
1916
- HSSFRow sheetRow;
1917
- HSSFCell cell;
1918
-
1919
- // Go to the first sheet
1920
- // getSheetAt: only if wb is created from an existing document
1921
- // sheet = wb.getSheetAt(0);
1922
- sheet = wb.createSheet("Spring");
1923
- sheet.setDefaultColumnWidth((short) 12);
1924
-
1925
- // write a text at A1
1926
- cell = getCell(sheet, 0, 0);
1927
- setText(cell, "Spring-Excel test");
1928
-
1929
- List words = (List) model.get("wordList");
1930
- for (int i=0; i < words.size(); i++) {
1931
- cell = getCell(sheet, 2+i, 0);
1932
- setText(cell, (String) words.get(i));
1933
- }
1934
- }
1935
-
1936
- }
1937
- ----
1844
+ [[mvc-view-document-pdf]]
1845
+ === PDF views
1938
1846
1939
- And the following is a view generating the same Excel file, now using JExcelApi:
1847
+ A simple PDF view for a word list could extend
1848
+ `org.springframework.web.servlet.view.document.AbstractPdfView` and implement the
1849
+ `buildPdfDocument()` method as follows:
1940
1850
1941
1851
[source,java,indent=0]
1942
1852
[subs="verbatim,quotes"]
1943
1853
----
1944
- package excel;
1854
+ public class PdfWordList extends AbstractPdfView {
1945
1855
1946
- // imports omitted for brevity
1947
-
1948
- public class HomePage extends AbstractJExcelView {
1949
-
1950
- protected void buildExcelDocument(Map model, WritableWorkbook wb,
1856
+ protected void buildPdfDocument(Map<String, Object> model, Document doc, PdfWriter writer,
1951
1857
HttpServletRequest request, HttpServletResponse response) throws Exception {
1952
1858
1953
- WritableSheet sheet = wb.createSheet("Spring", 0);
1954
-
1955
- sheet.addCell(new Label(0, 0, "Spring-Excel test"));
1956
-
1957
- List words = (List) model.get("wordList");
1958
- for (int i = 0; i < words.size(); i++) {
1959
- sheet.addCell(new Label(2+i, 0, (String) words.get(i)));
1859
+ List<String> words = (List<String>) model.get("wordList");
1860
+ for (String word : words) {
1861
+ doc.add(new Paragraph(word));
1960
1862
}
1961
1863
}
1962
1864
}
1963
1865
----
1964
1866
1965
- Note the differences between the APIs. We've found that the JExcelApi is somewhat more
1966
- intuitive, and furthermore, JExcelApi has slightly better image-handling capabilities.
1967
- There have been memory problems with large Excel files when using JExcelApi however.
1968
-
1969
- If you now amend the controller such that it returns `xl` as the name of the view (
1970
- `return new ModelAndView("xl", map);`) and run your application again, you should find
1971
- that the Excel spreadsheet is created and downloaded automatically when you request the
1972
- same page as before.
1867
+ A controller may return such a view either from an external view definition
1868
+ (referencing it by name) or as a `View` instance from the handler method.
1973
1869
1974
1870
1975
1871
1976
- [[mvc-view-document-configsubclasspdf]]
1977
- === PDF views
1978
-
1979
- The PDF version of the word list is even simpler. This time, the class extends
1980
- `org.springframework.web.servlet.view.document.AbstractPdfView` and implements the
1981
- `buildPdfDocument()` method as follows:
1982
-
1983
- [source,java,indent=0]
1984
- [subs="verbatim,quotes"]
1985
- ----
1986
- package pdf;
1987
-
1988
- // imports omitted for brevity
1989
-
1990
- public class PDFPage extends AbstractPdfView {
1991
-
1992
- protected void buildPdfDocument(Map model, Document doc, PdfWriter writer,
1993
- HttpServletRequest req, HttpServletResponse resp) throws Exception {
1994
- List words = (List) model.get("wordList");
1995
- for (int i=0; i<words.size(); i++) {
1996
- doc.add( new Paragraph((String) words.get(i)));
1997
- }
1998
- }
1872
+ [[mvc-view-document-pdf]]
1873
+ === Excel views
1999
1874
2000
- }
2001
- ----
1875
+ Since Spring Framework 4.2,
1876
+ `org.springframework.web.servlet.view.document.AbstractXlsView` is provided as a base
1877
+ class for Excel views based on POI, with specialized subclasses `AbstractXlsxView`
1878
+ and `AbstractXlsxStreamingView`, superseding the outdated `AbstractExcelView` class.
2002
1879
2003
- Once again, amend the controller to return the `pdf` view with `return new
2004
- ModelAndView("pdf", map);`, and reload the URL in your application. This time a PDF
2005
- document should appear listing each of the words in the model map .
1880
+ The programming model is similar to `AbstractPdfView`, with `buildExcelDocument()`
1881
+ as the central template method and controllers being able to return such a view from
1882
+ an external definition (by name) or as a `View` instance from the handler method .
2006
1883
2007
1884
2008
1885
@@ -2014,16 +1891,16 @@ document should appear listing each of the words in the model map.
2014
1891
2015
1892
2016
1893
[[mvc-view-json-mapping]]
2017
- === JSON
1894
+ === Jackson-based JSON views
2018
1895
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same in Spring WebFlux>>#
2019
1896
2020
1897
The `MappingJackson2JsonView` uses the Jackson library's `ObjectMapper` to render the response
2021
1898
content as JSON. By default, the entire contents of the model map (with the exception of
2022
1899
framework-specific classes) will be encoded as JSON. For cases where the contents of the
2023
1900
map need to be filtered, users may specify a specific set of model attributes to encode
2024
- via the `RenderedAttributes ` property. The `extractValueFromSingleKeyModel` property may
2025
- also be used to have the value in single-key models extracted and serialized directly
2026
- rather than as a map of model attributes.
1901
+ via the `modelKeys ` property. The `extractValueFromSingleKeyModel` property may also be
1902
+ used to have the value in single-key models extracted and serialized directly rather than
1903
+ as a map of model attributes.
2027
1904
2028
1905
JSON mapping can be customized as needed through the use of Jackson's provided
2029
1906
annotations. When further control is needed, a custom `ObjectMapper` can be injected
@@ -2038,7 +1915,7 @@ Spring Framework 5.1, <<mvc-cors,CORS>> should be used instead.
2038
1915
2039
1916
2040
1917
[[mvc-view-xml-mapping]]
2041
- === XML
1918
+ === Jackson-based XML views
2042
1919
[.small]#<<web-reactive.adoc#webflux-view-httpmessagewriter,Same in Spring WebFlux>>#
2043
1920
2044
1921
The `MappingJackson2XmlView` uses the
@@ -2056,11 +1933,11 @@ serializers/deserializers need to be provided for specific types.
2056
1933
2057
1934
2058
1935
[[mvc-view-xml-marshalling]]
2059
- == XML
1936
+ == XML marshalling
2060
1937
2061
1938
The `MarshallingView` uses an XML `Marshaller` defined in the `org.springframework.oxm`
2062
1939
package to render the response content as XML. The object to be marshalled can be set
2063
- explicitly using ``MarhsallingView ``'s `modelKey` bean property. Alternatively, the view
1940
+ explicitly using ``MarshallingView ``'s `modelKey` bean property. Alternatively, the view
2064
1941
will iterate over all model properties and marshal the first type that is supported
2065
1942
by the `Marshaller`. For more information on the functionality in the
2066
1943
`org.springframework.oxm` package refer to the chapter
@@ -2070,7 +1947,7 @@ by the `Marshaller`. For more information on the functionality in the
2070
1947
2071
1948
2072
1949
[[mvc-view-xslt]]
2073
- == XSLT
1950
+ == XSLT views
2074
1951
2075
1952
XSLT is a transformation language for XML and is popular as a view technology within web
2076
1953
applications. XSLT can be a good choice as a view technology if your application
@@ -2089,9 +1966,8 @@ document ready for transformation.
2089
1966
[[mvc-view-xslt-beandefs]]
2090
1967
=== Beans
2091
1968
2092
- Configuration is standard for a simple Spring application.
2093
- The MVC configuration has to define a `XsltViewResolver` bean and
2094
- regular MVC annotation configuration.
1969
+ Configuration is standard for a simple Spring web application: The MVC configuration
1970
+ has to define an `XsltViewResolver` bean and regular MVC annotation configuration.
2095
1971
2096
1972
[source,java,indent=0]
2097
1973
[subs="verbatim,quotes"]
@@ -2108,7 +1984,6 @@ public class WebConfig implements WebMvcConfigurer {
2108
1984
viewResolver.setSuffix(".xslt");
2109
1985
return viewResolver;
2110
1986
}
2111
-
2112
1987
}
2113
1988
----
2114
1989
@@ -2120,7 +1995,7 @@ And we need a Controller that encapsulates our word generation logic.
2120
1995
=== Controller
2121
1996
2122
1997
The controller logic is encapsulated in a `@Controller` class, with the
2123
- handler method being defined like so...
1998
+ handler method being defined as follows:
2124
1999
2125
2000
[source,java,indent=0]
2126
2001
[subs="verbatim,quotes"]
@@ -2130,7 +2005,6 @@ handler method being defined like so...
2130
2005
2131
2006
@RequestMapping("/")
2132
2007
public String home(Model model) throws Exception {
2133
-
2134
2008
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
2135
2009
Element root = document.createElement("wordList");
2136
2010
@@ -2145,7 +2019,6 @@ handler method being defined like so...
2145
2019
model.addAttribute("wordList", root);
2146
2020
return "home";
2147
2021
}
2148
-
2149
2022
}
2150
2023
----
2151
2024
0 commit comments