“SpringMVC:开发基础”的版本间差异
(→非注解) |
|||
第275行: | 第275行: | ||
所有的映射器都实现'''<code>HandlerMapping</code>'''接口: | 所有的映射器都实现'''<code>HandlerMapping</code>'''接口: | ||
==== 非注解 ==== | ==== 非注解 ==== | ||
===== BeanNameUrlHandlerMapping ===== | |||
根据请求的url与spring容器中定义的bean的name进行匹配,从而从spring容器中找到bean实例。 | |||
<syntaxhighlight lang="xml"> | <syntaxhighlight lang="xml"> | ||
<!-- 处理器映射器 将bean的name作为url进行查找 ,需要在配置Handler时指定beanname(就是url) | <!-- 处理器映射器 将bean的name作为url进行查找 ,需要在配置Handler时指定beanname(就是url) | ||
第283行: | 第284行: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
===== 简单url映射 ===== | |||
BeanNameUrlHandlerMapping的增强版本,它可以将url和处理器bean的id进行统一映射配置。 | |||
<syntaxhighlight lang="xml"> | <syntaxhighlight lang="xml"> | ||
<!--简单url映射 --> | <!--简单url映射 --> |
2020年9月25日 (五) 11:11的版本
基础
SpringMVC框架是一个开源的Java平台,属于Spring框架 Spring的一部分,是一个轻量级的web框架。
(Spring框架最初由Rod Johnson撰写,并于2003年6月根据Apache 2.0许可证首次发布。)
SpringMVC在三层架构(表示层UI、业务逻辑层BLL、持久层DAL)中处于表示层。
MVC
MVC框架用于开发灵活和松散耦合的Web应用程序的组件:
- 模型(Model):封装了应用程序数据,通常它们将由POJO(
Plain Ordinary Java Object
简单Java对象,即区别于EJB的普通JavaBean)类组成。pojo
、action
、service
、dao
- 视图(View):负责渲染模型数据,一般来说它生成客户端浏览器可以解释HTML输出。
jsp
、pdf
、excel
、framework
- 控制器(Controller):负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。
- struts2中的
filter
- struts2中的
架构
|
依赖包
springMVC属于spring的一个部分,所以需要spring包的支持:
组件
DispatcherServlet
(前端控制器):作用接收请求,响应结果,相当于转发器、中央处理器,减少其它组件之间的耦合度;HandlerMapping
(处理器映射器):根据请求的url查找Handler;HandlerAdapter
(处理器适配器):按照特定规则(HandlerAdapter
要求的规则)去执行Handler
;Handler
(Controller:处理器):编写Handler
时按照HandlerAdapter
的要求去做,这样适配器才可以去正确执行Handler
;ViewReslover
(视图解析器):进行视图解析,根据逻辑视图名解析成真正的视图(view
);View
(视图):View
是一个接口,实现类支持不同的视图类型(jsp
、pdf
、excel
、framework
);
配置文件
web.xml示例
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- Web应用名称 -->
<display-name>springmvcfirst1208</display-name>
<!-- springmvc前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation配置springmvc加载的配置文件(配置处理器映射器、适配器等等)
如果不配置contextConfigLocation,默认加载的是/WEB-INF/servlet名称-serlvet.xml(springmvc-servlet.xml)
-->
<init-param>
<!-- 指定加载的配置文件 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
第一种:*.action,访问以.action结尾 由DispatcherServlet进行解析
第二种:/,除jsp之外的全拦截。所有访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析
使用此种方式可以实现 RESTful风格的url
第三种:/*,真的全拦截。这样配置不对,使用这种配置,最终要转发到一个jsp页面时,
仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到handler,会报错。
-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- post乱码过虑器 -->
<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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
springmvc.xml示例
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- 可以扫描controller、service、... 这里让扫描controller,指定controller的包 -->
<context:component-scan
base-package="cn.itcast.ssm.controller"></context:component-scan>
<!--注解映射器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> -->
<!--注解适配器 -->
<!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> -->
<!-- 使用 mvc:annotation-driven代替上边注解映射器和注解适配器配置 mvc:annotation-driven默认加载很多的参数绑定方法,
比如json转换解析器就默认加载了,如果使用mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
实际开发时使用mvc:annotation-driven -->
<mvc:annotation-driven
conversion-service="conversionService"></mvc:annotation-driven>
<!-- 视图解析器 解析jsp解析,默认使用jstl标签,classpath下的得有jstl的包 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置jsp路径的前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 配置jsp路径的后缀 -->
<property name="suffix" value=".jsp" />
</bean>
<!-- 自定义参数绑定 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!-- 转换器 -->
<property name="converters">
<list>
<!-- 日期类型转换 -->
<bean
class="cn.itcast.ssm.controller.converter.CustomDateConverter" />
</list>
</property>
</bean>
</beans>
开发基础
建立项目
Eclipse:Dynamic Web Project
导入依赖包
springmvc独立运行需要的jar:
commons-logging-1.1.1.jar
jstl-1.2.jar
spring-aop-3.2.0.RELEASE.jar
spring-aspects-3.2.0.RELEASE.jar
spring-beans-3.2.0.RELEASE.jar
spring-context-3.2.0.RELEASE.jar
spring-context-support-3.2.0.RELEASE.jar
spring-core-3.2.0.RELEASE.jar
spring-expression-3.2.0.RELEASE.jar
spring-jdbc-3.2.0.RELEASE.jar
spring-orm-3.2.0.RELEASE.jar
spring-test-3.2.0.RELEASE.jar
spring-tx-3.2.0.RELEASE.jar
spring-web-3.2.0.RELEASE.jar
spring-webmvc-3.2.0.RELEASE.jar
配置DispatcherServlet
(关于servlet)
在web.xml
中配置前端控制器:
<!-- springmvc前端控制器 -->
<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:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
其中:
contextConfigLocation
:配置springmvc
加载的配置文件(配置处理器映射器、适配器等等);- 如果不配置
contextConfigLocation
,默认加载的是/WEB-INF/servlet名称-serlvet.xml(springmvc-servlet.xml)
;
- 如果不配置
load-on-startup
:表示容器启动优先级:- 当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;
- 非负数时,值越小优先级越高;
- 负数时或未指定时,则指示容器在该servlet被选择时才加载;
DispathcerServlet
作为springmvc
的中央调度器存在,DispatcherServlet
创建时会默认从DispatcherServlet.properties
(“Dspring-webmvc-3.2.0.RELEASE.jar”>>“org.springframework.web.servlet”>>“DispatcherServlet.properties”)文件加载springmvc
所用的各各组件,如果在springmvc.xml
中配置了组件则以springmvc.xml
中配置的为准,DispatcherServlet
的存在降低了springmvc
各各组件之间的耦合度。
DispatcherServlet.properties:
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
Servlet拦截方式
*.action
:拦截固定后缀的url
(如*.do
、*.action
),由DispatcherServlet进行解析;- 例如:
/user/add.action
,此方法最简单,不会导致静态资源(jpg
、js
、css
)被拦截。
- 例如:
/
:除jsp之外的全拦截。所有访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析;- (此方法可以实现
REST
风格的url
) - 例如:
/user/add
、/user/add.action
,但是会导致静态文件(jpg
、js
、css
)被拦截后不能正常显示,需要特殊处理。
- (此方法可以实现
/*
:全拦截;- 使用这种配置,最终要转发到一个
jsp
页面时,仍然会由DispatcherServlet
解析jsp
地址,不能根据jsp
页面找到handler
,会报错;
- 使用这种配置,最终要转发到一个
配置 HandlerMapping
HandlerMapping
负责根据request
请求找到对应的Handler
处理器及Interceptor
拦截器,将它们封装在HandlerExecutionChain
对象中给前端控制器(DispatcherServlet)返回。
所有的映射器都实现HandlerMapping
接口:
非注解
BeanNameUrlHandlerMapping
根据请求的url与spring容器中定义的bean的name进行匹配,从而从spring容器中找到bean实例。
<!-- 处理器映射器 将bean的name作为url进行查找 ,需要在配置Handler时指定beanname(就是url)
所有的映射器都实现 HandlerMapping接口。
-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
简单url映射
BeanNameUrlHandlerMapping的增强版本,它可以将url和处理器bean的id进行统一映射配置。
<!--简单url映射 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- 对itemsController1进行url映射,url是/queryItems1.action -->
<prop key="/queryItems1.action">itemsController1</prop>
<prop key="/queryItems2.action">itemsController1</prop>
<prop key="/queryItems3.action">itemsController2</prop>
</props>
</property>
</bean>
注解映射器
<!--注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
- 与注解适配器
RequestMappingHandlerAdapter
搭配使用。
配置 HandlerAdapter
HandlerAdapter
会根据适配器接口对后端控制器进行包装(适配),包装后即可对处理器进行执行,通过扩展处理器适配器可以执行多种类型的处理器,这里使用了适配器设计模式。
所有处理器适配器都实现HandlerAdapter
接口:
非注解
SimpleControllerHandlerAdapter
简单控制器处理器适配器,所有实现了org.springframework.web.servlet.mvc.Controller
接口的Bean通过此适配器进行适配、执行。
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
HttpRequestHandlerAdapter
http
请求处理器适配器,所有实现了org.springframework.web.HttpRequestHandler
接口的Bean通过此适配器进行适配、执行。
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
Controller实现如下:
public class ItemList2 implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 商品列表
List<Items> itemsList = new ArrayList<Items>();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone5 苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
// 填充数据
request.setAttribute("itemsList", itemsList);
// 视图
request.getRequestDispatcher("/WEB-INF/jsp/order/itemsList.jsp").forward(request, response);
}
}
从上边可以看出此适配器器的handleRequest
方法没有返回ModelAndView
,可通过response
修改定义响应内容,比如返回json数据:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
注解适配器
<!--注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
- 与注解映射器
RequestMappingHandlerMapping
搭配使用。