文章目录
项目经验
登录
- 需要将用户注册的用户名和密码存入数据库
- 可以使用
DigestUtils.md5DigestAsHex(password.getBytes())
对密码进行md5加密存储到数据库中 - 当用户登录时对用户输入的密码进行md5加密和数据库中密码进行对比即可
- 可以使用
- 使用
HttpServletRequest.getSession().setAttribute(String s, Object o)
将用户的信息存入Session方便下次访问- 用户退出登录的时候通过
HttpServletRequest.getSession().removeAttribute(String s)
清除session - 这种设置会话属性的方式会在服务结束或重启后清楚,因为会话属性是存储在服务器内存中的
- 用户退出登录的时候通过
拦截器
- 在需要设置拦截器的服务的启动类上加
@ServletComponentScan
,以便能够扫描到@WebFilter - 创建过滤器类,实现Filter接口,重写doFilter方法
- 在过滤器类上加上
@WebFilter(filterName = "name", urlPatterns = "/*")
- filterName是过滤器的名称
- urlPatterns是需要拦截的路径
- 在类中创建AntPathMatcher对象,可以处理包含通配符的路径匹配(*和?等)
- 其中包含
match(String pattern, String path)
方法,用于检查指定的路径是否与指定的模式匹配# BUG
- 其中包含
- 在doFilter方法中创建
HttpServletRequest request = (HttpServletRequest) servletRequest
- 使用
request.getRequestURI()
获取访问路径 - 判断是否需要处理后,使用
filterChain.doFilter(request,response)
进行放行或进行其他处理
全局异常
- 创建全局异常处理类
- 在该类上加上
@ControllerAdvice(annotations = {RestController.class, Controller.class})
- ControllerAdvice用于增强Controller
- annotations用于指明需要增强的Controller
- 使用了该注解的类中可以使用@ExceptionHandler、@InitBinder、@ModelAttribute增强Controller
- 自定义异常处理方法,并在方法上加上
@ExceptionHandler(xxx.class)
- 其中的xxx.class是异常类,指明异常类后将由该方法捕获这个异常类并进行处理
分页查询
使用Mybatis-Plus的分页插件实现分页查询
- 创建MybatisPlusConfig配置类,并在其中加上MybatisPlus的分页插件并用@Bean进行注解
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
- 构造分页构造器和条件构造器,使用MybatisPlus自带的分页查询进行查询
//构造分页构造器
Page pageInfo = new Page(page,pageSize);
//构造条件构造器
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
//添加查询条件
queryWrapper.……;
//执行查询
employeeService.page(pageInfo,queryWrapper);
公共字段自动填充
对统一字段进行管理,避免重复代码
- 在需要自动填充的实体类中的公共字段上
@TableField(fill = FieldFill.INSERT)
或@TableField(fill = FieldFill.INSERT_UPDATE)
注解@TableField(fill = FieldFill.INSERT)
指在插入时自动填充@TableField(fill = FieldFill.INSERT_UPDATE)
指在插入和更新时自动填充
- 创建元数据对象处理器的类,并实现MetaObjectHandler接口
- 重写insertFill和updateFill方法,并在其中使用
metaObject.setValue(String name, Object value)
对需要自动填充的对象进行赋值
文件上传和下载
文件上传
- 使用
MultipartFile
类获取浏览器传来的文件对象 - 使用
UUID.randomUUID()
生成随机文件名 - 使用
file.transferTo(new File(pathName))
将文件转存到某路径
文件下载
- 使用
FileInputStream fileInputStream = new FileInputStream(new File(pathName))
从指定路径读取文件 ServletOutputStream servletOutputStream = response.getOutputStream()
创建输出流,用于将文件写回浏览器response.setContentType("image/jpeg")
设置文件格式- 将文件写回浏览器
int len = 0;
byte[] bytes = new byte[1024];
while((len = fileInputStream.read(bytes))!=-1){
servletOutputStream.write(bytes,0,len);
servletOutputStream.flush();
}
fileInputStream.close();
servletOutputStream.close();
多表插入
当涉及到多表插入时
- 需要引入DTO实体类
- 需要在serviceImpl上加上@Transactional开启事务
- 需要在服务的启动类上加上@EnableTransactionManagement开启事务管理
Bug
Error:InvalidDataAccessApiUsageException: Error attempting to get column ‘create_time’ from result set.
ERROR 17352 — [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Error attempting to get column ‘create_time’ from result set. Cause: java.sql.SQLFeatureNotSupportedException; null; nested exception is java.sql.SQLFeatureNotSupportedException] with root cause
错误解决办法参考CSDN博主「lz无痕」的原创文章
出现错误的原因:
因为表的createtime类型为DateTime,但是实体中属性的类型为LocalDateTime,并不匹配
这与mabatis-plus和数据库或druid的版本有关,我使用的mybatis-plus为3.4.0,druid为1.1.16
解决方法:
- 将LocalDateTime改为Date(此方法虽有效,但是会导致后期获取时间以及时间格式的序列化与反序列化困难)
- 将druid版本升级为1.2.16
AntPathMatcher.match()方法未能正确识别
错误原因:AntPathMatcher.match()的参数传递错误
解决办法:
- 第一个参数需要设置参数的匹配规则,即将可能存在通配符(/**)的放在第一个参数位置
- 第二个参数需要设置被匹配的URI,即requestURI
JS丢失精度导致数据错误
错误情况:后端将19位的userID传给前端后,前端接收到数据,后端再从前端获取数据时,能获取到19位ID,但是只有16位精确
错误原因:js对long型数据处理时丢失精度,只有16位准确、
解决方法:在服务端给页面响应json数据时,将long型数据统一转成String字符串
- 提供对象转换器JacksonObjectMapper
- 在WebMvcConfig中扩展Spring mvc的消息转换器
前后端路径不统一导致未能接收到数据
错误原因:前端的url中uri为/category?ids=123456,后端的controller中的参数为Long id,参数名不一致
解决方法:将后端的参数名改为ids
后端写好逻辑后返回json数据,前端却未能显示(传参问题)
错误原因:前端给后端传参并未以json的格式传参,而是直接传某数据,但是后端以@RequestBody想接收json数据,根据前端返回的数据查询对应的方法时,找不到能接收该参数的方法时,直接报400异常,导致后端接收不到对应参数,最后不能查询到对应数据库数据
解决方法:前端如果传json数据,就以@RequestBody方式接收;如果直接传参数就以直接形参的方式接收
使用Mybatis-Plus调用接口查询结果有问题
Mybatis-Plus使用QueryWrapper包装条件后,需要在接口service()中加入包装条件,即service(queryWrapper)