苍穹外卖Day03——解决总结3中存在的问题

解决Day03中存在的问题

  • 1. @ ResponseBody 与 @RequestBody
  • 2. @RequestParam 与 @PathVariable
  • 3. 字段填充技术(注解、AOP、反射)
    • 3.1. AOP
    • 3.2. 注解
    • 3.3. 反射
    • 3.5 字段填充在项目应用
  • 4. 阿里云云存储OOS

1. @ ResponseBody 与 @RequestBody

@ResponseBody,用于将后端的JAVABEAN对象对象转化为JSON格式的数据返回给前端。

  1. 标注在控制器的方法上,用于将方法的返回值以JSON/XML的格式返回给客户端。
  2. 如果没有该注解,将返回一个ModelAndView给客户端,即返回视图。
  3. Spring中的新增注解:@RestController,@RestController = @Controller + @ResponseBody,如果一个Controller类添加了@RestController注解,那么该Controller类中的所有方法都相当于添加了@ResponseBody 注解。
  4. 当控制器使用@RestController标注时,控制器中的所有方法无需再添加@ResponseBody 注解;当控制器使用@Controller标注时,控制器中的所有方法则需要添加@ResponseBody注解。

@RequestBody,用于将前端发送来的JSON/XML格式的数据转化为JAVABEAN对象;

作用:

  1. 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;

  2. 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

使用时机

  1. GET、POST方式提时, 根据request header Content-Type的值来判断:
  • application/x-www-form-urlencoded, 可选(即非必须,因为这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理);
  • multipart/form-data, 不能处理(即使用@RequestBody不能处理这种格式的数据);
  • 其他格式, 必须(其他格式包括application/json, application/xml等。这些格式的数据,必须使用@RequestBody来处理);
  1. PUT方式提交时, 根据request header Content-Type的值来判断:
  • application/x-www-form-urlencoded, 必须;
  • multipart/form-data, 不能处理;
  • 其他格式, 必须;

2. @RequestParam 与 @PathVariable

@RequestParam@PathVariable 注解是用于从request中接收请求的,两个都可以接收参数,关键点不同的是@RequestParam 是从request里面拿取值,@PathVariable 是从一个url模板里面来填充。

@RequestParam

// 请求方式1:http://127.0.0.1:8080/getUserId2?id=1  // id为1@PostMapping("getUserId2")
@ApiOperation(value = "获取Id2", notes = "通过用户ID获取")
public String findById2(@ApiParam(value = "用户ID", required = true) @RequestParam("id") Long id) {return "id为===》" + id;
}// 请求方式2:http://localhost:8080/springmvc/hello/101?param1=10&param2=20public String getDetails(@RequestParam(value="param1", required=true) String param1,@RequestParam(value="param2", required=false) String param2){
...
}

@RequestParam 支持下面四种参数:

  1. defaultValue 如果本次请求没有携带这个参数,或者参数为空,那么就会启用默认值

  2. name 绑定本次参数的名称,要跟URL上面的一样

  3. required 这个参数是不是必须的

  4. value 跟name一样的作用,是name属性的一个别名

@PathVariable

// 请求方式1:http:// 127.0.0.1:8080/getUserId/1  // id为1@PostMapping("getUserId/{id}")
@ApiOperation(value = "获取Id", notes = "通过用户ID获取")
public String findById(@ApiParam(value = "用户ID", required = true) @PathVariable("id") Long id) {return "id为===》" + id;
}// http://localhost:8080/springmvc/hello/101?param1=10&param2=20@RequestMapping("/hello/{id}")
public String getDetails(@PathVariable(value="id") String id, @RequestParam(value="param1", required=true) String param1,@RequestParam(value="param2", required=false) String param2){
.......
}

3. 字段填充技术(注解、AOP、反射)

3.1. AOP

查看个人博客详细介绍:

文章名称笔记链接简介
Spring:AOP的核心概念(1)https://lushimeng.blog.csdn.net/article/details/127962788主要讲解AOP的一些概念,主要内容包括:AOP简介、AOP入门案例以及AOP工作的流程
Spring:AOP切入点表达式(2)https://lushimeng.blog.csdn.net/article/details/127962794主要描述切入点表达式、语法格式、通配符和书写技巧
Spring:AOP的五种通知类型(3)https://lushimeng.blog.csdn.net/article/details/127962807主要介绍AOP的五中通知类型:前置通知@Before、后置通知@After、环绕通知@Around、返回后通知@AfterReturning和异常后通知@AfterThrowing。主要掌握前后置和环绕通知类型
Spring:AOP通知获取数据(4)https://lushimeng.blog.csdn.net/article/details/127962821主要介绍AOP通知获取数据,主要分为两大块:AOP通知获取参数(非环绕获取和环绕获取) 和 AOP通知获取返回值(环绕通知获取和返回后通知获取)
Spring:AOP事务管理(5)https://lushimeng.blog.csdn.net/article/details/127962845主要讲的是Spring事务管理,主要包括Spring事务简介、Spring事务以及Spring事务属性

