SpringMVC--05视图

视图View

springmvc中常用视图

  • InternalResourceView
    • 内部资源视图
    • 是SpringMVC内置的,专门负责解析JSP模板语法,同时也负责转发功能的实现
  • RedirectView
    • 重定向视图
    • 是SpringMVC内置的,专门负责重定向功能实现
  • ThymeleafView
    • 第三方,专门负责解析Thymeleaf模板语法的
    • 使用时注意<html lang="en" xmlns:th="http://www.thymeleaf.org">

实现视图机制的核心类和接口

  • DispatcherServlet
    • 前端控制器
    • 负责接收前端的请求
    • 根据请求路径找到对应的处理器方法
    • 执行处理器方法,并最终返回ModelAndView对象
  • ViewResolver接口
    • 视图解析器接口
    • 将逻辑视图名称转换为物理视图名称(将逻辑名称转换为物理路径),并最终返回一个View接口对象
  • View接口
    • 视图接口
    • 负责将模板语法的字符串转换成html代码,并将html代码响应给浏览器

视图解析流程

下面的各个类|接口都是SpringMVC中源码选取的片段,这些类中方法的执行,反映了底层视图解析的流程

DispatcherServlet类

public class DispatcherServlet extends FrameworkServlet{
    // 前端控制器的核心方法,处理请求,返回视图,渲染视图,都是在这个方法中完成
    protected void doDispatch(HttpServletRequest request,HttpServletResponse response) throws Exception{
        // 根据请求路径调用映射的处理器方法,处理器方法执行结束之后,返回逻辑视图名称
        // 返回逻辑视图名称之后,DispatcherServlet会将逻辑视图名称ViewName+Model,将其封装为ModelAndView对象
        mv=ha.handle(processedRequest,response,mappedHandler.getHandler());
        
        // 这行代码作用是处理视图
        processDispatchResult(processedRequest,response,mappedHandler,mv,dispatchException);
    }

    private void processDispatchResult(
        HttpServletRequest request,
        HttpServletResponse response,
        @Nullable HandlerExecutionChain mappedHandler,
        @Nullable ModelAndView mv,
        @Nullable Exception exception)throws Exception{
            // 渲染页面(将模板字符串转换成html代码响应到服务器)
            render(mv,request,response);
        }

    protected void render(ModelAndView mv,HttpServletRequest request, HttpServletResponse response) throws Exception{
        // 这个方法作用是将逻辑视图名称转换成物理视图名称,并且最终返回视图对象view
        View view = resolveViewName(viewName,mv.getModelInternal(),locale,request);

        // 真正的将模板字符串转换成HTML代码,并且将HTML代码响应给浏览器(真正渲染)
        view.render(mv.getModelInternal(),request,response);
    }

    protected View resolveViewName(
        String viewName,
        @Nullable Map<String, Object> model,
        Locale locale,
        HtpServletRequest request) throws Exception{
            // 上述render方法中真正调用执行的方法
            ViewResolver viewResolver;//底层会创建一个ThymeleafViewResolver
            // ,如果使用Thymeleaf,那么该接口实现类就为ThymeleafView对象
            View view = viewResolver.resolveViewName(viewName,locale);
            return view;
        }
}

ViewResolver接口

public interface ViewResolver{
    // 这里只是一个规范了行为的接口,具体的实现类要根据所选择的模板解析器来确定(列如,如果使用Thymeleaf,那么该接口实现类就为ThymeleafViewResolver)
    // 该方法是将逻辑视图名称转换成物理视图名称,并且最终返回视图对象View
    View resolveViewName(String viewName,Locale locale) throws Exception;
}

View接口

// 该接口负责将模板字符串转换成HTML代码,响应给浏览器
public interface View(){
    void render(
        @Nullable Map<String, ?> model, 
        HttpServletRequest request, 
        HttpServletResponse response) throws Exception;
}

代码流程描述

若在SpringMVC中使用了Thymeleaf作为视图

  1. 浏览器发送请求给web服务器
  2. Spring MVC中的DispatcherServlet接收到请求
  3. DispatcherServlet根据请求路径分发到对应的Controller
  4. DispatcherServlet调用Controller的方法
  5. Controller的方法处理业务并返回一个逻辑视图名给DispatcherServlet
  6. DispatcherServlet调用ThymeleafViewResolver的resolveViewName方法,将逻辑视图名转换为物理视图名,并创建ThymeleafView对象返回给DispatcherServlet
  7. DispatcherServlet再调用ThymeleafView的render方法,render方法将模板语言转换为HTML代码,响应给浏览器,完成最终渲染

