三大框架之SpringMVC4框架 第二章

第二章 SpringMVC配置式开发

所谓配置式开发是指,“处理器类是程序员手工定义的、实现了特定接口的类,然后再在SpringMVC配置文件中对该类进行显式的、明确的注册”的开发方式。

2.1.1处理器映射器 HandlerMapping 通过注册

HandlerMapping 接口负责根据request 请求找到对应的Handler处理器及Interceptor拦截器,并将它们封装在HandlerExecutionChain对象中,返回给中央调度器。
其常用的实现类有两种:
BeanNameUrlHandlerMapping
SimpleUrlHandlerMapping
(1)BeanNameUrlHandlerMapping默认的
第一个程序里使用的就是这个。
BeanNameUrlHandlerMapping处理器映射器,会根据请求的url与spring容器中定义的处理器bean的name属性值进行匹配,从而在spring 容器中找到处理器bean实例。
其中
其中第一行代码可以省略不写。
打开类的源码,从处理器映射器的方法中可以看出,对于处理器的Bean的名称,必须以“/”开头,否则无法加入到urIs数组中。
(2)SimpleUrlHandlerMapping
/11-simpleUrlHandlerMapping
使用BeanNameUrlHandlerMapping映射器有两点明显不足:
1、处理器Bean的id为一个url请求路径,而不是Bean的名称,有些不伦不类。
2、处理器Bean的定义与请求url绑定在了一起。若出现多个url请求同一个处理器的情况,就需要在Spring容器中配置多该处理器类的。这将导致容器会创建多个该处理器类实例。

SimpleUrlHandlerMapping处理器映射器,不仅可以将url与处理器的定义分离,还可以对url 进行统一映射管理。
SimpleUrlHandlerMapping处理器映射器,会根据请求的url与Spring容器中定义的处理器映射器子标签的key属性进行匹配。匹配上后,再将该key的value值与处理器bean的id值进行匹配,从而在spring容器中找到处理器bean。
两种方法

<!-- 注册处理器映射器 -->
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<!-- 		
		<property name="mappings">
			<props>
				<prop key="/hello.do">myController</prop>
				<prop key="/world.do">myController</prop>
				<prop key="/my.do">myController</prop>
			</props>
		</property>
		-->
		<property name="urlMap">
			<map>
				<entry key="/hello.do" value="myController"></entry>
				<entry key="/world.do" value="myController"></entry>
				<entry key="/my.do" value="myController"></entry>
			</map>
		</property>
	</bean>
	<!-- 注册处理器对处理的请求做出限制,限制.do -->
	<bean id="myController" class="com.bjpowernode.handlers.MyController"/>

2.1.2 处理器适配器 HandlerAdapter 通过实现接口

适配器模式解决的间题是,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。所以处理器适配器所起的作用是,将多种处理器(实现了不同接口的处理器),通过处理器适配器的适配,使它们可以进行统一标准的工作,对请求进行统一方式的处理。

只所以要将Handler定义为Controller接口的实现类,就是因为这里使用的处理器适配器是SimpleControllerHandlerAdapter。打开其源码,可以看到将handler 强转为了Controller。

在定义Handler时,若不将其定义为Controller接口的实现类,这里的强转要出错的。
当然,中央调度器首先会调用该适配器的supports()方法,判断该Handler是否与Controller具有is-a关系。在具有is-a关系的前提下,才会强转。
(1)SimpleControllerHandlerAdapter
所有实现了Controller接口的处理器Bean,均是通过此适配器进行适配、执行的。Controller接口中有一个方法:就是我们在第一个程序中写过的
在这里插入图片描述
该方法用于处理用户提交的请求。通过调用Service层代码,实现对用户请求的计算响应,并最终将计算所得数据及要响应的页面,封装为一个对象ModelAndView,返回给中央调度器。
(2)HttpRequestHandlerAdapter
/12-httpRequestHandlerAdapter
所有实现了HttpRequestHandler接口的处理器Bean,均是通过此适配器进行适配、执行的。HttpRequestHandler接口中有一个方法:‘
在这里插入图片描述
该方法没有返回值,不能像ModelAndView一样,将数据及目标视图封装为一个对象。但可以将数据直接放入到request、session等域属性中,并由request或response完成到目标页面的跳转。

