阅读量:0
JdbcConfig:
public class JdbcConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { DataSourceTransactionManager ds = new DataSourceTransactionManager(); ds.setDataSource(dataSource); return ds; } }
@Bean:定义第三方的插件bean类
MybatisConfig:
public class MybatisConfig { @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); factoryBean.setTypeAliasesPackage("com.example.domain"); return factoryBean; } @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer msc = new MapperScannerConfigurer(); msc.setBasePackage("com.example.dao"); return msc; } }
ServletConfig:
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer { //加载Spring配置类 protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class}; } //加载SpringMVC配置类 protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } //设置SpringMVC请求地址拦截规则 protected String[] getServletMappings() { return new String[]{"/"}; } //设置post请求中文乱码过滤器 @Override protected Filter[] getServletFilters() { CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setEncoding("utf-8"); return new Filter[]{filter}; } }
SpringConfig:
@Configuration @ComponentScan("com.example.service") @PropertySource("classpath:jdbc.properties") @Import({JdbcConfig.class, MybatisConfig.class}) @EnableTransactionManagement public class SpringConfig { }
@Configuration:标注为配置文件
@ComponentScan:标注要扫描的目录(Spring主要负责service层)
@PropertySource:加载数据库jdbc文件,classPath通过path加载
@Import:加载需要加载的Bean文件
@EnableTransactionManagement:允许启用事务回滚机制
SpringMvcConfig:
@Configuration @ComponentScan("com.example.controller") @EnableWebMvc public class SpringMvcConfig { }
@EnableWebMvc:启用Spring-Mvc功能
resources\jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/数据库名 jdbc.username=账户名 jdbc.password=账户密码
项目主要文件层级:
项目Test层级:
Test文件内容:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class BookServiceTest { @Autowired private BookService bookService; @Test public void testGetById(){ Book book = bookService.getById(15); System.out.println(book); } @Test public void testGetAll(){ List<Book> all = bookService.getAll(); System.out.println(all); } }
@Autowired:自动从spring中取出实体类
@Test:定义为测试类
Dao层:
主要用于数据层,书写sql语句
public interface BookDao { @Insert("insert into tbl_book (type,name,description) values (#{type},#{name},#{description})") public void save(Book book); @Update("update tbl_book set type = #{type},name = #{name},description = #{description} where id = #{id}") public void update(Book book); @Delete("delete from tbl_book where id = #{id}") public void delete(Integer id); @Select("select * from tbl_book where id = #{id}") public Book getById(Integer id); @Select("select * from tbl_book") public List<Book> getAll(); }
Sql方法注解:@Insert、@Update、@Select、@Delete
domain层:
定义数据模态层
public class Book { private Integer id; private String type; private String name; private String description; //省略Getter和Setter... }
Service服务层:
@Transactional public interface BookService { /** * 保存 * * @param book * @return */ public boolean save(Book book); /** * 修改 * * @param book * @return */ public boolean update(Book book); /** * 按id删除 * * @param id * @return */ public boolean delete(Integer id); /** * 按id查询 * * @param id * @return */ public Book getById(Integer id); /** * 查询全部 * * @return */ public List<Book> getAll(); }
@Transactional:定义该Service允许事务回滚
Service的实体类Impl:
@Service public class BookServiceImpl implements BookService { @Autowired private BookDao bookDao; public boolean save(Book book) { bookDao.save(book); return true; } }
@Service:Service层的Impl必须声明为Service才会被Spring自动收集
异常处理类
@RestControllerAdvice public class ProjectExceptionAdvice { //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常 @ExceptionHandler(Exception.class) public void doException(Exception ex){ System.out.println("嘿嘿,异常你哪里跑!") } }
@RestControllerAdvice:@ResponseBody风格的异常处理
@RestControllerAdvice=@ControllerAdvice+@ResponseBody
如异常处理为文件夹,须在SpringMvcConfig中配置ComponentScan
异常分类
分为三类:
1.业务异常(Business Excption)
数据遗漏、提示规范操作
public class BusinessException extends RuntimeException { private Integer code; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public BusinessException(Integer code, String message) { super(message); this.code = code; } public BusinessException(Integer code, String message, Throwable cause) { super(message, cause); this.code = code; } }
2.系统异常(System Excption)
数据库、服务器宕机
public class SystemException extends RuntimeException { private Integer code; public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public SystemException(Integer code, String message) { super(message); this.code = code; } public SystemException(Integer code, String msg, Throwable cause) { super(msg, cause); this.code = code; } }
3.其他异常(Excption)
未预期到的异常
整合异常处理
@RestControllerAdvice public class ProjectExceptionAdvice { @ExceptionHandler(SystemException.class) public Result doSystemException(SystemException ex) { // 记录日志 // 发送消息给运维 // 发送邮件给开发 return new Result(ex.getCode(), null, ex.getMessage()); } @ExceptionHandler(BusinessException.class) public Result doBusinessException(BusinessException ex) { return new Result(ex.getCode(), null, ex.getMessage()); } @ExceptionHandler(Exception.class) public Result doException(Exception ex) { return new Result(Code.SYSTEM_UNKNOW_ERR, null, "系统繁忙,请稍后重试"); } }
拦截器开发
步骤1:创建ProjectInterceptor,重写HandlerInterceptor
@Component public class ProjectInterceptor implements HandlerInterceptor { @Override //原始方法调用前执行的内容 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle..."); return true; } @Override //原始方法调用后执行的内容 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle..."); } @Override //原始方法调用完成后执行的内容 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion..."); } }
步骤2:修改SpringMvcConfig,具有一定侵入性
public class SpringMvcConfig implements WebMvcConfigurer { @Autowired private ProjectInterceptor projectInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { //配置多拦截器 registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*"); } }
通过拦截器获取参数
request:请求体 response:响应体 handler:被调用的处理器对象
preHandle
获取header中内容:request.getHeader(头部key名)
handler:
HandlerMethod hm = (HandlerMethod) handler; String methodName = hm.getMethod().getName();
postHandle
ModelAndView modelAndView:如果处理器执行完成具有返回结果,可以读取到对应数据与页面信息,并进行调整。因为都是返回json数据,所以该参数的使用率不高afterCompletion
配置多个拦截器
新增拦截器文件,在SpringMvcConfig中添加
@Configuration @ComponentScan({"com.example.controller", "com.example.exception"}) @EnableWebMvc public class SpringMvcConfig implements WebMvcConfigurer { @Autowired private ProjectInterceptor projectInterceptor; @Autowired private ProjectInterceptor2 projectInterceptor2; @Override public void addInterceptors(InterceptorRegistry registry) { //配置多拦截器 registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*"); //新添加的拦截器 registry.addInterceptor(projectInterceptor2).addPathPatterns("/books", "/books/*"); } }