1. 异常处理
SpringMVC: HandlerExceptionResolver接口,
该接口的每个实现类 都是异常的一种处理方式:
a.
ExceptionHandlerExceptionResolver: 主要提供了@ExceptionHandler注解,并通过该注解处理异常
//该方法 可以捕获本类中 抛出的ArithmeticException异常
@ExceptionHandler({ArithmeticException.class,ArrayIndexOutOfBoundsException.class })
public String handlerArithmeticException(Exception e) {
System.out.println(e +"============");
return "error" ;
}
@ExceptionHandler标识的方法的参数 必须在异常类型(Throwable或其子类) ,不能包含其他类型的参数
异常处理路径:最短优先
如果有方法抛出一个ArithmeticException异常,而该类中 有2个对应的异常处理法你发:
@ExceptionHandler({Exception.class })
public ModelAndView handlerArithmeticException2(Exception e) {}
@ExceptionHandler({ArithmeticException.class })
public ModelAndView handlerArithmeticException1(Exception e) {}
则优先级: 最短优先。
@ExceptionHandler默认只能捕获 当前类中的异常方法。
如果发生异常的方法 和处理异常的方法 不在同一个类中:@ControllerAdvice
总结:如果一个方法用于处理异常,并且只处理当前类中的异常:@ExceptionHandler
如果一个方法用于处理异常,并且处理所有类中的异常: 类前加@ControllerAdvice、 处理异常的方法前加 @ExceptionHandler
b.
ResponseStatusExceptionResolver:自定义异常显示页面 @ResponseStatus
@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="数组越界222!!!")
public class MyArrayIndexOutofBoundsException extends Exception {//自定义异常
}
@ResponseStatus也可以标志在方法前:
@RequestMapping("testMyException")
public String testMyException(@RequestParam("i") Integer i) throws MyArrayIndexOutofBoundsException {
if(i == 3) {
throw new MyArrayIndexOutofBoundsException();//抛出异常
}
return "success" ;
}
@RequestMapping("testMyException2")
public String testMyException2(@RequestParam("i") Integer i) {
if(i == 3) {
return "redirect:testResponseStatus" ;//跳转到某一个 异常处理方法里
}
return "success" ;
}
c. 异常处理的实现类:
DefaultHandlerExceptionResolver:SPringMVC在一些常见异常的基础上(300 500 405),新增了一些异常,例如:
* @see org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
* @see #handleNoSuchRequestHandlingMethod
* @see #handleHttpRequestMethodNotSupported :如果springmvc的处理方法限制为post方式,如果实际请求为get,则会触发此异常显示的页面
* @see #handleHttpMediaTypeNotSupported
* @see #handleMissingServletRequestParameter
* @see #handleServletRequestBindingException
* @see #handleTypeMismatch
* @see #handleHttpMessageNotReadable
* @see #handleHttpMessageNotWritable
* @see #handleMethodArgumentNotValidException
* @see #handleMissingServletRequestParameter
* @see #handleMissingServletRequestPartException
* @see #handleBindException
d.
SimpleMappingExceptionResolver:通过配置来实现异常的处理
<!-- SimpleMappingExceptionResolver:以配置的方式 处理异常 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 如果发生异常,异常对象会被保存在 exceptionAttribute的value值中;
并且会放入request域中 ;异常变量的默认值是 exception-->
<!--<property name="exceptionAttribute" value="exception"></property>-->
<property name="exceptionMappings">
<props>
<!-- 相当于catch(ArithmeticException ex){ 跳转:error } -->
<prop key="java.lang.ArithmeticException">
error
</prop>
<prop key="java.lang.NullPointerException">
error
</prop>
</props>
</property>
</bean>
2. SSM整合
SSM整合:
Spring - SpringMVC - MyBatis
1 . Spring - MyBatis : 需要整合:将 MyBatis 的 SqlSessionFactory 交给Spring
2. Spring - SpringMVC : 就是将 Spring - SpringMVC 各自配置一遍
思路:
SqlSessionFactory -> SqlSession ->StudentMapper ->CRUD
可以发现 ,MyBatis最终是通过SqlSessionFactory来操作数据库,
Spring整合MyBatis 其实就是 将MyBatis的SqlSessionFactory 交给Spring
SM整合步骤:
1. jar
mybatis-spring.jar spring-tx.jar spring-jdbc.jar spring-expression.jar
spring-context-support.jar spring-core.jar spring-context.jar
spring-beans.jar spring-aop.jar spring-web.jar commons-logging.jar
commons-dbcp.jar ojdbc.jar mybatis.jar log4j.jar commons-pool.jar
2. 类-表
Student类 -student表
3. -(与Spring整合时,conf.xml可省)--MyBatis配置文件conf.xml(数据源、mapper.xml) --可省,将该文件中的配置 全部交由spring管理
spring 配置文件 applicationContext.xml
4. 通过mapper.xml将 类、表建立映射关系
5.
之前使用MyBatis: conf.xml ->SqlSessionFacotry
现在整合的时候,需要通过Spring管理SqlSessionFacotry ,因此 产生qlSessionFacotry 所需要的数据库信息 不在放入conf.xml 而需要放入spring配置文件中
配置Spring配置文件(applicationContext.xml) (Web项目):
web.xml配置
<!-- Web项目中,引入Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
6.使用Spring整合MyBatis :将MyBatis的SqlSessionFactory 交给Spring
applicationContext.xml配置:
<!-- 依赖注入:给service注入dao -->
<bean id="studentService" class="org.lanqiao.service.impl.StudentServiceImpl">
<property name="studentMapper" ref="studentMapper"></property>
</bean>
<!-- 加载db.properties文件 -->
<bean id="config" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="locations">
<array>
<value>classpath:db.properties</value>
</array>
</property>
</bean>
<!-- 配置配置数据库信息(替代mybatis的配置文件conf.xml) -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${username}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- conf.xml : 数据源,mapper.xml -->
<!-- 配置MyBatis需要的核心类:SqlSessionFactory -->
<!-- 在SpringIoc容器中 创建MyBatis的核心类 SqlSesionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- 加载mapper.xml路径 -->
<property name="mapperLocations" value="classpath:org/lanqiao/mapper/*.xml">
</property>
</bean>
<!-- 将MyBatis的SqlSessionFactory 交给Spring -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<property name="basePackage" value="org.lanqiao.mapper"></property>
<!--上面basePackage所在的property的作用:
将org.lanqiao.mapper包中,所有的接口 产生与之对应的 动态代理对象
(对象名 就是 首字母小写的接口名) :studentMapper.querystudentBYNO();
-->
</bean>
===================================================
7.继续整合SpringMVC:将springmvc加入项目即可
a. 加入SpringMVC需要的jar
spring-webmvc.jar
b. 给项目加入SpringMVC支持
web.xml文件中配置 : dispatcherServlet
<!-- 整合SPringMVC -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-controller.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
c. 编写springmvc配置文件:
applicationContext-controller.xml文件配置:视图解析器、基础配置
<!-- 将控制器所在包 加入IOC容器 -->
<context:component-scan base-package="org.lanqiao.controller"></context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- SPringMVC基础配置、标配 -->
<mvc:annotation-driven></mvc:annotation-driven>
===================================
案例
Student.java类
package org.lanqiao.entity;
public class Student {
private int stuNo;
private String stuName;
private int stuAge ;
public int getStuNo() {
return stuNo;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getStuAge() {
return stuAge;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
}
index.jsp
<body>
<a href="controller/queryStudentByNo/1">查询1号学生</a>
<form action="controller/addStudent">
<input name="stuNo" />
<input name="stuName" />
<input name="stuAge" />
<input type="submit" value="增加"/>
</form>
</body>
StudentController.java
@RequestMapping("controller")
@Controller//StudentController加入Ioc容器
public class StudentController {
//控制器依赖于Service
@Autowired
@Qualifier("studentService")
private StudentService studentService;
public void setStudentService(StudentService studentService) {
this.studentService = studentService;
}
@RequestMapping("queryStudentByNo/{stuno}")
public String queryStudentByNo(@PathVariable("stuno") Integer stuNo ,Map<String,Object> map) {
Student student = studentService.queryStudentByNo(stuNo) ;
map.put("student", student) ;
return "result" ;
}
@RequestMapping("addStudent")
public String addStudent(Student student) {
studentService.addStudent(student) ;
return "result" ;
}
}
StudentService.java
package org.lanqiao.service;
import org.lanqiao.entity.Student;
public interface StudentService {
Student queryStudentByNo(int stuNo);
void addStudent(Student student);
}
StudentServiceImpl.java
package org.lanqiao.service.impl;
import org.lanqiao.entity.Student;
import org.lanqiao.mapper.StudentMapper;
import org.lanqiao.service.StudentService;
public class StudentServiceImpl implements StudentService {
//service依赖于dao(mapper)
private StudentMapper studentMapper ;
public void setStudentMapper(StudentMapper studentMapper) {
this.studentMapper = studentMapper;
}
@Override
public Student queryStudentByNo(int stuNo) {
return studentMapper.queryStudentByStuno(stuNo) ;
}
@Override
public void addStudent(Student student) {
studentMapper.addStudent(student);
}
}
StudentMapper.xml文件
<!-- namespace:该mapper.xml映射文件的 唯一标识 -->
<mapper namespace="org.lanqiao.mapper.StudentMapper">
<select id="queryStudentByStuno" parameterType="int" resultType="org.lanqiao.entity.Student" >
select * from student where stuno = #{stuNo}
</select>
<insert id="addStudent" parameterType="org.lanqiao.entity.Student" >
insert into student(stuno,stuname,stuage) values(#{stuNo},#{stuName},#{stuAge})
</insert>
</mapper>
StudentMapper.java类
package org.lanqiao.mapper;
import org.lanqiao.entity.Student;
public interface StudentMapper {
public void addStudent(Student student );
Student queryStudentByStuno(int stuno);
}