package com.bjpowernode.handlers;

public class MyController implements HttpRequestHandler {

	@Override
	public void handleRequest(HttpServletRequest request, 
			HttpServletResponse response)
			throws ServletException, IOException {
		request.setAttribute("message", "Hello SpringMVC World!");
		request.getRequestDispatcher("/WEB-INF/jsp/welcome.jsp").forward(request, response);
		
	}
}

当然,此时视图解析器也无需再配置前辍与后辍了。即在springmvc.xml中无需声明视图解析器的Bean了。即springmvc.xml文件中不用修改。

<!-- 注册处理器对处理的请求做出限制,限制.do -->
	<bean id="/my.do" class="com.bjpowernode.handlers.MyController"/>

2.1.3 处理器 通过继承

处理器除了实现Controller接口外,还可以继承自一些其它的类来完成些特殊的功能。

(1)继承自AbstractController类

/13-abstractController 项目位置
若处理器继承自AbstractController类,那么该控制器就具有了一些新的功能。因为AbstractController类还继承自一个父类WebContentGenerator

WebContentGenerator 类具有supportedMethods属性,可以设置支持的HTTP数据提交方式。默认支持GET、POST。

若处理器继承自AbstractController类,那么处理器就可以通过属性supportedMethods来限制HTTP请求提交方式了。例如,指定只支持POST的HTTP请求提交方式。

<!-- 注册处理器 -->
	<bean id="/my.do" class="com.bjpowernode.handlers.MyController">
		<proprty name="supportedMethods" value="POST"></proprty>
	</bean>

注意,这里的POST必须写为大写。
那就意味着该请求只能通过表单或AlAX请求方式进行提交,而不能通过地址栏、超链接、Html标签中的src方式进行提交。因为地址栏、超链接、Html标签中的src方式都是GET提交。否则,会给出请求方法不允许的405错误。
客户端访问浏览器常用的提交方式:
在这里插入图片描述
指定提交方法要么不写,则默认都可以;要么只写POST,支持一种。

(2)继承自MultiActionController类

/14-multiActionController 项目名称
MultiActionController 类继承自AbstractController,所以继承自MultiActionController类的子类也可以设置HTTP请求提交方式。
除此之外,继承自该类的处理器中可以定义多个处理方法。这些方法的签名为公共的方法,返回值为ModelAndView,包含参数HttpServletRequest 与HttpServletResponse,抛出Exception异常,方法名随意

1修改处理器类

要执行两个方法

public class MyController extends MultiActionController {

	public ModelAndView doFirst(HttpServletRequest request, 
			HttpServletResponse response) {
		 ModelAndView mv = new ModelAndView();
		 mv.addObject("message", "执行doFirst()方法");
		 mv.setViewName("/WEB-INF/jsp/welcome.jsp");
		return mv;
	}

	public ModelAndView doSecond(HttpServletRequest request, 
			HttpServletResponse response) {
		ModelAndView mv = new ModelAndView();
		mv.addObject("message", "执行doSecond()方法");
		mv.setViewName("/WEB-INF/jsp/welcome.jsp");
		return mv;
	}
}

修改springmvc.xml

