Spring MVC代码实例系列-04:通过自定义视图(继承InternalResourceView),实现既能解析Jsp页面又能解析Html页面的目的

超级通道 :Spring MVC代码实例系列-绪论

本章主要讲解了如何通过自定义视图,达到项目既能解析Jsp页面又能解析Html页面的目的。主要涉及的技术有:
- InternalResourceViewResolver : 内部资源视图解析器,一般用来处理系统的视图解析。
- InternalResourceView : 内部资源视图,InternalResourceViewResolver 默认使用的视图。
- AbstractUrlBasedView : 抽象URL基础视图,InternalResourceView 的父类。
- checkResource : AbstractUrlBasedView的方法,判断资源是否存在。
- viewClass : InternalResourceViewResolver的一个配置属性,用来注入使用哪个视图。
- mvc:resources : Spring MVC中用来设置静态资源的xml配置项。

1.原始场景

  • 目标项目之前都是用Jsp作为前端页面。在当前的开发中,因为某种需求,需要在项目中添加几个Html页面。
  • 如果只是简单的浏览这些Html页面,则通过mvc:resources配置即可达到目的。
  • 但是,业务中也存在通过方法跳转Html页面的需求,若果不做其他处理,只能通过InternalResourceViewResolver跳转到Jsp页面。
    当前的spring-mvc-servlet.xml配置如下:
<!--默认视图解析器:jsp-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
</bean>

2.添加自定义视图,并配置Html视图解析器

2.1.定义一个Html资源视图:

package pers.hanchao.hespringmvc.htmlviewresolver;

import org.springframework.web.servlet.view.InternalResourceView;

import java.io.File;
import java.util.Locale;

/**
 * <p>定义一个Html视图,重写了checkResource方法</p>
 * @author hanchao 2018/1/18 21:57
 **/
public class HtmlResourceView extends InternalResourceView{
    /**
     * <p>AbstractUrlBasedView中的checkResource永远都返回true,表示视图存在,不会再进入其他的视图解析器。
     * 重写了checkResource方法,若当前视图无法解析,则返回false,使之能够进入下一个视图。</p>
     * @author hanchao 2018/1/18 21:58
     **/
    @Override
    public boolean checkResource(Locale locale) throws Exception {
        File file = new File(this.getServletContext().getRealPath("/") + getUrl());
        return file.exists();
    }
}

2.2.配置视图解析器

    <!--自定义视图解析器:html-->
    <bean id="htmlViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="pers.hanchao.hespringmvc.htmlviewresolver.HtmlView"/>
        <property name="prefix" value="/"/>
        <property name="suffix" value=".html"/>
        <property name="order" value="0"/>
        <property name="contentType" value="text/html;charset=UTF-8"></property>
    </bean>
    <!--默认视图解析器:jsp-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
        <property name="order" value="1"/>
    </bean>

其中:

  1. order : 视图加载先后顺序,越小越先加载。
  2. 其实默认视图解析器和自定义视图解析器都是InternalResourceViewResolver,只是使用的viewClass不一样,前者是InternalResourceView,后者是HtmlResourceView

2.3.定义静态资源

不要忘记将Html页面所在路径配置到mvc:resources配置中:

<mvc:resources mapping="/htmlviewresolver/**" location="/htmlviewresolver/" cache-period="31536000"/>

3.运行实例

3.1.程序目录

src
\---main
    \---java
    |   \---pers
    |       \---hanchao
    |           \---hespringmvc
    |               \---htmlviewresolver
    |                   \---HtmlResourceView.java
    |                   \---MultiViewController.java
    \---resources
    |   \---applicationcontext.xml
    \---webapp
        \---htmlviewresolver
        |   \---index.jsp
        |   \---hellojsp.jsp
        |   \---hellohtml.html
        \---WEB-INF
        |   \---spring-mvc-servlet.xml
        |   \---web.xml
        \---index.jsp

3.2.MultiViewController.java

package pers.hanchao.hespringmvc.htmlviewresolver;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * <p>一个多种页面跳转的实例</p>
 * @author hanchao 2018/1/18 22:06
 **/
@Controller
@RequestMapping("/htmlviewresolver")
public class MultiViewController {
    /**
     * <p>跳转到jsp页面</p>
     * @author hanchao 2018/1/18 22:07
     **/
    @GetMapping("/returnjsp")
    public String getJsp(){
        return "htmlviewresolver/hellojsp";
    }

    /**
     * <p>跳转到html页面</p>
     * @author hanchao 2018/1/18 22:07
     **/
    @GetMapping("/returnhtml")
    public String getHtml(){
        return "htmlviewresolver/hellohtml";
    }

}

3.3.index.jsp

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/1/18
  Time: 21:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>多视图解析器</title>
</head>
<body>
<a href="/htmlviewresolver/returnhtml">解析成HTML页面</a><br/>
<a href="/htmlviewresolver/returnjsp">解析成JSP页面</a>
</body>
</html>

3.4.hellohtml.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Html Page</title>
</head>
<body>
<h3>Hello World! This is a html page.</h3>
</body>
</html>

3.5.hellojsp.jsp

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/1/18
  Time: 21:29
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Jsp Page</title>
</head>
<body>
<h3>Hello World! This is a jsp page.</h3>
</body>
</html>

3.6.result

这里写图片描述

4.进一步优化

仔细分析上面的代码,发现有两点可以优化:
1. HtmlResourceView:它是为了解析HTML页面才出现的,但是它跟html页面并没有关系,它存在的意义只是让视图解析器能够连续解析。所以HtmlResourceView完全可以用在其他解析器上。
2. 解析器顺序:分析上面的解析过程会发现,每一个View被DispatcherServlet处理时,都会首先经过Html视图解析器的解析。如果解析失败,继续进入Jsp视图解析器进行解析,直到解析完成。而当前项目之前是一个Jsp项目,存在大量的Jsp页面和较少的Html页面。使用这种解析机制,会导致所有的Jsp页面都进行两次解析,资源浪费严重。完全可以先使用Jsp解析器,在使用Html解析器。
下面进行优化:

4.1.HtmlResourceView–>ContinueResourceView

Continue即连续的意思。

package pers.hanchao.hespringmvc.htmlviewresolver;

import org.springframework.web.servlet.view.InternalResourceView;

import java.io.File;
import java.util.Locale;

/**
 * <p>定义一个Html视图,重写了checkResource方法,实现解析器的连续解析</p>
 * @author hanchao 2018/1/18 21:57
 **/
public class ContinueResourceView extends InternalResourceView{
    /**
     * <p>AbstractUrlBasedView中的checkResource永远都返回true,表示视图存在,不会再进入其他的视图解析器。
     * ContinueResourceView重写了checkResource方法,若当前视图无法解析,则返回false,使之能够进入下一个视图。</p>
     * @author hanchao 2018/1/18 21:58
     **/
    @Override
    public boolean checkResource(Locale locale) throws Exception {
        File file = new File(this.getServletContext().getRealPath("/") + getUrl());
        return file.exists();
    }
}

4.2.替换Html和Jsp视图解析器的顺序

记得修改order的大小。

<!--自定义视图解析器:html-->
<bean id="htmlViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".html"/>
    <property name="order" value="1"/>
    <property name="contentType" value="text/html;charset=UTF-8"></property>
</bean>
<!--默认视图解析器:jsp-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="pers.hanchao.hespringmvc.htmlviewresolver.ContinueResourceView"/>
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>
    <property name="order" value="0"/>
</bean>

运行结果与前面一直,不在赘述。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值