若在SpringMVC中使用了JSP作为视图

  1. 浏览器发送请求给web服务器
  2. Spring MVC中的DispatcherServlet接收到请求
  3. DispatcherServlet根据请求路径分发到对应的Controller
  4. DispatcherServlet调用Controller的方法
  5. Controller的方法处理业务并返回一个逻辑视图名给DispatcherServlet
  6. DispatcherServlet调用InternalResourceViewResolver的resolveViewName方法,将逻辑视图名转换为物理视图名,并创建InternalResourceView对象返回给DispatcherServlet
  7. DispatcherServlet再调用InternalResourceView的render方法,render方法将模板语言转换为HTML代码,响应给浏览器,完成最终渲染。

转发与重定向

转发和重定向的区别

  • 转发是一次请求,因此浏览器地址栏上的地址不会发生变化。
  • 重定向是两次请求,因此浏览器地址栏上地址会发送变化
  • 转发的代码实现request.getRequestDispatcher("/index").forward(request,response)
  • 重定向的代码实现response.sendRedirect("/webapproot/index");
  • 转发是服务器内部资源跳转,由服务器来控制,不可实现跨域访问
  • 重定向可以完成内部资源的跳转也可以完成跨域跳转。
  • 转发的方式可以访问WEB-INF目录下受保护的资源
  • 重定向相当于浏览器重新发送了一次请求,再浏览器直接发送的请求是无法访问WEB-INF目录下受保护的资源
转发的原理
  1. 假设发送了/a请求,执行了AServlet
  2. 在Aservlet中通过request.getRequestDispatcher("/b").forward(request,response)转发到BServlet
  3. 从AServlet跳转到BServlet是服务器内部来控制的。对于浏览器而言,浏览器只发送了一个/a请求
重定向原理
  1. 假设发送了/a请求,执行了AServlet
  2. 在Aservlet中通过response.sendRedirect("/webapproot/b")重定向到BServlet
  3. 此时浏览器会将请求路径/webapproot/b响应给浏览器
  4. 浏览器会自发的再次发送/webapproot/b请求来访问BServlet
  5. 因此对于重定向来说,发送了两次请求,一次是/webapproot/a,另一次是/webapproot/b

SpringMVC实现转发和重定向

@RequestMapping("/a")
public String toA(){
    return "a"; //转发到a
    //return "forward:/b" //转发到b
    //return "redirect:/b" //重定向到b
}

@RequestMapping("/b")
public String toB(){
    return "b"
}

当return “a”;的时候,返回了一个逻辑视图名称,这种方式跳转到视图,默认采用的是forward方式跳转过去,只不过,底层创建的视图对象是ThymeleafView

当return “forward:/b”;转发到/b,这桑一次请求,底层创建的视图对象是InternalResourceView对象

当return “redirect:/b”;转发到/b这是两次请求,底层创建的视图对象是RedirectView对象

上述所提到的转发和重定向使用的return "forward:/b|redirect:/b"中的/b是请求资源的路径不是逻辑视图名称

若要使用重定向进行跨域,则必须在redirect后面写上全路径

访问静态资源

由于在web.xml文件中配置了springmvc的前端控制器映射,使得浏览器的所有请求都会走向springmvc的DispatcherServlet,而我们并没有配置关于静态资源的映射,因此不能直接访问静态资源

解决方法1

在Tomcat服务器中提供了一个默认的Servlet,叫做org.apache,catalina.servlets.DefaultServlet
在CATALINA_HOME/conf/web.xml文件中,有这个默认的Servlet的相关配置

要使用这个Servlet需要在springmvc.xml文件中配置<mvc:default-servlet-handler/> <mvc:annotation-driven>
当开启这个Servlet后默认会先走DispatcherServlet若发生404是会走DefaultServlet然后DefaultServlet会定位静态资源

解决方法2

在springmvc.xml中配置静态资源处理器

<mvc:resources mapping="/static/**" location="/static/" /> <mvc:annotation-driven/>

这里的配置是指当路径符合/static/**的时候会去/static/位置找资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值