spring框架浅结03
我个人理解的springmvc框架是其实是对于web层的简化开发与处理,当然它也有自己的配置文件,需要注意的是我们用javaweb开发是通过web.xml文件的配置实现一定的前端请求与对应的控制层servlet方法的响应。而在springMVC框架里基本也是需要web.xml文件去实现一些很重要的配置的。与spring不同的是,专注在web层开发的springmvc框架是基于注解开发的,这大大的实
我个人理解的springmvc框架是其实是对于web层的简化开发与处理,当然它也有自己的配置文件,需要注意的是我们用javaweb开发是通过web.xml文件的配置实现一定的前端请求与对应的控制层servlet方法的响应。而在springMVC框架里基本也是需要web.xml文件去实现一些很重要的配置的。与spring不同的是,专注在web层开发的springmvc框架是基于注解开发的,这大大的实现代码的简洁。
请求分发器DispatcherServlet
DispatcherServlet的请求与响应流程
-
用户申请Tomcat处理web应用请求前端控制器DispatcherServlet。
-
DispatcherServlet收到请求并调用HanderMapping处理器映射器。
-
处理器映射器找到具体的处理器(可以根据xml配置、注解查找),生成处理对象及处理器拦截器(如果有就生成)一并返回给前端控制器。
-
前端控制器调用HanderAdapter处理器适配器。
-
处理器适配器经过适配具体的处理器(通常是我们设置的controller层,也叫后端控制器)。
-
controller完成任务返回modelandview。
-
处理器适配器将controller执行结果modelandview传给viewReslover视图解析器。
-
视图解析器解析后返回具体view。
-
由modelandview返回给Tomcat进行视图渲染返回客户
见下图:
DispatcherServlet的配置(web.xml文件配置)
<!-- 设置前端控制器DispatcherServet,让servlet服务里的公有行为去帮助我们访问其他的特定行为--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <!--使用框架封装的请求分发器类--> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!--同样的要想实现在前端控制器里对特定行为的访问,必须要将特定行为配置的资源设置为可以初始化读取的参数资源--> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 映射,和servlet成对出现--> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
字符编码过滤器Filter
字符编码过滤器的自定义
import javax.servlet.*; import java.io.IOException; /*过滤器的生命周期:我们看到在测试中,Tomcat工件部署之前就进行了过滤器的初始化,说明过滤器的初始化与Tomcat的部署过程中, * 而过滤器的销毁在本地web服务器销毁之后。*/ public class filters implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("测试过滤器能否读取设置的过滤器编码参数"+filterConfig.getInitParameter("encoding")); System.out.println(filterConfig.getFilterName()+"过滤器被初始化!"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletResponse.setCharacterEncoding("UTF-8"); System.out.println("已经过滤服务名:"+servletRequest.getServerName()); filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { System.out.println("过滤器被销毁!"); } }
自定义字符编码过滤器的配置(web.xml文件):
<!--注册字符过滤器--> <filter> <filter-name>filter1</filter-name> <filter-class>filters</filter-class> <!--设置字符过滤器的放行字符类型参数--> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>filter1</filter-name> <!--拦截路径设置,这个路径下面的包文件会被字符过滤器过滤--> <url-pattern>/*</url-pattern> </filter-mapping>
字符编码过滤器的配置(框架封装配置在web.xml文件里)
<!-- 编码过滤 utf-8,解决中文乱码的问题--> <filter> <description>char encoding filter</description> <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>
字符编码过滤器的生命周期
具体解释见文章:http://t.csdn.cn/oDyw9
生命周期的区域关系:服务器-监听器-过滤器的初始化-正常工作-过滤器的销毁-监听器-服务器。
监听器ContextLoaderListener
全局上下文参数的配置
<!-- 配置spring监听器与上下文参数applicationContext--> <!-- 上下文参数--> <context-param> <param-name>contextConfigLocation</param-name> <!--一般配置进去的内容是需要读取的spring核心配置文件,因为我们需要让Tomcat服务器帮助我们在初始化这个应用的时候将我们的spring容器也实例化出来,同时我们的注入的Bean也会被注入进去,只不过这个Bean的生命周期与作用域还受到一定因素的影响--> <param-value>classpath:/applicationContext.xml</param-value> </context-param>
监听器的作用机制
生命周期的区域关系:服务器-监听器-过滤器的初始化-正常工作-过滤器的销毁-监听器-服务器。
监听器的配置
自定义监听器与配置
public class listeners implements ServletContextListener, HttpSessionListener { /*定义会话人数参数p*/ private int p = 0; @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("初始化监听器"); ServletContext servletContext = sce.getServletContext(); /*读取全局参数can并输出测试servletContext监听器的作用是否起到*/ String context = servletContext.getInitParameter("can"); System.out.println(context); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("销毁监听器!"); } @Override public void sessionCreated(HttpSessionEvent se) { p++; /*将这个p存到当前的会话上下文里,由页面接收并输出会话人数!*/ se.getSession().setAttribute("person",p); /*控制台测试!*/ System.out.println("当前会话人数为"+p); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("销毁会话!"); } }
web.xml中配置
<!-- 设置全局参数can=ssss给监听器识别测试输出 --> <context-param> <param-name>can</param-name> <param-value>sssss</param-value> </context-param> <!--配置监听器--> <listener> <listener-class>listeners</listener-class> </listener>
框架封装监听器的配置(web.xml文件配置)
<!-- 监听器ContextLoaderListener--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
视图解析器InternalResourceViewResolver
视图解析器的作用机制
见DispatcherServlet工作流程图,后续的工作原理会在我的spring源码深入总结里提到。
视图解析器的配置(配置在MVC的核心配置mvc.xml文件里)
<!-- 内部资源视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
实现HandlerInterceptor接口的自定义HL拦截器
Spring MVC 的拦截器类似于 Servlet 中的过滤器 Filter,用于对处理器进行预处理和后处理。 将拦截器按一定的顺序联结成一条链,这条链叫做拦截器链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP面向切面编程思想的一个具体实现。
拦截器的配置
public class MyHandlerInterceptor1 implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("preHandle running..."); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { System.out.println("postHandle running..."); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("afterCompletion running..."); } }
配置在mvc.xml文件里:
<!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <!--拦截路径范围设置--> <mvc:mapping path="/**"/> <bean class="com.hlc.interceptor.MyHandlerInterceptor1"/> </mvc:interceptor> </mvc:interceptors>
-
preHandle() 方法将在请求处理之前进行调用,该方法的返回值是布尔值Boolean类型的, 当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会 再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方 法
-
postHandle() 该方法是在当前请求进行处理之后被调用,前提是preHandle 方法的返回值为 true 时才能被调用,且它会在DispatcherServlet 进行视图返回渲染之前被调 用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象 进行操作
-
afterCompletion() 该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图 之后执行,前提是preHandle 方法的返回值为true 时才能被调用
异常处理器SimpleMappingExceptionResolver
异常处理器的配置(框架封装,配置在mvc.xml文件里)
<!-- 配置异常处理器--> <!--配置使用springmvc的简单异常处理器,这里注意我们也可以自己设置异常处理方法;采用springmvc给我们的HandlerExceptionResolver 接口并实现方法去设置我们的异常处理方式--> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id="exceptionResolver"> <!-- 默认的异常错误视图,error是自定义的视图名称,因为我配置了内部资源视图解析器会自动补全路径和后缀--> <property name="defaultErrorView" value="error"/> <!-- 异常映射。 异常类型 -> 错误视图页面 --> <property name="exceptionMappings"> <map> <!-- 指定这个key对应的异常出现时 跳转的视图页面是error视图--> <entry key="com.hlc.exception.myException" value="error"/> <!-- 这个就是指定的类型转换异常的跳转视图是error1--> <entry key="java.lang.ClassCastException" value="error1"/> </map> </property> </bean>
自定义实现HandlerExceptionResolver接口的异常处理器
实现接口的java类
public class myException extends Throwable implements HandlerExceptionResolver { // 方法中的参数Exception:异常对象 // 显然返回值就是我要跳转的视图信息model and view @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { ModelAndView modelAndView = new ModelAndView(); // 判断异常,对应操作,相当于简单的异常处理器的原理 if(ex instanceof ClassCastException){ modelAndView.addObject("info",ex.toString()); modelAndView.setViewName("error1"); } return modelAndView; } }
配置在mvc配置文件里
<!-- 配置自定义异常处理器--> <bean class="com.hlc.exception.myException" id="exception"/>
区别于spring注解的MVC新注解
-
@RequestMapping 作用:用于建立请求URL和处理请求方法之间的对应关系,位置:可以放在类上,也可以放在方法上。注意路径的变化。属性:value:设置的静态路由的值,也叫URL与path的作用一样。method:指定请求方式,默认是GET请求方式。params:用于指定带参数访问的条件。
-
@RequestParam 请求参数,可以变换URL输入的字符指定为方法体里的某个参数。value就是替换参数之后的值(加入用n替换name,这样在浏览器URL里输入n=XXX就可以了),required = true或者false,作用就是必须输入参数或者可以不输入参数。defaultValue的值是后面参数的默认值,不输入时默认。
-
@RequestHeader value就是指定的头信息名,这个注解的作用就是请求头信息。required同上。
-
@cookieValue 获取指定的cookie值,用法与上请求头信息一致。
-
@ResponseBody 可以使方法返回的字符串按照json格式直接回写到空视图
文件上传
请点击查看这篇文章:http://t.csdn.cn/zm1fq
springMVC框架xml文件常用配置集合
组件扫描
<!--组件扫描--> <context:component-scan base-package="com.hlc.controller"/>
注解驱动
<!-- 注解驱动--> <mvc:annotation-driven/>
静态资源访问开启
<!-- 静态资源访问权限--> <mvc:default-servlet-handler/>
视图解析器
<!-- 内部资源视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
错误页面处理(通常自己写一个错误页面在controller代码里体现出来错误处理)
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id="exceptionResolver"> <!-- 默认的异常错误视图,error是自定义的视图名称,因为我配置了内部资源视图解析器会自动补全路径和后缀--> <property name="defaultErrorView" value="error"/> <!-- 异常映射。 异常类型 -> 错误视图页面 --> <property name="exceptionMappings"> <map> <!-- 指定这个key对应的异常出现时 跳转的视图页面是error视图--> <entry key="com.hlc.exception.myException" value="error"/> <!-- 这个就是指定的类型转换异常的跳转视图是error1--> <entry key="java.lang.ClassCastException" value="error1"/> </map> </property> </bean>
更多推荐
所有评论(0)