3.2. 注解

查看个人博客详细介绍:Java单元测试、反射、注解、动态代理

3.3. 反射

查看个人博客详细介绍:Java单元测试、反射、注解、动态代理

3.5 字段填充在项目应用

在这里插入图片描述

存在问题:代码冗余、不便于后期维护

解决思路:字段填充技术。对于插入数据和更新数据分别加上不同的注解帮助自动填充字段信息。

  • 自定义注解AutoFill,用于标识需要进行公共字段自动填充的方法
  • 自定义切面类AutoFillAspect, 统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值
  • 在Mapper的方法上加上AutoFillzhu注解

步骤一:自定义注解AutoFill

/*** 自定义注解,用于标识某个方法需要进行功能字段自动填充处理*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {// 数据库操作类型:insert, updateOperationType value();
}/*** 数据库操作类型*/
public enum OperationType {/*** 更新操作*/UPDATE,/*** 插入操作*/INSERT}

步骤二:自定义切面AutoFillAspect

/*** 自定义切面,实现公共字段自动填充处理逻辑*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {/*** 切入点*/@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")public void autoFillPointCut(){}/*** 前置通知,在通知总进行公共字段的赋值* @param joinPoint*/@Before("autoFillPointCut()")public void autoFill(JoinPoint joinPoint){log.info("开始进行公共字段自动填充....");}
}

完善autoFill方法

package com.sky.aspect;import com.sky.annotation.AutoFill;
import com.sky.constant.AutoFillConstant;
import com.sky.context.BaseContext;
import com.sky.enumeration.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDateTime;/*** 自定义切面,实现公共字段自动填充处理逻辑*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {/*** 切入点*/@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")public void autoFillPointCut(){}/*** 前置通知,在通知总进行公共字段的赋值* @param joinPoint*/@Before("autoFillPointCut()")public void autoFill(JoinPoint joinPoint){log.info("开始进行公共字段自动填充....");// 获取到当前被拦截的方法上的数据库操作类型MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 方法签名对象AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class); // 获取方法上的注解OperationType operationType = autoFill.value(); // 获取数据库操作类型// 获取当前被拦截方法的参数--实体对象Object[] args = joinPoint.getArgs();if(args == null || args.length == 0){return;}Object entity = args[0];  // 获取参数实体对象,然后通过反射设置参数// 准备赋值数据LocalDateTime now = LocalDateTime.now();Long currentId = BaseContext.getCurrentId();// 根据当前不同的操作类型,为对应的属性通过反射来赋值if(operationType == OperationType.INSERT){try {Method setCreateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setCreateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);// 通过反射为对象属性赋值setCreateTime.invoke(entity, now);setUpdateTime.invoke(entity, now);setCreateUser.invoke(entity, currentId);setUpdateUser.invoke(entity, currentId);} catch (Exception e) {e.printStackTrace();}} else {try {Method setUpdateTime = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);Method setUpdateUser = entity.getClass().getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);// 通过反射为对象属性赋值setUpdateTime.invoke(entity, now);setUpdateUser.invoke(entity, currentId);} catch (Exception e) {e.printStackTrace();}}}}

步骤三:在Mapper接口的方法上加入AutoFill注解并把业务层为公共字段赋值的代码注释掉

在这里插入图片描述

在这里插入图片描述

4. 阿里云云存储OOS

参考黑马2023年JavaWeb教程:黑马程序员JavaWeb开发教程 p148 文件上传-阿里云OOS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/709888.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试经典150题——矩阵置零

​"Dream it. Wish it. Do it." - Unknown 1. 题目描述 2. 题目分析与解析 2.1 思路一——暴力求解 思路一很简单,就是尝试遍历矩阵的所有元素,如果发现值等于0,就把当前行与当前列的值分别置为0。同时我们需要注意,…

【Java】基本数据类型、包装类与字符串间的转换 例题

写在前面: 关于这道题,初见感觉有点cpu烧坏了,准确来说是看了网上的一些讲解都感觉不尽人意。自己整理了一下,希望能帮助到大家。 题目: 如下两个题目输出结果相同吗?各是什么。 Object o1 true ? new…

java演唱会网上订票购票系统springboot+vue

随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的交换和信息流通显得特别重要。因此,开发合适的基于springboot的演唱会购票系统的设计与实现成为企业必然要走…

基于uniapp开发小程序,代码上线发布教程【抖音、微信】

本系列文章适合三类同学:1.希望学习小程序开发;2.希望无代码、低代码拥有自己的小程序;3.快速搭建小程序交作业、交毕设的大学生 本系列文章将推出配套桌面端软件,配合软件,可实现傻瓜式开发小程序,请有需求…

@Slf4j 变量log找不到符号,可能是 Gradle 配置文件写得有问题

Slf4j 变量log找不到符号 鄙人在学习 Java 的 spring boot 项目时, 常常因为 maven 配置文件使用 xml 格式过于复杂, 所以更倾向于使用 gradle 作为构建工具. 然而, 在使用 gradle 作为构建工具时, 又需要引用 Lombok 依赖. 有时忘记在初始化项目时添加上 Lombok 依赖, 所以经…

