本人是一名物联网工程专业大二的学生,是互联网浪潮中一朵小小的浪花,写博客即是为了记录自己的学习历程,又希望能够帮助到很多和自己一样处于起步阶段的萌新。临渊羡鱼,不如退而结网。一起加油!
博客主页:https://blog.csdn.net/qq_44895397
请求重定向和转发
当处理器对请求处理完毕后,向其它资源进行跳转时,有两种跳转方式:请求转发与重定向。而根据所要跳转的资源类型,又可分为两类:跳转到页面与跳转到其它处理器。
对于请求转发的页面,可以是WEB-INF中页面;而重定向的页面,是不能为WEB-INF中页的。因为重定向相当于用户再次发出一次请求,而用户是不能直接访问 WEB-INF 中资源的
SpringMVC 框架把原来 Servlet 中的请求转发和重定向操作进行了封装。现在可以使用简单的方式实现转发和重定向。
- forward:表示转发,实现request.getRequestDispatcher(“xx.jsp”).forward()
- redirect:表示重定向,实现 response.sendRedirect(“xxx.jsp”)
请求转发
处理器方法返回 ModelAndView 时,需在 setViewName()指定的视图前添加 forward:,且此时的视图不再与视图解析器一同工作,这样可以在配置了解析器时指定不同位置的视图。视图页面必须写出相对于项目根的路径。forward 操作不需要视图解析器。处理器方法返回 String,在视图路径前面加入 forward: 视图完整路径。
语法:setViewName(“forward:使徒的完整路径”);
@RequestMapping("/handlerIntercwptor.do")
public ModelAndView forwardDemo(String name ,Integer age){
ModelAndView mv = new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage",age);
mv.setViewName("forward:/WEB-INF/view/forward.jsp");
return mv;
}
请求重定向
在处理器方法返回的视图字符串的前面添加 redirect:,则可实现重定向跳转。
处理器方法定义:
@RequestMapping("/handlerIntercwptor.do")
public ModelAndView redirectDemo(String name ,Integer age){
ModelAndView mv = new ModelAndView();
mv.addObject("myname",name);
mv.addObject("myage",age);
mv.setViewName("redirect:/redirect.jsp");
//mv.setViewName("redirect:/WEB-INF/view/forward.jsp");
return mv;
}
异常处理
@ExceptionHandler 注解
使用注解@ExceptionHandler 可以将一个方法指定为异常处理方法。该注解只有一个可选属性 value,为一个 Class<?>数组,用于指定该注解的方法所要处理的异常类,即所要匹配的异常。
而被注解的方法,其返回值可以是 ModelAndView、String,或 void,方法名随意,方法参数可以是 Exception 及其子类对象、HttpServletRequest、HttpServletResponse 等。系统会自动为这些方法参数赋值。
对于异常处理注解的用法,也可以直接将异常处理方法注解于Controller 之中
public @interface ExceptionHandler {
Class<? extends Throwable>[] value() default {};
}
使用步骤:
- 自定义异常类
- 修改Controller抛出异常
- 自定义异常响应页面
- 自定义一场全局处理类
- 修改配置文件(声明异常类的存在)
Controller抛出异常:
@RequestMapping("/some.do")
public ModelAndView addStudent(String name, Integer age) throws MyException {
ModelAndView mv = new ModelAndView();
if (!"zs".equals(name)) {
throw new NameException("名字有误");
}
if(age==null||age>100){
throw new AgeException("年龄异常");
}
mv.addObject("myname", name);
mv.addObject("myage", age);
mv.setViewName("show");
return mv;
}
/**
* @ControllerAdvice :控制器增强,给控制器类增强功能
* 在类上使用
* 需要使用组件扫描器,让框架知道这个注解所在的包名
*
* 处理异常的方法和控制器方法的定义一样可以以有多个参数,可以返回ModelAndView
* String,void对象返回值
* 形参:Exception,获取异常发生的信息
* @ExceptionHandler :异常的class,表示发生异常的类型
*/
@ControllerAdvice
public class MyHandler {
@ExceptionHandler(NameException.class)
public ModelAndView ageExcrption(Exception e){
ModelAndView mv = new ModelAndView();
mv.addObject("msg","宁输入的姓名异常");
mv.addObject("message",e.getMessage());
mv.setViewName("ageErorr");
return mv;
}
}
拦截器
SpringMVC 中的 Interceptor 拦截器它的主要作用是拦截指定的用户请求,并进行相应的预处理与后处理。其拦截的时间点在“处理器映射器根据用户提交的请求映射出了所要执行的处理器类,并且也找到了要执行该处理器类的处理器适配器,在处理器适配器执行处理器之前”。当然,在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链,并返回给了中央调度器。
一个拦截器的执行
- preHandle(request,response, Object handler):
该方法在处理器方法执行之前执行。其返回值为 boolean,若为 true,则紧接着会执行处理器方法,且会将 afterCompletion()方法放入到一个专门的方法栈中等待执行。
/**
* preHandle:预处理方法,
* Object handler:被拦截的控制器对象
* 返回值:boolean
* true:表示能够进入控制方法,
* false:请求被拦截
* 特点:
* 1、方法在控制器方法之前执行
* 2、这个方法中能够验证请求的信息,验证请求是否符合要求
* 验证失败可以截断请求
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("preHandle,验证通过");
return true;
}
- postHandle(request,response,Objecthandler,modelAndView):
该方法在处理器方法执行之后执行。处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。
/**
*后处理方法:
* handler :被拦截的处理器对象
* modelAndView:处理器方法的返回值,能够修改
* 在处理器方法之后进行,没有返回值
* 能够获取处理器返回值,能够修改视图和值
* 对执行结果进行二次修正
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
- afterCompletion(request,response, Object handler, Exception ex):
当 preHandle()方法返回 true 时,会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法。即该方法是在中央调度器渲染(数据填充)了响应页面之后执行的,此时对 ModelAndView 再操作也对响应无济于事。
afterCompletion 最后执行的方法,清除资源,例如在 Controller 方法中加入数据
/**
* 最后执行的方法
*
*Exception:程序发生的异常
* 在请求处理完成过后执行,视图处理完成后,对视图进行了forward就认为请求处理完成
* 一般做资源回收工作
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
System.out.println("afterCompletion");
}
拦截器中方法与处理器方法的执行顺序如下图:
多个拦截器的执行
当有多个拦截器时,形成拦截器链。拦截器链的执行顺序,与其注册顺序一致。需要再次强调一点的是,当某一个拦截器的preHandle()方法返回 true 并被执行到时,会向一个专门的方法栈中放入该拦截器的 afterCompletion()方法。
SSM的整合
两个容器:
- SpringMVC容器,管理Controller对象
- Spring容器,管理service,dao,工具类
实现步骤:
-
建表
-
新建maven项目
-
加入依赖:
SpringMVC,servlet,jsp,jackson,Spring,Spring事务,Spring-MyBatis,Mybatis,mysql驱动,druid连接池 -
web.xml
1)注册DispatcherServlet,目的:创建springmvc容器,才能创建Controller类对象
2)注册spring监听器:ContextLoaderListener,创建spring容器对象,才能创建service,dao等对象
3)注册字符集过滤器,post请求乱码 -
创建包,Controller,service,dao,实体类
-
springmvc,spring,mybatis的配置文件
pom.xml:
<dependencies>
<!--添加依赖-->
<!--servlet依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2.1-b03</version>
<scope>provided</scope>
</dependency>
<!--springmvc的依赖,自动导入了spring的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--spring管理事务的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--jkson的依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<!--mybatis的依赖,spring-mybatis的依赖,德鲁伊连接池-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!--Resource注解无法使用-->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
spring的主配置文件:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:conf/mybatis.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<property name="basePackage" value="com.yky.dao" />
</bean>
<!--创建出service的对象使用注解完成,添加注解扫描器-->
<context:component-scan base-package="com.yky.service" />
springmvc的配置文件:
- 组件扫描器
- 视图解析器
- 数据类型转为json时用到@ResponseBody注解启动
能够解决访问静态资源时的冲突问题
<context:component-scan base-package="com.yky.Controller"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:annotation-driven/>
本站所有文章均为原创,欢迎转载,请注明文章出处:爱敲代码的小游子