Spring框架 - Web框架 View解析

本文介绍Spring MVC中View解析的过程及配置方法,包括InernalResourceViewResolver、FreeMarkerViewResolver和ContentNegotiatingViewResolver的使用。

View解析

定义请求处理函数可以返回不同内容,这几类都是有View相关的线索

  • String:名称
  • View
  • ModelAndView

而下面这类并没有View的信息,只返回的Map和Model

  • Map
  • Model

View解析过程

首先每个项目都会有ViewResolver,ViewResolver是把函数处理结果返回的View名称,需要把View名称与视图展示的模板、JSP文件等等关联起来。ViewResolver的输出就是View。有时候我们要展示网页,有时候返回Json的数据,有时候返回PDF文件。

输入图片说明

View解析

ViewResolver是抽象接口,可以定义不同的ViewResolver接口。

InernalResourceViewResolver

例如JSP可以用Spring提供的InernalResourceViewREsolver,可以通过一些配置告诉Spring在碰到一些View名称时,会根据Resolver的路径设置,把View名称转换到本地JSP的文件。

FreeMarkerViewResolver

也有FreeMarkerViewResolver,FreeMarker是模板引擎,可以通过类似于JSP,FreeMarker可以在模板文件中定义变量,在返回View时,可以把和View相关的数据进行返回。可以在FreeMarker的模板文件中引用所返回的数据。

ContentNegotiatingViewResolver

字面意思为内容协商ViewResolver,就是指并不是固定的ViewResolver,是多种ViewResolver的组合。可以处理不同的View解析的需要。可以把多个ViewResolver都配置到ContentNegotiatingViewResolver,根据客户端传递给不同内容的Resolver返回不同的View

输入图片说明

ViewResolver基本配置

InernalResourceViewResolver

  • Servlet,JSP
  • 基本配置
    可以看到有两个属性,prefix是指要解析的文件在项目的什么位置,而suffix指要解析的文件后缀,如下例子是.jsp。
  • 处理结果
    我们通过String或者View返回相关的View对象,例如resultView,是View的名称,最终要渲染或者访问的资源是如下结果/WEB-INF/jsp/resultView.jsp,会把我们之前在ViewResolver定义的prefix和view名称+后缀名称组合起来。形成完整路径。之后把内容返回给客户端,客户端显示JSP内容。
<!-- 定义JSP文件的位置 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

FreeMarkerViewResolver

  • FreeMarker
    是针对FreeMarker模板引擎,提供的对象就是FreeMarker模板引擎
  • 基本配置
    要是使用FreeMarkerViewResolver的需要定义跟FreeMarker相关的配置,这里配置是配置类FreeMarker的路径,这样告诉FreeMarker在碰到View解析需求的时候,去/WEB-INF/freemarker目录查找freemarker相关的模板。
    下面就定义prefix、suffix,这里prefix已经在config配置了路径。cache的值是是否重新查找映射结果。
  • 处理结果
    resultView的处理结果为/WEB-INF/freemarker/resultView.ftl
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
      <property name="templateLoaderPath" value="/WEB-INF/freemarker" />
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResovler">
    <property name="cache" value="true" />
    <property name="prefix" value="" />
    <property name="suffix" value=".ftl" />
</bean>

ContentNegotiatingViewResolver

  • ViewResolver的组合

  • 根据扩展名:user.json、user.xml、user.pdf

  • 也可以根据Accept头(media types):application/json,application/xml
    可以根据Request的媒体类型

  • 配置
    需要配置viewResolver,也就是说我们在view名称时,我们会碰到viewResolver进行解析。需要注意的是defaultViews的属性。配置了一个MappingJackson2JsonView,是一个Json的View。defaultViews是当如果通过viewResolver,没有办法进行处理,比如找不到view名称关联的模板文件。这时候通过defaultView处理返回结果。defaultView不指定prefix、suffix。会忽略view名称,直接解析成json数据。

