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

news2024/9/21 16:40:47

解决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=20

public 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, update
    OperationType 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.coloradmin.cn/o/1481323.html

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

相关文章

Docker容器与虚拟化技术:OpenEuler 使用 docker-compose 部署 LNMP

目录 一、实验 1.环境 2.OpenEuler 部署 docker-compose 3.docker-compose 部署 LNMP 二、问题 1.ntpdate未找到命令 2.timedatectl 如何设置时区与时间同步 3.php网页显示时区不对 一、实验 1.环境 (1)主机 表1 主机 系统架构版本IP备注Lin…

事物

概述: 数据库的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令。 事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么同时成功,要么同时失败。 事…

大模型量化技术原理-ZeroQuant系列

近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,从而导致模型变得越来越大,因此,我们需要一些大模型压缩技术来降低模型部署的成本,并提升模型的推理性能。 模型压缩主要分…

神经网络系列---卷积

文章目录 卷积神经网络卷积转置卷积 卷积核和反卷积的三种实现方式卷积的次数计算 卷积神经网络 在神经网络的卷积层中,向下取整(Floor)是一种常用的策略,特别是在处理输出尺寸不是整数的情况时。当你计算出卷积层输出的尺寸&…

回溯例题(leetcode17/37)

文章目录 leetcode37leetcode17 回溯跟枚举差不多。要注意“回溯”,别忘记“回”之前把之前的改动都复原。 leetcode37 leetcode37是解数独问题。本题保证有且仅有唯一解。 思路:先把空格子的位置存下来,然后对每一个空位置挨个枚举1-9。枚…

Vue2:用node+express部署Vue项目

一、编译项目 命令 npm run build执行命令后,我们会在项目文件夹中看到如下生成的文件 二、部署Vue项目 接上一篇,nodeexpress编写轻量级服务 1、在demo中创建static文件夹 2、将dist目录中的文件放入static中 3、修改server.js文件 关键配置&…

小红书关键词爬虫

标题 1 统计要收集的关键词,制作一个文件夹2 爬取每一页的内容3 爬取标题和内容4 如果内容可以被查看,爬取评论内容5 将结果进行汇总,并且每个帖子保存为一个json文件,具体内容6 总结 1 统计要收集的关键词,制作一个文…

【白嫖8k买的机构vip教程】Appium自动化(3):Appium-Desktop界面介绍

Appium-Desktop主界面包含三个菜单Simple、Advanced、Presets Simple界面: Host设置Appium server的ip地址,本地调试可以将ip地址修改为127.0.0.1;Port设置端口号,默认是4723不用修改Start Server 启动 Appium serverEdit Confi…

优思学院|质量工程师需要学习什么软件?

初入职质量工程师的朋友常常会问:质量工程师需要学习什么软件?在质量控制和管理的世界里,拥有强大的数据分析工具是走向成功的关键,因此,对于质量工程师来说,掌握正确的软件不仅能提升工作效率,…

多输入多输出 | Matlab实现RIME-BP霜冰算法优化BP神经网络多输入多输出预测

多输入多输出 | Matlab实现RIME-BP霜冰算法优化BP神经网络多输入多输出预测 目录 多输入多输出 | Matlab实现RIME-BP霜冰算法优化BP神经网络多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现RIME-BP霜冰算法优化BP神经网…

深度学习-神经网络原理

文章目录 神经网络原理1.单层神经网络1.1 回归单层神经网络:线性回归1.2 二分类单层神经网络:sigmoid与阶跃函数 1.3 多分类单层神经网络:softmax回归 神经网络原理 人工神经网络(Artificial Neural Network,ANN&…

Java ElasticSearch-Linux面试题

Java ElasticSearch-Linux面试题 前言1、守护线程的作用?2、链路追踪Skywalking用过吗?3、你对G1收集器了解吗?4、你们项目用的什么垃圾收集器?5、内存溢出和内存泄露的区别?6、什么是Spring Cloud Bus?7、…

【零基础SRC】成为漏洞赏金猎人的第一课:加入玲珑安全漏洞挖掘班。

我们是谁 你是否对漏洞挖掘充满好奇?零基础或有基础但想更进一步?想赚取可观的漏洞赏金让自己有更大的自由度? 那么,不妨了解下我们《玲珑安全团队》。 玲珑安全团队,拥有多名实力讲师,均就职于互联网头…

【比较mybatis、lazy、sqltoy、mybatis-flex操作数据】操作批量新增、分页查询(二)

orm框架使用性能比较 环境: idea jdk17 spring boot 3.0.7 mysql 8.0比较mybatis、lazy、sqltoy、mybatis-flex操作数据 测试条件常规对象 orm 框架是否支持xml是否支持 Lambda对比版本mybatis☑️☑️3.5.4sqltoy☑️☑️5.2.98lazy✖️☑️1.2.4-JDK17-SNAPS…

仿牛客网项目---帖子详情功能的实现

这篇文章主要讲讲帖子详情功能。其实帖子详情功能简单来说就是你点进去可以看到文章&#xff0c;这就叫帖子详情功能。那接下来我讲讲我的这个项目是如何实现这个功能的。 首先写DAO层。 Mapper public interface DiscussPostMapper {List<DiscussPost> selectDiscussPo…

【Unity】在Unity中导出WebGL并读取Excel数据的实现方法

在游戏开发中&#xff0c;数据的处理和导出是至关重要的环节之一。Unity作为一款强大的游戏开发引擎&#xff0c;提供了丰富的工具和功能来处理和导出数据&#xff0c;包括将游戏导出为WebGL应用&#xff0c;并读取外部数据文件&#xff0c;比如Excel表格。本文将介绍如何在Uni…

Navicat Premium 16:打破数据库界限,实现高效管理mac/win版

Navicat Premium 16是一款功能强大的数据库管理工具&#xff0c;旨在帮助用户更轻松地连接、管理和保护各种数据库。该软件支持多种数据库系统&#xff0c;如MySQL、Oracle、SQL Server、PostgreSQL等&#xff0c;并提供了直观的图形界面&#xff0c;使用户能够轻松地完成各种数…

计算机网络_2.2物理层下面的传输媒体

2.2物理层下面的传输媒体 一、传输媒体的分类二、导向型传输媒体1、同轴电缆2、双绞线3、光纤&#xff08;1&#xff09;光纤通信原理&#xff08;2&#xff09;光纤组成&#xff08;4&#xff09;多模光纤与单模光纤对比&#xff08;5&#xff09;光纤的波长与规格&#xff08…

WSL2部署RV1126 SDK编译环境

1 下载RV1126 SDK 在 Firefly | 让科技更简单&#xff0c;让生活更智能 下载REPO_SDK 这里将SDK下载到了F:\SDK 2 解压SDK到WSL2 tar -xvf /mnt/f/SDK/rv1126_rv1109_linux_release_20211022.tgz 3 编译依赖安装 gcc、g版本依赖安装 sudo apt-get install lib32gcc-7-dev g-7 l…

【center-loss 中心损失函数】 原理及程序解释(更新中)

文章目录 前言问题引出open-set问题抛出 解决方法softmax函数、softmax-loss函数解决代码&#xff08;center_loss.py&#xff09;原理程序解释 代码运用 如何梯度更新首先了解一下基本的梯度下降算法然后 补充&#xff1a;外围知识模型 前言 学习一下&#xff1a; 中心损失函…