汪意处埋器类的映格的与法:要求必须以/xxx/*的路径万式定又映剔路径。其中*为通配符,在访问时使用要访问的方法名代替。
因为有多个方法,所以采用SimpleUrlHandlerMapping处理器映射器

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="urlMap">
			<map>
				<entry key="/my/*.do" value-ref="myController"/>
				
			</map>
		</property>
	</bean>
	
<!-- 注册处理器对处理的请求做出限制,限制.do -->
	<bean id="myController" class="com.bjpowernode.handlers.MyController"/>

3访问

对doFirst()方法的访问请求是:
在这里插入图片描述
对doSecond()方法的访问请求是:
在这里插入图片描述
只所以通过在请求URI中写上方法名就可以访问到指定方法,是因为在MultiActionController 类中有一个专门处理方法名称的解析器MethodNameResolver。该解析器作为一个属性出现,具有get与set方法。MethodNameResolver是一个接口,不同的解析器实现类,其对方法名在URI中的写法要求也是不同的。

A、InternalPathMethodNameResolver 方法名解析器(默认)

该方法名解析器要求方法名以URI中资源名称的身份出现,即方法作为一种可以被请求的资源出现。也就是前面的写法:/xxx/方法名。

B、PropertiesMethodNameResolver 方法名解析器

该方法名解析器中的方法名是作为URI资源名称中的一部分出现的,即方法名并非单独作为一种资源名称出现。例如请求时可以写为/xxx_doFirst,则会访问xxx所映射的处理器的doFirst()方法。
/15-multiActionController-2
其他不变,只修改springmvc.xml
1、处理器映射器的请求格式发生了改变。
2、另外,还需要配置一个PropertiesMethodNameResolver 方法名解析器,并指定请求与要执行的方法名之间的映射关系。注意,这里的指定的请求,必须要加上.do,否则,无法完成匹配,将报404错误。
3、最后,将配置好的方法名解析器,注入给处理器。
其实完成的就是更多修饰访问名称限制的操作

	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="urlMap">
			<map>
				<entry key="/my_*.do" value-ref="myController"/>
				
			</map>
		</property>
	</bean>
	
<!-- 注册方法名称解析器 -->
	<bean id="propertiesMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
		<property name="mappings">
			<props>
				<prop key="/my_first.do">doFirst</prop>
				<prop key="/my_second.do">doSecond</prop>
			</props>
		</property>
	</bean>
<!-- 注册处理器 -->
	<bean id="myController" class="com.bjpowernode.handlers.MyController">
		<property name="methodNameResolver" ref="propertiesMethodNameResolver"/>
	</bean>

对doFirst()方法的请求是:

http://localhost:8080/15-multiActionController-2/my_first.do

C、ParameterMethodNameResolver 方法名解析器

该方法名解析器中的方法名作为请求参数的值出现。例如请求时可以写为/xxx?ooo=doFirst,则会访问xxx所映射的处理器的doFirst()方法。其中ooo为该请求所携带的参数名,而doFirst则作为其参数值出现。
/16-multiActionController-3
直接修改springmvc.xml文件即可

	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="urlMap">
			<map>
				<entry key="/my.do" value-ref="myController"/>
				
			</map>
		</property>
	</bean>
	
<!-- 注册方法名称解析器 -->
	<bean id="parameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
		<property name="paramName" value="xxx"/>
	</bean>
<!-- 注册处理器 -->
	<bean id="myController" class="com.bjpowernode.handlers.MyController">
		<property name="methodNameResolver" ref="parameterMethodNameResolver"/>
	</bean>

对doFirst()方法的访问请求是:
http://localhost:8080/16-multiActionController-3/my.do?xxx=doSecond
不过,打开ParameterMethodNameResolver源码,发现该类中有一个默认的参数action。即若不指定参数名称,则可以使用action作为参数。

2.1.4 视图解析器ViewResolver

springmvc.xml
注册XmlViewResolver视图解析器顺序1和ResourceBundleViewResolver视图解析器顺序3与优先级

	<!-- ResourceBundle注册视图解析器1 -->
	<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
		<property name="basename" value="myViews"/>
		<property name="order" value="3"/>
	</bean>
	
	<!-- xml注册视图解析器2 -->
	<bean class="org.springframework.web.servlet.view.XmlViewResolver">
		<property name="location" value="classpath:myViews.xml"/>
		<property name="order" value="1"/>
	</bean>
	
	<!-- 默认的视图解析器优先级最低 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
		
<!-- 注册处理器对处理的请求做出限制,限制.do -->
	<bean id="/my.do" class="com.bjpowernode.handlers.MyController"/>

myViews.xml
定义XmlViewResolver视图解析器

    <!-- 定义外部资源视图 -->
	<bean id="ecommerce" class="org.springframework.web.servlet.view.RedirectView">
		<property name="url" value="http://www.taobao.com"/>
	</bean>

myViews.properties
定义ResourceBundleViewResolver视图解析器

ecommerce.(class)=org.springframework.web.servlet.view.RedirectView
ecommerce.url=http://www.jd.com

接口

public class MyController implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request, 
			HttpServletResponse response) throws Exception {
	
		return new ModelAndView("ecommerce");
	}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值