SSM整合
包层次结构
一、整合配置
Spring配置类
package com.GY.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan("com.GY.service")
@PropertySource("jdbc.properties")
@Import({JdbcConfig.class,MybatisConfig.class})
public class SpringConfig {
}
SpringMVC配置类
package com.GY.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan("com.GY.controller")
@EnableWebMvc
public class SpringmvcConfig {
}
Jdbc配置类
package com.GY.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String name;
@Value("${jdbc.password}")
private String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource=new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(name);
dataSource.setPassword(password);
return dataSource;
}
}
MyBatis配置类
package com.GY.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
SqlSessionFactoryBean S=new SqlSessionFactoryBean();
S.setDataSource(dataSource);
S.setTypeAliasesPackage("com.GY.domain");
return S;
}
//扫描映射
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer M=new MapperScannerConfigurer();
M.setBasePackage("com.GY.dao");
return M;
}
}
Web容器配置类
package com.GY.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringmvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//当有表单提交需求时乱码可设置过滤器
protected Filter[] getServletFilters(){
CharacterEncodingFilter filter=new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
二、功能模块开发
POJO封装对象
数据层接口
package com.GY.dao;
import com.GY.domain.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserDao {
@Insert("insert into user values (#{id},#{name},#{money})")
void save(User user);
@Delete("delete from user where id=#{id}")
void delete(Integer id);
@Update("update user set name=#{name},money=#{money} where id=#{id}")
void update(User user);
@Select("select * from user where id=#{id};")
User getById(Integer id);
@Select("select * from user")
List<User> getAll();
}
业务层接口
package com.GY.service;
import com.GY.domain.User;
import java.util.List;
public interface UserService {
//保存
boolean save(User user);
//根据id删除
boolean delete(Integer id);
//修改
boolean update(User user);
//根据id查询
User getById(Integer id);
//查询全部
List<User> getAll();
}
业务层实现类
package com.GY.service.Impl;
import com.GY.dao.UserDao;
import com.GY.domain.User;
import com.GY.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public boolean save(User user) {
userDao.save(user);
return true;
}
public boolean delete(Integer id) {
userDao.delete(id);
return true;
}
public boolean update(User user) {
userDao.update(user);
return true;
}
public User getById(Integer id){
return userDao.getById(id);
}
public List<User> getAll() {
return userDao.getAll();
}
}
基于Restful的Controller控制器类开发
package com.GY.controller;
import com.GY.domain.User;
import com.GY.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public boolean save(@RequestBody User user) {
return userService.save(user);
}
@DeleteMapping("/{id}")
public boolean delete(@PathVariable Integer id) {
return userService.delete(id);
}
@PutMapping
public boolean update(@RequestBody User user) {
return userService.update(user);
}
@GetMapping("/{id}")
public User getById(@PathVariable Integer id){
return userService.getById(id);
}
@GetMapping
public List<User> getAll() {
return userService.getAll();
}
}
三、接口测试
业务层接口测试
import com.GY.config.SpringConfig;
import com.GY.domain.User;
import com.GY.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserTest {
@Autowired
private UserService userService;
@Test
public void testById(){
User user= userService.getById(1);
System.out.println(user);
}
@Test
public void tsetGetAll(){
List<User> All = userService.getAll();
System.out.println(All);
}
}
测试成功
表现层接口测试
① 查询全部
② 添加
再次查询发现添加操作成功
🎊🎊🎊
由此说明我们的接口均可正常实现
四、表现层与前端数据传输协议实现
表现层数据封装
● 前端接收数据格式
🚸🚸🚸
【问题】前端接收数据格式多种多样,数据无法解析
此时,便需要对接收的数据统一格式
设置统一数据返回结果类
(data:数据) ( code:编码) (msg:消息)
● 前端接收数据模型实现
数据返回结果类(Result类)
设置统一数据返回结果编码(Code类)
package com.GY.controller;
public class Code {
public static final Integer SAVE_OK=11;
public static final Integer DELETE_OK=21;
public static final Integer UPDATE_OK=31;
public static final Integer GET_OK=41;
public static final Integer SAVE_ERR=10;
public static final Integer DELETE_ERR=20;
public static final Integer UPDATE_ERR=30;
public static final Integer GET_ERR=40;
}
表现层封装数据(根据情况设定合理的Result)
package com.GY.controller;
import com.GY.domain.User;
import com.GY.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public Result save(@RequestBody User user) {
boolean flag=userService.save(user);
return new Result(flag?Code.SAVE_OK:Code.SAVE_ERR,flag) ;
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
boolean flag=userService.delete(id);
return new Result(flag?Code.DELETE_OK:Code.DELETE_ERR,flag);
}
@PutMapping
public Result update(@RequestBody User user) {
boolean flag=userService.update(user);
return new Result(flag?Code.UPDATE_OK:Code.UPDATE_ERR,flag);
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id){
User user=userService.getById(id);
Integer code=user!=null?Code.GET_OK:Code.GET_ERR;
String msg=user!=null?"":"数据查询失败,请重试";
return new Result(code,user,msg);
}
@GetMapping
public Result getAll() {
List<User> user=userService.getAll();
Integer code=user!=null?Code.GET_OK:Code.GET_ERR;
String msg=user!=null?"":"数据查询失败,请重试";
return new Result(code,user,msg);
}
}
Apifox中模拟数据请求
eg: ①模拟添加数据业务
eg: ①模拟查询全部数据业务
五、异常处理器
程序开发过程中不可避免的会遇到异常现象
● 出现异常现象的常见位置与常见诱因
① 框架内部抛出异常:因使用不合规导致
② 数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时)
③ 业务层抛出的异常:因业务逻辑书写错误导致(例如:遍历业务书写操作,导致索引异常等)
④ 表现层抛出的异常:因数据收集、校验等规则导致(例如:不匹配的数据类型间导致异常)
⑤ 工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等)
【思考】
1、各个层级均出现异常,异常处理代码书写在哪一层 ?
——所有的异常均抛出到表现层进行处理
2、表现层处理异常,每个方法中单独书写,代码书写量巨大且意义不强,如何解决 ?
——AOP思想
总结:异常要分类处理;异常要放到表现层处理;异常要使用AOP的思想来处理
项目异常分类
业务异常(BusinessException)
不规范的用户行为操作产生的异常
规范的用户行为产生的异常
【处理方案】 发送对应消息传递给用户,提醒规范操作
系统异常(SystemException)
项目运行过程中可预计且无法避免的异常
eg: 服务器宕机、中央服务器出现问题等… .
【处理方案】
◆ 发送固定消息传递给用户,安抚用户
◆ 发送特定消息给运维人员,提醒维护
◆ 记录日志
其他异常(Exception)
编程人员未预期到的异常
【处理方案】
◆ 发送固定消息传递给用户,安抚用户
◆ 发送特定消息给编程人员,提醒维护(纳入预期范围内)
◆ 记录日志
项目异常处理方案
◆集中的、统一的处理项目中的异常
自定义项目业务/系统级异常
eg:
模拟业务异常(触发自定义异常)
异常处理器(拦截并处理异常)
package com.GY.controller;
import com.GY.exception.BusinessException;
import com.GY.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//声明此类用来做异常处理(Rest风格)
@RestControllerAdvice
public class ProjectExceptionAdvice {
//拦截哪种异常:业务异常
@ExceptionHandler(SystemException.class)
public Result doSystemException(SystemException e){
//记录日志
// 发送消息给运维
//发送邮件给开发人员
return new Result(e.getCode(),null,e.getMessage());
}
//系统异常
@ExceptionHandler(BusinessException.class)
public Result doBusinessException(BusinessException e){
return new Result(e.getCode(),null,e.getMessage());
}
//处理其他异常
@ExceptionHandler(Exception.class)
public Result doException(Exception e){
return new Result(Code.UNKNOW_ERR,"系统繁忙,请稍后重试!");
}
}
异常处理成功