【Spring MVC】笔记

1.Web、MVC、WebMVC概述
1)完成一次web请求的过程
Web浏览器发起请求
Web服务器接收请求并处理请求,最后产生响应(一般为html)。
web服务器处理完成后,返回内容给web客户端,客户端对接收的内容进行处理并显示出来。

	从这里可以看出,在web中,都是web客户端发起请求,web服务器接收处理请求并产生响应。
	一般Web服务器是不能主动通知Web客户端更新内容。虽然有些技术可以帮我们实现这样的效果,如服务器推技术(Comet)、还有HTML5中的websocket等。

2)MVC模型(Model-View-Controller)
	是一种架构型的模式,本身不引入新功能,只是帮助我们将开发的代码结构,组织的更加合理。

	Model(模型)
		数据模型,提供要展示的数据,因此包含数据和行为,行为是用来处理这些数据的。不过现在一般都分离开来:Value Object(数据) 和 服务层(行为)。也就是数据由实体类或者javabean来提供,行为由service层来提供.
	
	View(视图)
		负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。

	Controller(控制器)
		接收用户请求,委托给模型进行处理,处理完毕后把返回的模型数据交给给视图。也就是说控制器在中间起到一个调度的作用。


	在标准的MVC中,模型能主动推数据给视图进行更新(可以采用观察者设计模式实现,在模型上注册视图,当模型更新时自动更新视图),但在Web开发中模型是无法主动推给视图,即无法主动更新用户界面,因为在Web的访问是请求-响应的模式。必须由客户端主动发出请求后,服务器才能把数据返回。



3)WebMVC
	Web中MVC里面的模型-视图-控制器的概念和标准MVC概念一样,但是在Web MVC模式下,模型无法【主动】推数据给视图,如果用户想要视图更新,需要再发送一次请求(即请求-响应模型)。

	在我们之前的学习中,其实就是把Servlet作为Controller(控制器),把jsp作为View(视图),把javabean作为Model(模型)中的数据,service层作为Model(模型)中的行为.

	注意:MVC和三层架构的区别

2.SpringWebMVC概述(SpringMVC)
1)SpringWebMVC简称SpringMVC
SpringMVC就是Spring框架提供的一个模块,通过实现MVC模式来很好地将数据、业务与展现进行分离,SpringMVC框架的目的是要简化我们日常的Web开发。

	SpringMVC框架跟其他的WebMVC框架一样,都是请求驱动,并且设计围绕一个能够分发请求到控制器以及提供其他加快web应用开发功能的核心Servlet(叫做DispatcherServlet,即前端控制器)。Spring的DispatcherServlet实现比其他框架中还要多的功能。它和spring的ioc容器完全整合,并且允许使用spring中其他的所有功能。

	SpringMVC框架设计的一个核心的原则就是"开闭原则",对扩展开放,对修改关闭.所以SpringMVC框架中很多方法都是final的,不允许用户随意覆盖,但是却提供给用户很多可扩展的机制。SpringMVC目前已经成为非常流行的web应用的框架。

	
2)SpringMVC框架的获取
	由于SpringMVC是Spring框架中的一个模块,所以我们下载Spring框架即可,因为里面包含了Spring框架的各个模块的相关东西,当然也包含了SpringMVC的(jar包、API文档、源代码)
	
	
3)SpringMVC框架的核心组件
	1.DispatcherServlet: 前端控制器,用来过滤客户端发送过来,想要进行逻辑处理的请求。

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

	3.HandlerMapping: 处理器映射器。DispatcherServlet接收到客户端请求的URL之后,根据一定的匹配规则,再把请求转发给对应的Handler,这个匹配规则由HandlerMapping决定。
	
	4.HandlerAdaptor:处理器适配器。处理器适配器用来适配每一个要执行的Handler对象。通过HandlerAdapter可以支持任意的类作为处理器
	
	5.ViewResolver:视图解析器。Handler返回的是逻辑视图名,需要有一个解析器能够将逻辑视图名转换成实际的物理视图。而且Spring的可扩展性决定了视图可以由很多种,所以需要不同的视图解析器,解析不同的视图。但是一般由jsp充当视图的情况居多


	SpringMVC框架提供一个核心的Servlet对象(DispatcherServlet,前端控制器)来对服务器接收到的请求进行解析,当这个请求被DispatcherServlet获取到之后,DispatherServlet需要根据HandlerMapping对象的映射关系,将这个请求转交给真正能够处理客户端请求的Controller控制器(我们要写的就是这个东西,相当于之前的servlet)来处理。Controller处理完成后返回ModelAndView对象,也就是模型和视图的结合体。ViewResolver视图解析器根据ModelAndView中的逻辑视图名找到真正的物理视图,同时使用ModelAndView中模型里面的数据对视图进行渲染。最后把准备好的视图展现给用户