C++ deque详解以及容器适配器

目录 1.容器适配器 2.deque的使用 2.1deque的介绍 2.2deque的缺陷 2.3deque作为stack和queue的可行性 2.4 deque类的使用 2.4.1deque的构造函数 2.4.2deque容量操作 2.4.3deque赋值,插入 1.容器适配器 适配器是一种设计模式(设计模式是一套被人…

idea创建一个简单的maven项目

个人学习笔记(整理不易,有帮助点个赞) 笔记目录:学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 添加-DarchetypeCataloginternal 运行参数 (ps:不填的话,maven 骨架生成速度缓慢) 其实我没…

Redis---持久化

Redis是内存数据库,是把数据存储在内存中的,但是内存中的数据不是持久的,如果想要做到持久,那么就需要让redis将数据存储到硬盘上。 Redis持久化有两种策略: RDB > Redis DataBase RDB机制采取的是定期备份AOF …

c# ABB 机械手上位机连接

c# 程式开发和调试步骤如下: ABB 机械手要开启PC Interface功能。ABB 机械手设定ip地址。设定测试笔记本和机械手同一网段,用网线直连机械手,也可以通过交换机连接机械手。确保笔记本能够ping通和telnet 机械手80端口都是OK的。以上都OK的话…

QT C++实践|超详细数据库的连接和增删改查操作|附源码

0:前言 🪧 什么情况需要数据库? 1 大规模的数据需要处理(比如上千上万的数据量)2 需要把数据信息存储起来,无论是本地还是服务上,而不是断电后数据信息就消失了。 如果不是上面的原因化,一般…

是谁家的小千金跑出来了?

古典的山树绣花设计 精致典雅,上身立体又轻盈 做了粉绿两色,很适合春天的氛围 春天是个适合外出游玩的季节 穿上这件出游真的超美,日常穿也可 超出片很吸睛!

Pytorch学习 day01(Jupyter安装

Jupyter 安装过程中遇到的问题: Anaconda的base环境会自动安装Jupyter,但是如果我们要在其他环境中安装Jupyter,就需要注意,该环境的python版本不能高于3.11,且用以下代码安装: conda install nb_conda_…

消息中间件之RocketMQ源码分析(二十三)

Broker的关机恢复机制 概述 Broker关机恢复是指恢复CommitLog、Consume Queue、Index File等数据文件。Broker关机分为正常调用命令关机和异常被迫进程终止关机两种情况。恢复过程的设计目标是使正常停止的进程实现零数据丢失,异常停止的进程实现最少量的数据丢失…

Groovy - 大数据共享搜索配置

数据共享搜索列中配置了搜索列,相应的数据共享接口中也需要支持根据配置的字段搜索,配置实体时,支持搜索的入参code必须是searchKeys,且接口应该是需要支持分页(入参必须是 current、pageSize)的。current …

Linux系统Docker部署Nexus Maven并实现远程访问本地管理界面

文章目录 1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus Nexus是一个仓库管理工具,用于管理和组织软件构建过程中的依赖项和构件。它与Maven密切相关,可…

SpringBoot多数据源配置(MySql、Oracle)

一、依赖 <!-- dynamic-datasource 多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId></dependency><!--oracle驱动--><dependency><groupI…

JavaScript高级程序设计

前言 《JavaScript高级程序设计》 第1章——什么是JavaScript DOM将整个页面抽象为一组分层节点。 BOM用于支持访问和操作浏览器的窗口。 第2章——HTML中的JavaScript 2.1 < script >元素 元素描述async立即开始下载脚本&#xff0c;但不能阻止其他页面动作&#…

linux查看服务器内核CUP版本相关命令

服务器参考 计算架构&#xff1a;x86-64产品系列&#xff1a;华为云耀云服务器操作系列&#xff1a;CentOS 7 执行uname -a查看服务器内核版本 Linux hecs-82210 3.10.0-1160.92.1.el7.x86_64 #1 SMP Tue Jun 20 11:48:01 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux执行hostn…

掌握结构化日志记录:全面指南

在当今复杂的软件生态系统中&#xff0c;应用程序日志非常宝贵。它们允许开发者窥视应用程序的内部&#xff0c;了解系统内部的真实情况。但是&#xff0c;传统的非结构化日志数据有很多不足之处。这些混乱的文本块无法提供完整的画面。要真正发挥日志的力量&#xff0c;我们需…

浅析扩散模型与图像生成【应用篇】(三)——RDDM

3. Residual Denoising Diffusion Models 该文提出一种残差去噪扩散模型&#xff08;RDDM&#xff09;可用去图像生成和图像修复&#xff08;如去除阴影、去雨、暗光提升等&#xff09;。该文最大的特点是提出一种双扩散模型&#xff0c;在扩散过程中不仅包含噪声 ϵ \epsilon …