SpringMVC的概述:
springmvc是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB框架,属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面,其流程都是基于组件方式执行。
SpringMVC 和 Struts2 的优略分析:
共同点:
它们都是表现层框架,都是基于 MVC 模型编写的。
它们的底层都离不开原始 ServletAPI。
它们处理请求的机制都是一个核心控制器。
区别:
Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter
Spring MVC 是基于方法设计的,而 Struts2 是基于类,Struts2 每次执行都会创建一个动作类。所以 Spring MVC 会稍微比 Struts2 快些。
Spring MVC 使用更加简洁,同时还支持 JSR303(它定义了很多常用的校验注解,我们可以直接将这些注解加在我们 JavaBean 的属性上面,就可以在需要校验的时候进行校验了。), 处理 ajax 的请求更方便。
Struts2 的 OGNL 表达式使页面的开发效率相比 Spring MVC 更高些,但执行效率并没有比 JSTL 提升,尤其是 struts2 的表单标签,远没有 html 执行效率高。
入门程序
- 在web.xml配置文件中配置过滤器和核心控制器
/* 配置过滤器,解决中文乱码的问题 */
<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>
/*SpringMVC的核心控制器 */
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-
class>
<!-- 配置Servlet的初始化参数,读取springmvc的配置文件,创建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet启动时加载对象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.编写springmvc.xml的配置文件
/* 配置spring创建容器时要扫描的包 */
<context:component-scan base-package="cn.kjcoder.controller"/>
/*视图解析器对象*/
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--文件所在的目录-->
<property name="prefix" value="/WEB-INF/pages/"/>
<!--文件的后缀名-->
<property name="suffix" value=".jsp"/>
</bean>
/* 配置spring开启注解mvc的支持,此注解自动加载处理映射器和处理适配器*/
<mvc:annotation-driven></mvc:annotation-driven>
/*哪些静态资源不拦截*/
<mvc:default-servlet-handler/>
@执行流程分析:
- 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件
- 开启了注解扫描,那么Controller类就会被加载进容器创建成对象。
- 从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法。
- 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件,最后渲染页面,做出响应。
组件分析:
前端控制器(DispatcherServlet):用户请求到达前端控制器,它就相当于 mvc 模式中的 c,控制整个流程的执行。
处理器映射器(HandlerMapping):可以让你找到我具体的哪个Controller类的哪个方法去执行。
处理器适配器(HandlAdapter):可以把任何的Controller全适配上,帮你去执行方法。
视图解析器(View Resolver):可以跳转到指定的页面去展示数据。
自定义类型转换器
1.如果想自定义数据类型转换,可以实现Converter的接口
public class StringToDateConverter implements Converter<String, Date> {
/**
*
* @param source 传入进来的字符串
* @return
*/
@Override
public Date convert(String source) {
if(source == null){
throw new RuntimeException("请您传入数据");
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(source);
} catch (Exception e) {
throw new RuntimeException("数据类型转换出现错误");
}
}
}
2.注册自定义类型转换器,在springmvc.xml配置文件中编写配置
<!--配置自定义类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
//指定自定义类型所在的类
<bean class="cn.kjcoder.utils.StringToDateConverter"/>
</set>
</property>
</bean>
<!--开启springmvc对注解的支持,这个标签对 自定义类型转换器 不生效,所以必须把类型转换器在这里配置一下,使它生效-->
<mvc:annotation-driven conversion-service="conversionService"/>
SpringMvc常用注解:
"RequestMapping":RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系,可作用在方法和类上。常用属性有value(path)和mthod。
"RequestParam":把请求中的指定名称的参数传递给控制器中的形参赋值。属性:value:请求参数中的名称。required:请求参数中是否必须提供此参数,默认值是true,必须提供
"RequestBody":用于获取请求体内容。直接使用得到是 key=value&key=value..结构的数据。
"PathVariable":绑定url中的占位符的。例:@RequestMapping("/testPathVariable/{sid}")
//将name属性的sid的值赋值给id
public String testPathVariable(@PathVariable(value="sid") String id){
System.out.println("执行了");
System.out.println(id);
return "success";
}
"ResponseBody": 在方法上添加该注解,该方法就不会走视图解析器,会直接返回一个字符串。
"RestController":在类上使用,该类中的Controller方法都只会返回Json字符串
"ModelAttribute":出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。应用场景:当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
"SessionAttribute":用于多次执行控制器方法间的参数共享。将数据存入session域中。在类上使用。例:@SessionAttributes(value={"msg"})//把msg=允允存入到session域对象中。
SpringMVC返回值类型及响应数据类型:
ModelAndView 是 SpringMVC 为我们提供的一个对象,该对象也可以用作控制器方法的返回值。该对象中有两个方法,addObject(用于存储数据)和setViewName(用于跳转页面),然后在指定的页面通过el表达式进行取值。
SpringMvc异常处理
异常处理配置步骤:
1.编写自定义异常类(做提示信息)
public class SysException extends Exception{
private String message;
//省略get和set方法,带参构造方法
}
2.编写异常处理器类(实现HandlerExceptionResolver接口)
public class SysExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
//获取到异常对象
SysException ex = null;
if(e instanceof SysException){
ex = (SysException) e;
}else{
e = new SysException("系统正在维护。。。");
}
//创建ModelAndView对象
ModelAndView mv = new ModelAndView();
mv.addObject("errorMsg",ex.getMessage());
mv.setViewName("error");
return mv;
}
}
3.配置异常处理器(跳转到提示页面)
<!--在springmvc中配置异常处理器-->
<bean id="sysException" class="cn.kjcoder.exception.SysExceptionResolver"></bean>
SpringMVC中的拦截器
拦截器的概述:
1.用于对处理器进行预处理和后处理的技术,还可以定义拦截器链。
2. 拦截器和过滤器的功能比较类似,有区别:
①过滤器是Servlet规范的一部分,任何 java web 工程和框架都可以使用过滤器技术。
②拦截器是SpringMVC框架独有的。
③过滤器配置了/*,可以拦截任何资源。
④ 拦截器只会对控制器中的方法进行拦截。
自定义拦截器配置步骤:
1.编写拦截器类,实现HandlerInterceptor接口,接口中有3个方法。
"preHandle",预处理:controller方法执行前执行,可以进行一些用户是否登录的判断,没登录就跳转到登录页面去。返回值是boolean,true 放行执行下一个拦截器,如果没有,就执行controller中的方法,false 不放行。
"postHandle",后处理方法 controller 方法执行后,Controller要返回的页面(success.jsp)执行前。
"afterCompletion",Controller要返回的页面(success.jsp)执行后,该方法会执行,但是不能再跳转到别的页面了,可用于一些资源的释放。
2.配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<!--配置第一个拦截器-->
<mvc:interceptor>
<!--要拦截的具体方法-->
<mvc:mapping path="/user/*"/>
<!--不拦截的方法-->
<!-- <mvc:exclude-mapping path=""/>-->
<!--配置拦截器对象-->
<bean class="cn.kjcoder.interceptor.InterceptorDemo01"></bean>
</mvc:interceptor>
<!--配置第二个拦截器-->
<mvc:interceptor>
<!--要拦截的具体方法-->
<mvc:mapping path="/**"/>
<!--不拦截的方法-->
<!-- <mvc:exclude-mapping path=""/>-->
<!--配置拦截器对象-->
<bean class="cn.kjcoder.interceptor.InterceptorDemo02"></bean>
</mvc:interceptor>
</mvc:interceptors>