<bean class="org.springframework.web.serlvet.view.ContentNegotiatingViewResolver">
    <property name="viewResolvers">
        <list>
            <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" />
            </bean>
        </list>
    </property>

    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
        </list>
    </property>
</bean>

处理非View的Model

DefaultRequestToViewNameTranslator

客户端请求地址是example/display.html,当在处理这个请求时,函数没有返回View相关的名称,会进行请求地址转换为display,作为返回的view。
另外一个示例是exmaple/admin/index.html,默认会转换成admin/index,这里都是把应用名称的example当做前缀,后面的.html当做后缀。中间的部分就是请求的view名称。

代码示例

之前的Login改装,成FreeMarker,并且ViewResolver使用ContentNegotiatingViewResolver。

创建freemarker模板文件

在/WEB-INF下创建freemarker目录,在目录中创建文件login_user.ftl,内容如下:

<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <title>用户信息</title>
</head>
<body>
    <p>FreeMarker通过如下方式引用Model的数据</p>
    <p>Username:${username}</p>
    <p>Password:${password}</p>
</body>
</html>

在Spring配置中添加配置


	<mvc:annotation-driven />

	<!-- FreeMarket在这里进行prefix的设置 -->
	<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPath" value="/WEB-INF/freemarker" />
	</bean>

	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		<property name="viewResolvers">
			<!-- FreeMarker ViewResolver -->
			<bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
				<property name="cache" value="true" />
				<property name="suffix" value=".ftl" />
				<property name="prefix" value="" />
				<property name="contentType" value="text/html; charset=utf-8" />
			</bean>
			<!-- 这里还可以添加JSP的viewResolver -->
		</property>
		<property name="defaultViews">
			<list>
				<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
				<!-- 可以添加更多的XML、PDF等 -->
			</list>
		</property>
	</bean>

修改Login的函数返回

    @RequestMapping(value = "/user_login/login")
    public String login2(@RequestParam("username") String username,
                         @RequestParam("password") String password,
                         @RequestHeader("host") String host,
                         ModelMap modelMap) throws IOException{
        System.out.println("username:" + username);
        System.out.println("password:" + password);

        // 向ModelMap添加内容
        modelMap.addAttribute("username",username);
        modelMap.addAttribute("password",password);

        //由于没有@ResponseBody,则返回的是View
        return "login_user";
    }

**注意:**如果发生异常,则需要去服务器后端进输出行查看

添加FreeMarker的依赖

添加SpringFramework-context-support,该包包含与第三方工具的整合。例如缓存框架、其他视图框架。

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>4.3.3.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.4</version>
		</dependency>

Chrome运行结果

FreeMarker閫氳繃濡備笅鏂瑰紡寮曠敤Model鐨勬暟鎹�/p>

Username锛�123

Password锛�456

中文字符乱码问题

注意如果freemarker发生了中文字符乱码,可能是由很多问题导致的Tomcat与FreeMarker的设置,Resolver的设置有关。
**注意:**虽然课程中讲到在FreeMarkerViewResolver中添加,但是本人在实际解决是在Config中添加的配置

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPath" value="/WEB-INF/freemarker" />
		<property name="freemarkerSettings">
			<props>
				<prop key="defaultEncoding">utf8</prop>
			</props>
		</property>
	</bean>

	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		<property name="viewResolvers">
			<!-- FreeMarker ViewResolver -->
			<bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
				<property name="cache" value="true" />
				<property name="suffix" value=".ftl" />
				<property name="prefix" value="" />
				<property name="contentType" value="text/html; charset=utf-8" />
			</bean>
			<!-- 这里还可以添加JSP的viewResolver -->
		</property>
		<property name="defaultViews">
			<list>
				<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
				<!-- 可以添加更多的XML、PDF等 -->
			</list>
		</property>
	</bean>

返回的结果

FreeMarker通过如下方式引用Model的数据

Username:123

Password:456

#没有返回的View,或者找不到View 当我们返回没有添加user,没有指定view,则返回的是json文件

{"password":"456","username":"123"}

转载于:https://my.oschina.net/hava/blog/777783

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值