第6章 渲染Web视图

6.1 理解视图解析

  我们所编写的控制器方法都没有直接产生浏览器中渲染所需的 HTML 。这些方法只是将一些数据填充到模型中,然后将模型传递给一个用来渲染的视图。这些方法会返回一个 String 类型的值,这个值是视图的逻辑名称,不会直接引用具体的视图实现。尽管我们也编写了几个简单的 JavaServer Page ( JSP )视图,但是控制器并不关心这些。

  将控制器中请求处理的逻辑和视图中的渲染实现解耦是 Spring MVC 的一个重要特性。如果控制器中的方法直接负责产生 HTML 的话,就很难在不影响请求处理逻辑的前提下,维护和更新视图。控制器方法和视图的实现会在模型内容上达成一致,这是两者的最大关联,除此之外,两者应该保持足够的距离。

  但是,如果控制器只通过逻辑视图名来了解视图的话,那 Spring 该如何确定使用哪一个视图实现来渲染模型呢?这就是 Spring 视图解析器的任务了。

 

 

6.2 解析jsp视图

//配置视图解析器
@Bean
public ViewResolver viewResolver(){
   InternalResourceViewResolver resourceViewResolver = new InternalResourceViewResolver();
   resourceViewResolver.setPrefix("/WEB-INF/views/");
   resourceViewResolver.setSuffix(".jsp");
   resourceViewResolver.setExposeContextBeansAsAttributes(true);
   return resourceViewResolver;
}

解析 JSTL 视图

如果想让 InternalResourceViewResolver 将视图解析为 JstlView ,而不是 InternalResourceView 的话,那么我们只需设置它的 viewClass 属性即可:

 

6.3 解析thymeleaf视图

需要导入除了spring包之外的包

<dependency>
   <groupId>org.thymeleaf</groupId>
   <artifactId>thymeleaf</artifactId>
   <version>3.0.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring4 -->
<dependency>
   <groupId>org.thymeleaf</groupId>
   <artifactId>thymeleaf-spring4</artifactId>
   <version>3.0.9.RELEASE</version>
</dependency>

注意:thymeleaf-spring4,如果用的spring版本不是4需要更换,请参考官网https://www.thymeleaf.org

@Bean
public ViewResolver viewResolver(){
   ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
   viewResolver.setTemplateEngine(templateEngine());
   return viewResolver;
}
@Bean
public TemplateEngine templateEngine(){
   SpringTemplateEngine templateEngine = new SpringTemplateEngine();
   templateEngine.setTemplateResolver(templateResolver());
   return templateEngine;
}
@Bean
public ITemplateResolver templateResolver(){
   SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
   templateResolver.setPrefix("/WEB-INF/templates/");
   templateResolver.setSuffix(".html");
   templateResolver.setTemplateMode("HTML5");
   return templateResolver;
}

ThymeleafViewResolver 是 Spring MVC 中 ViewResolver 的一个实现类。像其他的视图解析器一样,它会接受一个逻辑视图名称,并将其解析为视图。不过在该场景下,视图会是一个 Thymeleaf 模板。

 

需要注意的是 ThymeleafViewResolver bean 中注入了一个对 SpringTemplate Engine bean 的引用。 SpringTemplateEngine 会在 Spring 中启用 Thymeleaf 引擎,用来解析模板,并基于这些模板渲染结果。可以看到,我们为其注入了一个 TemplateResolver bean 的引用。

 

TemplateResolver 会最终定位和查找模板。与之前配置 InternalResource-ViewResolver 类似,它使用了 prefix 和 suffix 属性。前缀和后缀将会与逻辑视图名组合使用,进而定位 Thymeleaf 引擎。它的 templateMode 属性被设置成了 HTML 5 ,这表明我们预期要解析的模板会渲染成 HTML 5 输出。

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
</head>
<body>
   <h1>Welcome to Spittr</h1>
   <a th:href="@{/spittles}">Spittles</a>
   <a th:href="@{/spitter/register}">Register</a>
</body>
</html>

 

6.4 解析freemarker视图

需要导入额外包

<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
   <groupId>org.freemarker</groupId>
   <artifactId>freemarker</artifactId>
   <version>2.3.28</version>
</dependency>
<!-- FreeMarker configuration -->
<bean id="freemarkerConfig"
     class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
   <property name="templateLoaderPath" value="/WEB-INF/freemarker/" />
   <property name="defaultEncoding" value="UTF-8" />
   <!-- user-defined directives -->
   <property name="freemarkerVariables">
       <map>
           <entry key="schoolDirective" value-ref="schoolDirectiveModel" />
           <entry key="headerNavigationDirective" value-ref="headerNavigationDirectiveModel" />
           <entry key="footerNavigationDirective" value-ref="footerNavigationDirectiveModel" />

           <entry key="headerImageDirective" value-ref="headerImageDirectiveModel" />
           <entry key="categoryDirective" value-ref="categoryDirectiveModel" />
           <entry key="announcementDirective" value-ref="announcementDirectiveModel" />
           <entry key="courseDirective" value-ref="courseDirectiveModel" />
           <entry key="latestOrdersDirective" value-ref="latestOrdersDirectiveModel" />
           <entry key="liveCourseDirective" value-ref="liveCourseDirectiveModel" />
           <entry key="newsDirective" value-ref="newsDirectiveModel" />
           <entry key="questionDirective" value-ref="questionDirectiveModel" />
           <entry key="latestReviewDirective" value-ref="latestReviewDirectiveModel" />
           <entry key="latestUserDirective" value-ref="latestUserDirectiveModel" />
           <entry key="columnCourseDirective" value-ref="columnCourseDirectiveModel" />
           <entry key="youLikeDirective" value-ref="youLikeDirectiveModel" />
           <entry key="vipCourseDirective" value-ref="vipCourseDirectiveModel" />

           <entry key="prettyTime" value-ref="prettyTimeMethodModel" />
           <entry key="prettyFileSize" value-ref="prettyFileSizeMethodModel" />
           <entry key="progress" value-ref="progressMethodModel" />

           <entry key="cleanHtml" value-ref="cleanHtmlMethodModel" />
           <entry key="completeLecturesDirective" value-ref="completeLecturesDirectiveModel" />
           <entry key="userRoleDirective" value-ref="userRoleDirectiveModel" />
       </map>
   </property>
   <!-- FreeMarker setting -->
   <property name="freemarkerSettings">
       <props>
           <prop key="number_format">#</prop> <!-- 数字不包含逗号 -->
           <prop key="template_exception_handler">com.school.freemarker.MissingValuesTemplateExceptionHandler
           </prop>
       </props>
   </property>
</bean>

<!-- Resolves view names to protected .ftl resources within the /WEB-INF/freemarker
       directory -->
<bean id="viewResolver"
     class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
   <property name="cache" value="true" />
   <property name="prefix" value="" />
   <property name="suffix" value=".ftl" />
   <property name="contentType" value="text/html;charset=UTF-8" />
   <property name="exposeSpringMacroHelpers" value="true" />
   <property name="exposeRequestAttributes" value="true" />
   <property name="exposeSessionAttributes" value="true" />
</bean>

 

posted @ 2018-07-10 10:03  Bug的梦魇  阅读(378)  评论(0编辑  收藏  举报