初学者建议看这版《SSM初学者版》进阶版适合熟悉SSM框架开发流程的开发人员。
进阶版分为以下几个部分
- 统一返回对象Res(统一返回对象会增加代码的耦合性。spring有全局返回对象,耦合性低,但我个人不建议用,无法捕获404,可能是我菜)
- 分页查询PageHelper
- 全局异常捕获@ExceptionHandler()+自定义异常抛出(自定义异常抛出的好处就是防止程序继续往下执行,减少资源占用,提升程序的执行效率)
- 日志打印logback-spring.xml
- 参数校验框架validation
- apache的StringUtils工具类,String类型校验/判空
logback-spring.xml日志打印
[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%5level] %-60logger:%5line - %msg%n INFO ${log_dir}/log-%d{yyyy-MM-dd}.log ${maxHistory} true [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%5level] %-60logger:%5line - %msg%n
pom.xml引入PageHelper、Validation、commons-lang依赖
org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.4 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java runtime commons-lang commons-lang 2.5 org.springframework.boot spring-boot-starter-validation com.github.pagehelper pagehelper-spring-boot-starter 1.2.13
Res.java统一返回对象
public class Res{ private boolean success = true; private T data; public Res(){} public Res(T data){ this.data = data; } public Res(boolean success,T data){ this.success = success; this.data = data; } //省略get/set }
Err.java 继承RuntimeException才可以抛出自定义异常
public class Err extends RuntimeException {
private boolean success;
private String data;
public Err(){}
public Err(String data){
this.success = false;
this.data = data;
}
//省略get/set
}
GlobalExceptionHandler.java全局异常捕获+自定义异常处理
@RestControllerAdvice
public class GlobalExceptionHandler{
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
public static String getExceptionDetail(Exception ex) {
String ret = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PrintStream pout = new PrintStream(out);
ex.printStackTrace(pout);
ret = new String(out.toByteArray());
pout.close();
out.close();
} catch (Exception e) {
}
return ret;
}
@ExceptionHandler(value =Err.class)
public Res Err(Err e){
return new Res(false,e.getData());
}
@ExceptionHandler(value =NullPointerException.class)
public Res exceptionHandler(NullPointerException e){
log.error("空指针异常"+);
return new Res(false,"空指针异常");
}
@ExceptionHandler(value =Exception.class)
public Res exception(Exception e){
log.error("500异常:"+getExceptionDetail(e));
return new Res(false,"服务器异常");
}
@ExceptionHandler(BindException.class)
public Res bindException(BindException e) {
// 然后提取错误提示信息进行返回
log.error("参数校验异常:"+e.getBindingResult().getFieldError().getDefaultMessage());
return new Res(false,"参数校验异常:"+e.getBindingResult().getFieldError().getDefaultMessage());
}
@ExceptionHandler(MissingServletRequestParameterException.class)
public Res missingServletRequestParameterException(MissingServletRequestParameterException e) {
log.error("请求参数异常"+e);
return new Res(false,"缺少请求参数:"+e.getParameterName());
}
}
UserController.java
@RestController
@RequestMapping("user")
public class UserController {
@Resource
private UserService userService;
@PostMapping("hello")
public Res hello(User user){
if (user.getId()==null)throw new Err("自定义异常信息返回。");
return new Res(user);
}
@PostMapping("select")
public Res select(@RequestParam Long id) {
return new Res(userService.select(id));
}
@PostMapping("selectAll")
public Res selectAll() {
return new Res(userService.selectAll());
}
@PostMapping("selectPage")
public Res selectPage(@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) {
//2行代码解决分页
PageHelper.startPage(pageNum, pageSize);
return new Res(PageSerializable.of(userService.selectAll()));//PageSerializable.of的of里面存放的必须是List<>
}
@PostMapping("update")
public Res update(@RequestBody @Valid User user) {
//如果你的ID不是Long类型的是String类型的UUID或者其他,就用StringUtils.isBlank(user.getId())
//return new Res(StringUtils.isBlank(user.getId())?userService.insert(user) : userService.update(user));
return new Res(user.getId() == null ? userService.insert(user) : userService.update(user));
}
@PostMapping("delete")
public Res delete(@RequestParam Long id) {
return new Res(userService.delete(id));
}
}
UserService.java
@Service
public class UserService {
@Resource
private UserMapper userMapper;
//根据ID查询
public User select(Long id) {
return userMapper.select(id);
}
//查询全部
public List selectAll() {
return userMapper.selectAll();
}
//新增
public int insert(User user) {
return userMapper.insert(user);
}
//更新
public int update(User user) {
return userMapper.update(user);
}
//删除
public int delete(Long id) {
return userMapper.delete(id);
}
}
UserMapper.java
public interface UserMapper {
//根据ID查询
User select(Long id);
//查询全部
List selectAll();
//新增
int insert(User user);
//更新
int update(User user);
//删除
int delete(Long id);
}
UserMapping.xml
id, name, remark
User.java对象使用@NotBlank注解配合Controller层的@Valid注解使用
import javax.validation.constraints.NotBlank;
import java.util.Date;
public class User {
private Long id;
@NotBlank(message = "姓名不能为空")
private String name;
private String remark;
//省略get/set
}
测试:
日志就不说了,运行启动类自动生成logs文件夹,文件夹里面就是成勋运行时的日志信息。
自定义异常抛出测试:
参数校验异常:我UserController.java的update请求加了@Valid,然后User.java对象里面设置了姓名不能为空判断。如果User对象里面的name为null或者""或者trim()之后为false就抛异常。
分页查询+Res.java统一泛型返回对象(前面的其实也是Res统一返回对象的内容)