3.SpringMVC框架在项目中的搭建
第一步:构建Web项目
第二步:导入所需jar包
第三步:配置前端控制器DispatcherServlet
第四步:编写Controller控制器(也称为Handler处理器)
第五步:配置处理器映射器(可省去,有默认配置)
第六步:配置处理器适配器(可省去,有默认配置)
第七步:配置视图解析器(可省去,有默认配置,但是前缀和后缀都为"")
第八步:配置处理器

1)构建Web项目
	在自己Eclipse中创建一个动态web项目(DynamicWebProject),注意JDK版本和项目版本的选择


2)导入所需的jar包
	在lib目录下放入如下jar包,这是初始jar包,根据后续需求会陆续加入jar包

	commons-logging-1.2.jar
	spring-beans-4.3.7.RELEASE.jar
	spring-context-4.3.7.RELEASE.jar
	spring-core-4.3.7.RELEASE.jar
	spring-expression-4.3.7.RELEASE.jar
	spring-web-4.3.7.RELEASE.jar
	spring-webmvc-4.3.7.RELEASE.jar


3)配置前端控制器DispatcherServlet

	SpringMVC的核心控制器就是一个Servlet对象,继承自HttpServlet,所以需要在web.xml文件中配置。

	SpringMVC是Spring提供的一个模块,Spring所有的模块都是基于Spring IOC功能的。所以SpringMVC的DispatcherServlet对象在初始化之前也会去实例化Spring的容器对象(ApplicationContext),那么就需要读取Spring的配置文件。默认SpringMVC会在你web应用的WEB-INF目录下查找一个名字为[servlet-name]-servlet.xml文件(servlet-name指的是配置前端控制器的名字),并且创建在这个文件中定义的bean对象。如果你提供的spring配置文件的名字或者位置和默认的不同,那么需要在配置servlet时同时指定配置文件的位置。

	例如:
	  <servlet>
		<servlet-name>SpringMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	  </servlet>
	  <servlet-mapping>
		<servlet-name>SpringMVC</servlet-name>
		<url-pattern>/</url-pattern>
	  </servlet-mapping>

	如上配置,框架会自动去当前应用的WEB-INF目录下查找名字为SpringMVC-servlet.xml文件(默认前缀和<servlet-name>标签中的值一致)。
	也可以自己指定配置文件的名字和位置:
		
	<servlet>
		<servlet-name>SpringMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-web-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>SpringMVC</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	
	注意:
		配置文件在WEB-INF下:
		<param-value>/WEB-INF/spring-web-mvc.xml</param-value>
		配置文件在classpath下:
		<param-value>classpath:spring-web-mvc.xml</param-value>

	注意:
		<url-pattern>/</url-pattern>
		注意这里是 / 不是 /*

		后期可以测试了解配置成/*的后果:
			如果把前端控制器的url-pattern配置为<url-pattern>/*</url-pattern>那么就会发生404错误,为什么呢??当我们发送请求到Tomcat服务器的时候,/*匹配时,虽然Tomcat会把我们的请求正确交给我们的Servlet执行,但是当SprinMVC的视图解析器转发jsp视图的时候(看源码知道的),因为url-pattern是/*,所以Tomcat又会拦截我们的请求,把该请求发送给我们配置好的Servlet,导致我们SpringMVC的处理器映射器找不到Handler,最终发生404错误。

4)编写Controller控制器(handler)
	Controller控制器,是MVC中的部分C,因为此处的 控制器主要负责功能处理部分:
	1、收集、验证请求参数并封装到对象上;
	2、将对象交给业务层,由业务对象处理并返回模型数据;
	3、返回ModelAndView(Model部分是业务层返回的模型数据,视图部分为逻辑视图名)。
	 
	前端控制器(DispatcherServlet)主要负责整体的控制流程的调度部分:
	1、负责将请求委托给控制器进行处理;
	2、根据控制器返回的逻辑视图名选择具体的视图进行渲染(并把模型数据传入)。
	因此MVC中完整的C(包含控制逻辑+功能处理)由(DispatcherServlet + Controller)组成。
	
	Controller接口中只有一个需要实现的方法就是handleRequest方法,方法中接收两个参数,分别对应Servlet对象中的request,response对象。可以从request中获取客户端提交过来的请求参数。
	返回值ModelAndView,既包含要返回给客户端浏览器的逻辑视图又包含要对视图进行渲染的数据模型。

	例如:
	public class HelloWorldController implements Controller{
		@Override
		public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
			String name = request.getParameter("name");
			//ModelAndView对象中包括了要返回的逻辑视图,以及数据模型
			ModelAndView mv = new ModelAndView();
			//设置逻辑视图名称
			mv.setViewName("hello");
			//设置数据模型
			mv.addObject("name", name);

			return mv;
		}
	}

5)配置映射器(可省去,有默认配置)
	注意:如果xml文件不能自动提示,那么可以在Eclipse中把schame配置过来即可,schame文件也在下载的spring的压缩包中
	Spring容器需要根据映射器来将用户提交的请求url和后台Controller/Handler进行绑定,所以需要配置映射器。
	例如:
	<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

	BeanNameUrlHandlerMapping:表示将请求的URL和Bean名字映射,如URL为 "/hello",则Spring配置文件必须有一个名字为"/hello"的Bean.
	注意:这里/代表的含义是url中项目名后面的/


6)配置适配器(可省去,有默认配置)
	想要正确运行自定义处理器,需要配置处理器适配器,在spring的配置文件中(就是本例中的SpringMVC-servlet.xml),进行如下配置:
	
	<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

	SimpleControllerHandlerAdapter:表示所有实现了org.springframework.web.servlet.mvc.Controller接口的Bean可以作为SpringMVC中的处理器。如果需要其他类型的处理器可以通过实现HadlerAdapter来解决。


7)配置视图解析器(可省去,有默认配置,但是前缀和后缀都为"")
	当处理器执行完成后,返回给spring容器一个ModelAndView对象,这个对象需要能够被解析成与之相对应的视图,并且使用返回的Model数据对视图进行渲染。
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
		<property name="prefix" value="/WEB-INF/jsp/"/>  
		<property name="suffix" value=".jsp"/>  
	</bean>  

	如果配置设置为如上操作,那么在自定义的Handler中返回的视图的名字不能有后缀.jsp,并且页面一定放在/WEB-INF目录下。
	
	InternalResourceViewResolver:用于支持Servlet、JSP视图解析;
	viewClass:JstlView表示JSP模板页面需要使用JSTL标签库,classpath中必须包含jstl的相关jar包;
	prefix和suffix:视图页面的前缀和后缀(前缀+逻辑视图名+后缀),比如传进来的逻辑视图名为hello,则该该jsp视图页面应该存放在"WEB-INF/jsp/hello.jsp"
	
	注意:放在WEB-INF下的页面,只能通过内部跳转的方式访问到,因为客户端访问不到WEB-INF目录,而服务器端可以访问到WEB-INF目录
	注意:需要引入jstl相关jar包
	注意:页面中的路径问题
		 <%
			String path = request.getContextPath();
			String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
		 %>

		 <base href="<%=basePath%>" />

8)配置处理器
	把编写好的handler/controller在spring中进配置,让其接受Spring IoC容器管理
	<bean name="/hello" class="com.briup.web.controller.HelloWorldController"/>  



注意: 对于Spring配置文件中的处理器适配器,处理器映射器,都可以省去不写,springMVC框架中会有默认配置的,视图解析器也可以不配置,因为在org.springframework.web.servlet.DispatcherServlet这个类的同包下,有一个DispatcherServlet.properties文件,里面就是SpringMVC默认的配置,是当用户的Spring配置文件中没有指定配置时使用的默认策略(你不配置那么用默认的,你配置了,那么就使用你的配置)

从默认的配置中可以看出DispatcherServlet在启动时会自动注册这些特殊的Bean,无需我们注册,如果我们注册了,默认的将不会注册。

因此之前的BeanNameUrlHandlerMapping、SimpleControllerHandlerAdapter是不需要注册的,DispatcherServlet默认会注册这两个Bean。


整个访问的流程:
1、  首先用户发送请求,前端控制器DispatcherServlet收到请求后自己不进行处理,而是委托给其他的解析器进行处理,前端控制器作为统一访问点,进行全局的流程控制;
2、  DispatcherServlet把请求转交给HandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)对象.(后面会学习到拦截器)
3、  DispatcherServlet再把请求转交给HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器(适配器模式).简单点说就是让我们知道接下来应该调用Handler处理器里面的什么方法
4、  HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
5、  ModelAndView的逻辑视图名交给ViewResolver视图解析器, ViewResolver视图解析器把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、  View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、最后返回到DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。

4.DispatcherServlet中的映射路径

<servlet>
	<servlet-name>SpringMVC</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>SpringMVC</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

1)拦截所有请求
	此处需要特别强调的是 <url-pattern>/</url-pattern>使用的是/,而不是/*,如果使用/*,那么请求时可以通过DispatcherServlet转发到相应的Controller中,但是Controller返回的时候,如返回的jsp还会再次被拦截, ,即访问不到jsp。

2)自定义拦截请求的后缀名
	拦截*.do、*.html、*.action, 例如/user/add.do
	这是最传统的方式,最简单也最实用。不会导致静态文件(jpg,js,css)被拦截。

	拦截/,例如:/user/add
	可以实现REST风格的访问
	弊端:会导致静态文件(jpg,js,css)被拦截后不能正常显示。

	拦截/*,这是一个错误的方式,请求可以走到Controller中,但跳转到jsp时再次被拦截,不能访问到jsp。


3)静态资源的访问,如jpg,js,css
	如果DispatcherServlet拦截"*.do"这样的有后缀的URL,就不存在访问不到静态资源的问题。
  如果DispatcherServlet拦截"/",为了实现REST风格,拦截了所有的请求,那么同时对*.js,*.jpg等静态文件的访问也就被拦截了。
	例如:
	<link href="css/first.css" rel="stylesheet" type="text/css"/>
	

	解决方式一:利用Tomcat的defaultServlet来处理静态文件
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.jpg</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.js</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.css</url-pattern>
	</servlet-mapping>

	特点:1.要配置多个,每种文件配置一个。
	    2.要写在DispatcherServlet的前面(和tomcat版本有关),让defaultServlet先拦截请求,	这样请求就不会进入Spring了
	    3. 高性能。

	
	解决方式二: 使用<mvc:resources>标签,例如:
	<mvc:resources mapping="/images/**" location="/images/"/>  
	<mvc:resources mapping="/js/**" location="/js/"/>  
	<mvc:resources mapping="/css/**" location="/css/"/> 
	
	mapping: 映射
	两个*,表示映射指定路径下所有的URL,包括子路径
	location:本地资源路径

	这样如果有访问/images或者/js或者/css路径下面的资源的时候,spring就不会拦截了


	解决方式三: 使用<mvc:default-servlet-handler/>标签
	在spring配置文件中加入此标签配置即可

5.spring提供的编码过滤器
查看这个过滤器类源码便可知这里所传的俩个参数的作用

<filter>
	<filter-name>CharacterEncodingFilter</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
	<init-param>
		<param-name>forceEncoding</param-name>
		<param-value>true</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>CharacterEncodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值