SpringMVC-day2-基于注解实现与MVC各组件交互流程

SpringMVC

1. 核心组件

SpringMVC框架中提供给用户如下几个概念:

  • DispatcherServlet:(又称前端控制器)

    核心控制器,用来过滤客户端发送过来,想要进行逻辑处理的请求

  • Handler(Controller):

    处理器。开发人员自定义,用来处理用户请求的,并且处理完成之后返回给用户指定视图的对象。

  • HandlerMapping:

    处理器映射器。DispatcherServlet在根据URL转发请求给Handler时得有一个匹配规则,这个匹配规则由HandlerMapping决定。

  • HandlerAdaptor

    处理器适配器。处理器适配器用来适配每一个要执行的Handler对象。

  • ViewResolver

    视图解析器,Handler返回的是逻辑视图名,需要有一个解析器能够将逻辑视图名转换成实际的物理视图

    Spring的可扩展性决定了视图可以由很多种,所以需要不同的视图解析器,解析不同的视图。

    配置如下:

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        
        <property name="viewClass" 
                  value="org.springframework.web.servlet.view.JstlView">
        property>
        
        <property name="prefix" value="/WEB-INF/">property> 
        
         <property name="suffix" value=".jsp">property>
    bean>
    

注意:

处理器适配器,处理器映射器,视图解析器等都的配置都可以省略,

在spring的jar中都拥有默认的配置的。

2.组件交互

流程图:

SpringMVC-day2-基于注解实现与MVC各组件交互流程_第1张图片

流程介绍:
首先 用户在浏览器 发送一个请求,然后前端控制器收到请求后,将具体访问路径传给 处理映射器,处理映射器 根据 url 找到响应的Controller。然后返回一个对象,包含了 请求路径对应的处理对象和多个拦截器。前端控制器将收到的处理对象交给适配器,然后适配器根据 处理对象 的类型,(可能是实现接口,也可能是继承抽象类,也可能是注解)去适配处理器,然后处理器调用指定方法,返回数据和视图(逻辑视图,只有视图的名字),适配器将获得到的modelAndView 再交给 前端控制器,前端控制器再传给 视图解析器,视图解析器通过逻辑视图,找到真正的物理视图传送给前端控制器,再把物理视图交给jsp引擎去视图渲染,渲染完成后,通过前端控制器返回给用户,用户就看到了具有图形界面的视图

3.基于注解实现:

Spring MVC 是表现层框架 所以在动态web项目中配置。
而一个常规配置的web项目 拥有javaResources,build,WebConten。三类文件夹。
在WebConten/WEB-INF 中 先对lib 放入我们需要的jar包,然后在web.xml中配置前端控制器(也就是核心控制器)和加载SpringMVC的配置文件,以及启动时创建servlet 对象,最后需要配置拦截,默认将所有的访问都经过springMVC。

需要的包:
SpringMVC-day2-基于注解实现与MVC各组件交互流程_第2张图片
lo4j 与lombook 只是辅助,不是必须的。commons 是被log4j所依赖。
其他spring开头的 都是我们SpringMVC需要的jar包。

Web.xml 配置:


<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>你的项目名~display-name>


<servlet>
    <servlet-name>SpringMVCDispatcherServletservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    
    <init-param>
        <param-name>contextConfigLocationparam-name>
        <param-value>classpath:SpringMVC.xmlparam-value>
    init-param>
    
    <load-on-startup>1load-on-startup>
servlet>

<servlet-mapping>
    <servlet-name>SpringMVCDispatcherServletservlet-name>
    <url-pattern>/url-pattern>
servlet-mapping>

web-app>

而SpringMVC 需要配置在src包底下。


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        ">


	
	<mvc:annotation-driven/>
	
	<context:component-scan base-package="com.mvc">context:component-scan>
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/">property> 
     <property name="suffix" value=".jsp">property>
	bean> 
beans>

控制类:

package com.mvc;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
//与spring 中的 Component 一样 有了这个才能被扫描 才能够使用注解的形式实现应用
@Controller
public class HelloController {
	//这是在没有配置视图解析的情况下
	//RequestMapping 代表  当前控制器里面的控制器方法对外提供的访问路径
	// 相当于将一个请求路径与方法进行绑定
	//可以有多个地址
	@RequestMapping(value = {"/hello","say"})
	public ModelAndView hello() {
		ModelAndView mv = new ModelAndView();
		mv.addObject("rs","wuwuwuwuwuwu");
		mv.setViewName("index.jsp");
		// 直接 返回  ModelAndView 对象
		return mv;
	}
	
	//这是在没有配置视图解析的情况下
	//返回类型为String类型  返回的就是逻辑视图名  模型里面就没有数据了
	@RequestMapping("/hello2")
	public String hello2() {
		return "index.jsp";
	}
	// 一下俩种就是配了视图解析器,在视图解析的作用下,默认的为视图的名称加上了前缀和后缀,所以这里只需要 返回  index   在视图解析器查找物理视图的时候,它事件上查找的是 /WEB-INF/index.jsp
	@RequestMapping("/hello3")
	public String hello3() {
		return "index";
	}
	/* 这里的二级标题 意思是  可以随便传参数。都会被获取到这个方法中来,比如说
	* /p/dasdasdasdsadsa   此时的param 就是dasdasdasdsadsa   
	*/
	@RequestMapping("/p/{param}")
	public String p() {
		return "index";
	}
	/* 可以通过@PathVariable 获取param 的值。这个可以用在未来 匹配数据库时的
	数据依据 
	*/
	@RequestMapping("/p/{param}")
	public String ptwo(@PathVariable String param) {
		System.out.println(param);
		return "index";
	}
	//上面那种是形参名字相同,所以可以直接匹配,如果形参名字不同,则不能匹配,而在
	//注解的后面加上与网页形参相同的标识,则可以匹配。这里我说的是大概这个意思。
	// 看不懂可以看代码 就能理解
	@RequestMapping("/p/{param}")
	public String ptwo(@PathVariable("param") String param1) {
		System.out.println(param1);
		return "index";
	}
}

4.一些小细节

在web.xml 配置文件中,我们拦截了所有的请求,但是如果我们想要访问静态资源,能否正常访问到呢? 在当前情况下,我们所有的访问都会被拦截到springmvc中去,而springmvc 根据视图名称去查找是否有对应的控制器,如果没有 则没有响应。在我们想要访问静态资源时,springmvc将静态资源名当作视图名称去查找控制器,是查找不到我们想要的静态资源的。所以在这个时候,我们可以使用一些配置,在我们访问静态资源时,能够访问到我们想要的静态资源。
方法一:tomcat自带的defaultServlet
缺点:每种类型的静态资源需要分别配置一个servlet-mapping


<servlet-mapping>  
  <servlet-name>defaultservlet-name>  
  <url-pattern>/css/*url-pattern>  
servlet-mapping>  
<servlet-mapping>  
  <servlet-name>defaultservlet-name>  
  <url-pattern>*.jsurl-pattern>  
servlet-mapping>  
<servlet-mapping>  
  <servlet-name>defaultservlet-name>  
  <url-pattern>/image/*url-pattern>  
servlet-mapping>  

方法二:在spring的配置文件中启用mvc 这个schema


<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>

方法三:使用

<mvc:default-servlet-handler /> 

SpringMVC-day2-基于注解实现与MVC各组件交互流程_第3张图片
性能最好的应该是直接利用的Default Servlet,让它最先拦截静态资源请求,这样就避免了后续的转发等操作,提高了性能,但是无法访问classpath下的资源文件。

而通过mvc:resources标签可以简单配置匹配规则和资源文件路径,应该说是最简单快捷的一种方式,当然这大概也是mvc命名空间设计的初衷

今天就先这样。比心。

你可能感兴趣的:(spring,springmvc)