查看“SpringMVC:开发基础”的源代码
←
SpringMVC:开发基础
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
[[category:SpringMVC]] == 基础 == SpringMVC框架是一个开源的Java平台,属于[[Spring框架 Spring]]的一部分,是一个轻量级的web框架。<br/> (Spring框架最初由Rod Johnson撰写,并于2003年6月根据Apache 2.0许可证首次发布。)<br/> SpringMVC在三层架构(表示层UI、业务逻辑层BLL、持久层DAL)中处于表示层。 === MVC === MVC框架用于开发灵活和松散耦合的Web应用程序的组件: # 模型(Model):封装了应用程序数据,通常它们将由POJO(<code>Plain Ordinary Java Object</code>简单Java对象,即区别于EJB的普通JavaBean)类组成。 #: <code>pojo</code>、<code>action</code>、<code>service</code>、<code>dao</code> # 视图(View):负责渲染模型数据,一般来说它生成客户端浏览器可以解释HTML输出。 #: <code>jsp</code>、<code>pdf</code>、<code>excel</code>、<code>framework</code> # 控制器(Controller):负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。 #: struts2中的<code>filter</code> === 架构 === {| class="wikitable" |- | # 用户发送请求至'''<code>DispatcherServlet</code>'''; # '''<code>DispatcherServlet</code>'''收到请求调用'''<code>HandlerMapping</code>'''; # '''<code>HandlerMapping</code>'''根据请求'''<code>url</code>'''找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给'''<code>DispatcherServlet</code>'''; # '''<code>DispatcherServlet</code>'''通过'''<code>HandlerAdapter</code>'''调用处理器; # 执行'''<code>Controller</code>'''; # '''<code>Controller</code>'''执行完成返回'''<code>ModelAndView</code>'''; # '''<code>HandlerAdapter</code>'''将'''<code>controller</code>'''执行结果'''<code>ModelAndView</code>'''返回给'''<code>DispatcherServlet</code>'''; # '''<code>DispatcherServlet</code>'''将'''<code>ModelAndView</code>'''传给'''<code>ViewReslover</code>'''视图解析器; # '''<code>ViewReslover</code>'''解析后返回具体'''<code>View</code>'''; # '''<code>DispatcherServlet</code>'''对View进行渲染视图(即将模型数据填充至视图中); # '''<code>DispatcherServlet</code>'''响应用户; | [[File:springMVC架构.png|800px]] |} === 依赖包 === springMVC属于spring的一个部分,所以需要spring包的支持: [[File:spring3.2.0的jar包.png|none|250px]] === 组件 === # '''<code>DispatcherServlet</code>'''(前端控制器):作用接收请求,响应结果,相当于转发器、中央处理器,减少其它组件之间的耦合度; # '''<code>HandlerMapping</code>'''(处理器映射器):根据请求的url查找Handler; # '''<code>HandlerAdapter</code>'''(处理器适配器):按照特定规则(<code>HandlerAdapter</code>要求的规则)去执行<code>Handler</code>; # '''<code>Handler</code>'''(Controller:处理器):编写<code>Handler</code>时按照<code>HandlerAdapter</code>的要求去做,这样适配器才可以去正确执行<code>Handler</code>; # '''<code>ViewReslover</code>'''(视图解析器):进行视图解析,根据逻辑视图名解析成真正的视图(<code>view</code>); # '''<code>View</code>'''(视图):<code>View</code>是一个接口,实现类支持不同的视图类型(<code>jsp</code>、<code>pdf</code>、<code>excel</code>、<code>framework</code>); === 配置文件 === {| class="wikitable" |- ! 配置文件 !! 说明 !! 图 |- | web.xml | # 位置:“WEB-INF\web.xml”; # 用于:配置'''<code>Filter</code>'''、'''<code>Listener</code>'''、'''<code>Servlet等</code>'''及Servlet拦截方式等;('''<code>DispatcherServlet</code>''') | rowspan="2" | [[File:springMVC配置文件.png|300px]] |- | springmvc.xml | # 位置:默认加载'''<code>WEB-INF/[前端控制器的名字]-servlet.xml</code>''',也可以在前端控制器定义处指定加载的配置文件; # 用于:配置'''<code>HandlerMapping</code>'''、'''<code>HandlerAdapter</code>'''、'''<code>Handler</code>'''(组件扫描)、'''<code>ViewResolver</code>'''等; |} ==== web.xml示例 ==== <syntaxhighlight lang="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> </syntaxhighlight> ==== springmvc.xml示例 ==== <syntaxhighlight lang="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> </syntaxhighlight> == 开发基础 == === 建立项目 === Eclipse:Dynamic Web Project === 导入依赖包 === springmvc独立运行需要的jar: # <code>commons-logging-1.1.1.jar</code> # <code>jstl-1.2.jar</code> # <code>spring-aop-3.2.0.RELEASE.jar</code> # <code>spring-aspects-3.2.0.RELEASE.jar</code> # <code>spring-beans-3.2.0.RELEASE.jar</code> # <code>spring-context-3.2.0.RELEASE.jar</code> # <code>spring-context-support-3.2.0.RELEASE.jar</code> # <code>spring-core-3.2.0.RELEASE.jar</code> # <code>spring-expression-3.2.0.RELEASE.jar</code> # <code>spring-jdbc-3.2.0.RELEASE.jar</code> # <code>spring-orm-3.2.0.RELEASE.jar</code> # <code>spring-test-3.2.0.RELEASE.jar</code> # <code>spring-tx-3.2.0.RELEASE.jar</code> # <code>spring-web-3.2.0.RELEASE.jar</code> # <code>spring-webmvc-3.2.0.RELEASE.jar</code> === 配置DispatcherServlet === (关于[[servlet]])<br/> 在'''<code>web.xml</code>'''中配置前端控制器: <syntaxhighlight lang="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> </syntaxhighlight> 其中: # '''<code>contextConfigLocation</code>''':配置<code>springmvc</code>加载的配置文件(配置处理器映射器、适配器等等); #: 如果不配置<code>contextConfigLocation</code>,默认加载的是'''<code>/WEB-INF/servlet名称-serlvet.xml(springmvc-servlet.xml)</code>'''; # '''<code>load-on-startup</code>''':表示容器启动优先级: #: 当值为0或者大于0时,表示容器在应用启动时就加载这个servlet; #: 非负数时,值越小优先级越高; #: 负数时或未指定时,则指示容器在该servlet被选择时才加载; <br/> <code>DispathcerServlet</code>作为<code>springmvc</code>的中央调度器存在,<code>DispatcherServlet</code>创建时会默认从<code>DispatcherServlet.properties</code>(“Dspring-webmvc-3.2.0.RELEASE.jar”>>“org.springframework.web.servlet”>>“DispatcherServlet.properties”)文件加载<code>springmvc</code>所用的各各组件,如果在<code>springmvc.xml</code>中配置了组件则以<code>springmvc.xml</code>中配置的为准,<code>DispatcherServlet</code>的存在降低了<code>springmvc</code>各各组件之间的耦合度。<br/> <br/> DispatcherServlet.properties: <syntaxhighlight lang="xml"> # 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 </syntaxhighlight> ==== Servlet拦截方式 ==== # '''<code>*.action</code>''':拦截固定后缀的<code>url</code>(如<code>*.do</code>、<code>*.action</code>),由DispatcherServlet进行解析; #: 例如:<code>/user/add.action</code>,此方法最简单,不会导致静态资源(<code>jpg</code>、<code>js</code>、<code>css</code>)被拦截。 # '''<code>/</code>''':除jsp之外的全拦截。所有访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析; #: (此方法可以实现<code>REST</code>风格的<code>url</code>) #: 例如:<code>/user/add</code>、<code>/user/add.action</code>,但是会导致静态文件(<code>jpg</code>、<code>js</code>、<code>css</code>)被拦截后不能正常显示,需要特殊处理。 # '''<code>/*</code>''':全拦截; #: 使用这种配置,最终要转发到一个<code>jsp</code>页面时,仍然会由<code>DispatcherServlet</code>解析<code>jsp</code>地址,不能根据<code>jsp</code>页面找到<code>handler</code>,会报错; === 配置 HandlerMapping === <code>HandlerMapping</code> 负责根据<code>request</code>请求找到对应的<code>Handler</code>处理器及<code>Interceptor</code>拦截器,将它们封装在<code>HandlerExecutionChain</code>对象中给前端控制器(DispatcherServlet)返回。<br/> 所有的映射器都实现'''<code>HandlerMapping</code>'''接口: ==== 非注解 ==== ===== BeanNameUrlHandlerMapping ===== 根据请求的url与spring容器中定义的bean的name进行匹配,从而从spring容器中找到bean实例。 <syntaxhighlight lang="xml"> <!-- 处理器映射器 将bean的name作为url进行查找 ,需要在配置Handler时指定beanname(就是url) 所有的映射器都实现 HandlerMapping接口。 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> </syntaxhighlight> ===== 简单url映射 ===== BeanNameUrlHandlerMapping的增强版本,它可以将url和处理器bean的id进行统一映射配置。 <syntaxhighlight lang="xml"> <!--简单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> </syntaxhighlight> ==== 注解映射器 ==== <syntaxhighlight lang="xml"> <!--注解映射器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> </syntaxhighlight> # 与注解适配器'''<code>RequestMappingHandlerAdapter</code>'''搭配使用。 === 配置 HandlerAdapter === <code>HandlerAdapter</code>会根据适配器接口对后端控制器进行包装(适配),包装后即可对处理器进行执行,通过扩展处理器适配器可以执行多种类型的处理器,这里使用了适配器设计模式。<br/> 所有处理器适配器都实现'''<code>HandlerAdapter</code>'''接口: ==== 非注解 ==== ===== SimpleControllerHandlerAdapter ===== 简单控制器处理器适配器,所有实现了'''<code>org.springframework.web.servlet.mvc.Controller</code>'''接口的Bean通过此适配器进行适配、执行。 <syntaxhighlight lang="xml"> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /> </syntaxhighlight> ===== HttpRequestHandlerAdapter ===== <code>http</code>请求处理器适配器,所有实现了'''<code>org.springframework.web.HttpRequestHandler</code>'''接口的Bean通过此适配器进行适配、执行。 <syntaxhighlight lang="xml"> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/> </syntaxhighlight> Controller实现如下: <syntaxhighlight lang="java"> 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); } } </syntaxhighlight> 从上边可以看出此适配器器的<code>handleRequest</code>方法没有返回<code>ModelAndView</code>,可通过<code>response</code>修改定义响应内容,比如返回json数据: <syntaxhighlight lang="java"> response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write("json串"); </syntaxhighlight> ==== 注解适配器 ==== <syntaxhighlight lang="xml"> <!--注解适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> </syntaxhighlight> # 与注解映射器'''<code>RequestMappingHandlerMapping</code>'''搭配使用。 === 配置 Handler === === 配置 ViewReslover === === Handler开发 === ==== 非注解 ==== # 使用不同的HandlerAdapter(SimpleControllerHandlerAdapter、HttpRequestHandlerAdapter)需要Handler实现不同的接口(Controller、HttpRequestHandler); # ModelAndView:包含了模型数据及逻辑视图名; <syntaxhighlight lang="java"> public class ItemList1 implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { //商品列表 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("iphone6苹果手机!"); itemsList.add(items_1); itemsList.add(items_2); //创建modelAndView准备填充数据、设置视图 ModelAndView modelAndView = new ModelAndView(); //填充数据 modelAndView.addObject("itemsList", itemsList); //视图 modelAndView.setViewName("order/itemsList"); return modelAndView; } } </syntaxhighlight> ==== 注解 ==== # 注解的Handler需要使用配对的HandlerMapping与HandlerAdapter(RequestMappingHandlerMapping、RequestMappingHandlerAdapter); # 使用<code>@Controller</code>与<code>@RequestMapping("/queryItem.action")</code>进行注解说明,替换接口继承和映射配置; <syntaxhighlight lang="java"> @Controller public class ItemList3 { @RequestMapping("/queryItem.action") public ModelAndView queryItem() { // 商品列表 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("iphone6苹果手机!"); itemsList.add(items_1); itemsList.add(items_2); // 创建modelAndView准备填充数据、设置视图 ModelAndView modelAndView = new ModelAndView(); // 填充数据 modelAndView.addObject("itemsList", itemsList); // 视图 modelAndView.setViewName("order/itemsList"); return modelAndView; } } </syntaxhighlight> === View开发 === === 部署与测试 === == 与[[Structs2]]的区别 ==
返回至“
SpringMVC:开发基础
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
大陆简体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
笔记
服务器
数据库
后端
前端
工具
《To do list》
日常
阅读
电影
摄影
其他
Software
Windows
WIKIOE
所有分类
所有页面
侧边栏
站点日志
工具
链入页面
相关更改
特殊页面
页面信息