项目_瑞吉外卖

项目经验

登录

  • 需要将用户注册的用户名和密码存入数据库
    • 可以使用DigestUtils.md5DigestAsHex(password.getBytes())对密码进行md5加密存储到数据库中
    • 当用户登录时对用户输入的密码进行md5加密和数据库中密码进行对比即可
  • 使用HttpServletRequest.getSession().setAttribute(String s, Object o)将用户的信息存入Session方便下次访问
    • 用户退出登录的时候通过HttpServletRequest.getSession().removeAttribute(String s)清除session
    • 这种设置会话属性的方式会在服务结束或重启后清楚,因为会话属性是存储在服务器内存中的

拦截器

  1. 在需要设置拦截器的服务的启动类上加@ServletComponentScan,以便能够扫描到@WebFilter
  2. 创建过滤器类,实现Filter接口,重写doFilter方法
  3. 在过滤器类上加上@WebFilter(filterName = "name", urlPatterns = "/*")
    • filterName是过滤器的名称
    • urlPatterns是需要拦截的路径
  4. 在类中创建AntPathMatcher对象,可以处理包含通配符的路径匹配(*和?等)
    • 其中包含match(String pattern, String path)方法,用于检查指定的路径是否与指定的模式匹配# BUG
  5. 在doFilter方法中创建HttpServletRequest request = (HttpServletRequest) servletRequest
  6. 使用request.getRequestURI()获取访问路径
  7. 判断是否需要处理后,使用filterChain.doFilter(request,response)进行放行或进行其他处理

全局异常

  1. 创建全局异常处理类
  2. 在该类上加上@ControllerAdvice(annotations = {RestController.class, Controller.class})
    • ControllerAdvice用于增强Controller
    • annotations用于指明需要增强的Controller
    • 使用了该注解的类中可以使用@ExceptionHandler、@InitBinder、@ModelAttribute增强Controller
  3. 自定义异常处理方法,并在方法上加上@ExceptionHandler(xxx.class)
    • 其中的xxx.class是异常类,指明异常类后将由该方法捕获这个异常类并进行处理

分页查询

使用Mybatis-Plus的分页插件实现分页查询

  1. 创建MybatisPlusConfig配置类,并在其中加上MybatisPlus的分页插件并用@Bean进行注解
@Configuration
public class MybatisPlusConfig {
    
    
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
    
    
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}
  1. 构造分页构造器和条件构造器,使用MybatisPlus自带的分页查询进行查询
		//构造分页构造器
        Page pageInfo = new Page(page,pageSize);
        //构造条件构造器
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        //添加查询条件
        queryWrapper.……;
        //执行查询
        employeeService.page(pageInfo,queryWrapper);

公共字段自动填充

对统一字段进行管理,避免重复代码

  1. 在需要自动填充的实体类中的公共字段上@TableField(fill = FieldFill.INSERT)@TableField(fill = FieldFill.INSERT_UPDATE)注解
    • @TableField(fill = FieldFill.INSERT)指在插入时自动填充
    • @TableField(fill = FieldFill.INSERT_UPDATE)指在插入和更新时自动填充
  2. 创建元数据对象处理器的类,并实现MetaObjectHandler接口
  3. 重写insertFill和updateFill方法,并在其中使用metaObject.setValue(String name, Object value)对需要自动填充的对象进行赋值

文件上传和下载

文件上传

  1. 使用MultipartFile类获取浏览器传来的文件对象
  2. 使用UUID.randomUUID()生成随机文件名
  3. 使用file.transferTo(new File(pathName))将文件转存到某路径

文件下载

  1. 使用FileInputStream fileInputStream = new FileInputStream(new File(pathName))从指定路径读取文件
  2. ServletOutputStream servletOutputStream = response.getOutputStream()创建输出流,用于将文件写回浏览器
  3. response.setContentType("image/jpeg")设置文件格式
  4. 将文件写回浏览器
		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)

猜你喜欢

转载自blog.csdn.net/qq_57689612/article/details/131205099