public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception; }
public interface View { String getContentType(); void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception; }
@Configuration @EnableWebMvc @ComponentScan(basePackages={"com.spring.chapter5.spittr.web", "com.spring.chapter5.spittr.data"}) public class WebConfig extends WebMvcConfigurerAdapter { @Bean public ViewResolver viewResolver() { // highlight line. InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setExposeContextBeansAsAttributes(true); return resolver; } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }
@Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class); return resolver; }
<bean id="viewResolver" class="org.springframework.web.servlet.view. InternalResourceViewResolver" p:prefix="/WEB-INF/views/" p:suffix=".jsp" p:viewClass="org.springframework.web.servlet.view.JstlView" /> <span style="font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);"> </span>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
3)在注册JSP 中使用这些标签后,会得到如下程序:<sf:form method="POST" commandName="spitter">
First Name: <sf:input path="firstName" /><br /> Last Name: <sf:input path="lastName" /><br /> Email: <sf:input path="email" /><br /> Username: <sf:input path="username" /><br /> Password: <sf:password path="password" /><br /> <input type="submit" value="Register" /> </sf:form>
Email: <sf:input path="email" type="email" /><br/>
Email: <input id="email" name="email" type="email" value="jack"/><br/>
<sf:form method="POST" commandName="spitter"> First Name: <sf:input path="firstName" /> <sf:errors path="firstName" /><br/> ... </sf:form>
First Name: <input id="firstName" name="firstName" type="text" value="J"/> <span id="firstName.errors">size must be between 2 and 30</span>
<sf:form method="POST" commandName="spitter"> First Name: <sf:input path="firstName" /> <sf:errors path="firstName" cssClass="error" /> <br /> ... </sf:form>
span.error { color: red; }
<sf:form method="POST" commandName="spitter" > <sf:errors path="*" element="div" cssClass="errors" /> ... </sf:form>
<sf:form method="POST" commandName="spitter"> <sf:label path="firstName" cssErrorClass="error">First Name</sf:label>: <sf:input path="firstName" cssErrorClass="error" /> <br /> ... </sf:form>
<label for="firstName" class="error">First Name</label>
label.error { color: red; } input.error { }
firstName.size=First name must be between {min} and {max} characters long. lastName.size=Last name must be between {min} and {max} characters long. username.size=Username must be between {min} and {max} characters long. password.size=Password must be between {min} and {max} characters long. email.valid=The email address must be valid.
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<h1>Welcome to Spittr!</h1>
<h1><s:message code="spittr.welcome" /></h1>
@Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); // 核心在于设置basename属性值. return messageSource; }
@Bean public MessageSource messageSource() { ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasename("file:///etc/spittr/messages"); messageSource.setCacheSeconds(10); return messageSource; }
<a href="/spittr/spitter/register">Register</a>
<s:url href="/spitter/register" var="registerUrl" /> <a href="${registerUrl}">Register</a>
<s:url href="/spitter/register" var="registerUrl" scope="request" />
<s:url href="/spittles" var="spittlesUrl"> <s:param name="max" value="60" /> <s:param name="count" value="20" /> </s:url>
<s:url href="/spitter/{username}" var="spitterUrl"> <s:param name="username" value="jbauer" /> </s:url>
<s:url value="/spittles" htmlEscape="true"> <s:param name="max" value="60" /> <s:param name="count" value="20" /> </s:url> 所渲染得到的结果为: /spitter/spittles?max=60&count=20
<s:url value="/spittles" var="spittlesJSUrl" javaScriptEscape="true"> <s:param name="max" value="60" /> <s:param name="count" value="20" /> </s:url> <script> var spittlesUrl = "${spittlesJSUrl}" </script> 渲染得到的结果为: <script> var spittlesUrl = "\/spitter\/spittles?max=60&count=20" </script>
<s:escapeBody htmlEscape="true"> <h1>Hello</h1> </s:escapeBody> 所渲染得到的结果为: <h1>Hello</h1>
<s:escapeBody javaScriptEscape="true"> <h1>Hello</h1> </s:escapeBody>
@Bean public TilesConfigurer tilesConfigurer() { TilesConfigurer tiles = new TilesConfigurer(); tiles.setDefinitions(new String[] { "/WEB-INF/layout/tiles.xml" }); tiles.setCheckRefresh(true); return tiles; }
tiles.setDefinitions(new String[] { "/WEB-INF/**/tiles.xml" });
@Bean public ViewResolver viewResolver() { return new TilesViewResolver(); }
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer"> <property name="definitions"> <list> <value>/WEB-INF/layout/tiles.xml.xml</value> <value>/WEB-INF/views/**/tiles.xml</value> </list> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver" />
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd"> <tiles-definitions> <definition name="base" template="/WEB-INF/layout/page.jsp"> <put-attribute name="header" value="/WEB-INF/layout/header.jsp" /> <put-attribute name="footer" value="/WEB-INF/layout/footer.jsp" /> </definition> <definition name="home" extends="base"> // hightlight line: 这里用到了继承,碉堡了. <put-attribute name="body" value="/WEB-INF/views/home.jsp" /> </definition> <definition name="registerForm" extends="base"> <put-attribute name="body" value="/WEB-INF/views/registerForm.jsp" /> </definition> <definition name="profile" extends="base"> <put-attribute name="body" value="/WEB-INF/views/profile.jsp" /> </definition> <definition name="spittles" extends="base"> <put-attribute name="body" value="/WEB-INF/views/spittles.jsp" /> </definition> <definition name="spittle" extends="base"> <put-attribute name="body" value="/WEB-INF/views/spittle.jsp" /> </definition> </tiles-definitions>
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %> <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="t" %> <%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %> <%@ page session="false" %> <html> <head> <title>Spittr</title> <link rel="stylesheet" type="text/css" href="<s:url value="/resources/style.css" />" > </head> <body> <div id="header"> <t:insertAttribute name="header" /> </div> <div id="content"> <t:insertAttribute name="body" /> </div> <div id="footer"> <t:insertAttribute name="footer" /> </div> </body> </html>
@Bean public ViewResolver viewResolver(SpringTemplateEngine templateEngine) { ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setTemplateEngine(templateEngine); return viewResolver; } @Bean public TemplateEngine templateEngine(TemplateResolver templateResolver) { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver); return templateEngine; } @Bean public TemplateResolver templateResolver() { TemplateResolver templateResolver = new ServletContextTemplateResolver(); templateResolver.setPrefix("/WEB-INF/templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode("HTML5"); return templateResolver; }
<bean id="viewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver" p:templateEngine-ref="templateEngine" /> <bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine" p:templateResolver-ref="templateResolver" /> <bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver" p:prefix="/WEB-INF/templates/" p:suffix=".html" p:templateMode="HTML5" />
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <title>Spittr</title> <link rel="stylesheet" type="text/css" th:href="@{/resources/style.css}"></link> </head> <body> <h1>Welcome to Spittr</h1> <a th:href="@{/spittles}">Spittles</a> | <a th:href="@{/spitter/register}">Register</a> </body> </html>
<sf:label path="firstName" cssErrorClass="error">First Name</sf:label>: <sf:input path="firstName" cssErrorClass="error" /><br/>
2)考虑如下的 Thymeleaf模板片段,它会渲染first name输入域:
<label th:class="${#fields.hasErrors('firstName')}? 'error'"> First Name</label>: <input type="text" th:field="*{firstName}" th:class="${#fields.hasErrors('firstName')}? 'error'" /><br/>
对以上代码分析(Analysis):
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form method="POST" th:object="${spitter}"><div class="errors" th:if="${#fields.hasErrors('*')}"> <ul> <li th:each="err : ${#fields.errors('*')}" th:text="${err}">Input is incorrect</li> </ul> Listing 6.7 Registration page, using Thymeleaf to bind a form to a command object Display errors 192 CHAPTER 6 Rendering web views </div> <label th:class="${#fields.hasErrors('firstName')}? 'error'"> First Name</label>: <input type="text" th:field="*{firstName}" th:class="${#fields.hasErrors('firstName')}? 'error'" /><br /> <label th:class="${#fields.hasErrors('lastName')}? 'error'"> Last Name</label>: <input type="text" th:field="*{lastName}" th:class="${#fields.hasErrors('lastName')}? 'error'" /><br /> <label th:class="${#fields.hasErrors('email')}? 'error'"> Email</label>: <input type="text" th:field="*{email}" th:class="${#fields.hasErrors('email')}? 'error'" /><br /> <label th:class="${#fields.hasErrors('username')}? 'error'"> Username</label>: <input type="text" th:field="*{username}" th:class="${#fields.hasErrors('username')}? 'error'" /><br /> <label th:class="${#fields.hasErrors('password')}? 'error'"> Password</label>: <input type="password" th:field="*{password}" th:class="${#fields.hasErrors('password')}? 'error'" /><br /> <input type="submit" value="Register" /> </form> </body> </html>