# table_reservation **Repository Path**: singleseason/table_reservation ## Basic Information - **Project Name**: table_reservation - **Description**: 订餐系统 - **Primary Language**: Java - **License**: AFL-3.0 - **Default Branch**: develop - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2020-05-06 - **Last Updated**: 2021-09-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # table_reservation 订餐系统java后台 用到的技术有:SpringBoot+mysql+linux+redis+token 新增技术dubbo(更新中) 管理员/商家登录登录模块:主要是用redis 存储 用户登录状态和token令牌 设置过期时间,每一次请求都要携带token才可以请求成功 难点: @RestController public class AdministratorController { private static final Logger log = LoggerFactory.getLogger(AdministratorController.class); @Autowired AdministratorService administratorService; @Resource private RedisTemplate redisTemplate; @PostMapping("/view/administratorLogin") @RecordLoggerAnnotation("AdministratorLogin") public Result AdministratorLogin(@RequestBody Administrator administrators){ System.out.println(administrators); Administrator administrator = administratorService.AdministratorLogin(administrators.getAdminName(),administrators.getPassword()); log.info(administrators.getAdminName()); Map map = new HashMap(); if(administrator!=null) { String token = UUID.randomUUID()+""; redisTemplate.opsForValue().set(token,administrator, Duration.ofMinutes(30L)); return new Result(token, "登录成功", 200); } return new Result(null, "登录失败", 100); } } 商品管理模块:基本的增删改查 难点:文件上传 controller: @RestController public class CommodityController { //图片存放根路径 @Value("${file.rootPath}") private String ROOT_PATH; //图片存放根目录下的子目录 @Value("${file.sonPath}") private String SON_PATH; @CrossOrigin @PostMapping("/view/upload") public Map upload(@RequestParam(name = "file", required = false) MultipartFile file, HttpServletRequest request) { Map map = new HashMap(); if (file == null) { map.put("code",100); map.put("message","请选择要上传的图片"); map.put("data",null); return map; } if (file.getSize() > 1024 * 1024 * 10) { map.put("code",100); map.put("message","文件大小不能大于10M"); map.put("data",null); return map; } //获取文件后缀 String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1, file.getOriginalFilename().length()); if (!"jpg,jpeg,gif,png".toUpperCase().contains(suffix.toUpperCase())) { map.put("code",100); map.put("message","选择jpg,jpeg,gif,png格式的图片"); map.put("data",null); return map; } String savePath = ROOT_PATH + SON_PATH; File savePathFile = new File(savePath); if (!savePathFile.exists()) { //若不存在该目录,则创建目录 savePathFile.mkdir(); } //通过UUID生成唯一文件名 String filename = UUID.randomUUID().toString().replaceAll("-","") + "." + suffix; String url = "http://192.168.44.41:8080/img/"+filename; try { //将文件保存指定目录 file.transferTo(new File(savePath + filename)); } catch (Exception e) { e.printStackTrace(); map.put("code",100); map.put("message","保存文件异常"); map.put("data",null); return map; } //返回文件名称 System.out.println("filename"+filename); System.out.println("request"+request); System.out.println("url"+url); map.put("code",200); map.put("message","图片上传成功"); map.put("data",filename); map.put("url",url); return map; } } yml: file: rootPath: D:/ sonPath: img/ 配置类: @Configuration public class MyInterceptorConfig extends WebMvcConfigurationSupport { //图片存放根路径 @Value("${file.rootPath}") private String ROOT_PATH; //图片存放根目录下的子目录 @Value("${file.sonPath}") private String SON_PATH; @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ String filePath = "file:" + ROOT_PATH + SON_PATH; //指向外部目录 registry.addResourceHandler("img//**").addResourceLocations(filePath); super.addResourceHandlers(registry); } } 分类模块/轮播图模块:与商品模块基本一样 商家登录/用户登录:与管理员模块基本一样 日志模块: 难点:切面类 @Aspect @Component public class RecordLoggerAcpect { private static final Logger log = LoggerFactory.getLogger(RecordLoggerAcpect.class); @Autowired private LoggerService loggerService; /** * @Description: 定义切入点 */ //被注解CustomAopAnnotation表示的方法 @Pointcut("@annotation(com.ordering.table_reservation.config.RecordLoggerAnnotation)") public void pointCut(){} /** * @Description: 定义前置通知 */ @Before("pointCut()") public void before(JoinPoint joinPoint) throws Throwable { // 接收到请求,记录请求内容 log.info("【注解:Before】------------------切面 before"); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 记录下请求内容 log.info("【注解:Before】浏览器输入的网址=URL : " + request.getRequestURL().toString()); log.info("【注解:Before】HTTP_METHOD : " + request.getMethod()); log.info("【注解:Before】IP : " + request.getRemoteAddr()); log.info("【注解:Before】执行的业务方法名=CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); log.info("【注解:Before】业务方法获得的参数=ARGS : " + Arrays.toString(joinPoint.getArgs())); com.ordering.table_reservation.entity.Logger logger = new com.ordering.table_reservation.entity.Logger(); logger.setAddress(request.getRequestURL().toString()); logger.setDescribes(request.getMethod()); logger.setHost(request.getRemoteAddr()); logger.setMethod(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); logger.setParams(Arrays.toString(joinPoint.getArgs())); logger.setCreateTime(DateUtils.getNow()); logger.setUpdateTime(DateUtils.getNow()); logger.setIsDel("100"); loggerService.insert(logger); } /** * @Description: 后置返回通知 */ @AfterReturning(returning = "ret", pointcut = "pointCut()") public void afterReturning(Object ret) throws Throwable { // 处理完请求,返回内容 log.info("【注解:AfterReturning】这个会在切面最后的最后打印,方法的返回值 : " + ret); } /** * @Description: 后置异常通知 */ @AfterThrowing("pointCut()") public void afterThrowing(JoinPoint jp){ log.info("【注解:AfterThrowing】方法异常时执行....."); } /** * @Description: 后置最终通知,final增强,不管是抛出异常或者正常退出都会执行 */ @After("pointCut()") public void after(JoinPoint jp){ log.info("【注解:After】方法最后执行....."); } /** * @Description: 环绕通知,环绕增强 * @return */ @Around("pointCut()") public Object around(ProceedingJoinPoint pjp) { log.info("【注解:Around . 环绕前】方法环绕start....."); try { //如果不执行这句,会不执行切面的Before方法及controller的业务方法 Object o = pjp.proceed(); log.info("【注解:Around. 环绕后】方法环绕proceed,结果是 :" + o); return o; } catch (Throwable e) { e.printStackTrace(); return null; } } }