SpringMVC(2)

news2024/11/27 15:56:32

一)接受到JSON格式的数据:使用@RequestBody来进行接收

@ResponseBody表示的是返回一个非页面的数据

@RequestBody表示的是后端要接受JSON格式的数据

一)接收单个格式的JSON格式的数据,我们使用一个对象来进行接收

1)我们之前接受GET请求中的queryString中的参数的时候,我们是使用在参数中创建一个对象来进行接收的,但是如果我们要接受一个JSON格式的对象,我们需要在对象前面加上@RequestBody注解,标识为要接受JSON格式的数据;

2)加上@RequestBody后表示要读取一个JSON数据,加到对象前面就行了;

3)我们前后端的一个交互过程相当于是:我们先通过一个URL来进行访问html界面,当html界面进行加载的时候,就会给服务器发送一个二次请求,发送一个格式为json格式数据的post请求,然后服务器会进行返回一个json格式的数据;

4)虽然我们现在已经把JSON格式的字符串发送给后端了,但是如果我们使用对象来进行接受的时候不加上@RequestBody注解,那么最后的对象什么也不会接受到,都是默认值;

2)前端传来的是一个Json对象时:@HashMap,键值对的方式来进行接收

用POSTMMAN接受JSON格式的数据,点击body,点击raw,点击Text,再点击JSON,就可以构建JSON格式的字符串发送;

3)当前端传来这样一个Json数组:用List<实体类>,@RequestBody

下面我们来进行演示一下:前端传递一大堆JSON对象,后端如何进行接受一个JSON数组

@Controller
@ResponseBody
@RequestMapping("/Java100")
public class UserController {
    @RequestMapping("/hello")
    public List<User> start(@RequestBody List<User> list){
           return list;
    }
}

二)接收表单提交的数据以及获取特殊url的参数:

1)获取表单提交格式:

2)获取到特殊URL地址中的参数:@PathVariable是从地址部分获取参数而不是从URL地址中的参数部分来进行获取参数 

 

我们先创建一个User类:
@ToString
@Setter
@Getter
public class User {
    public String username;
    public String password;
    public int ClassID;
    public int UserID;
}
我们进行访问的地址:http://127.0.0.1:8080/host/李佳伟/12503487
@RequestMapping("/host/{username}/{password}")
 @ResponseBody
    public Object Start(@PathVariable String username,@PathVariable String password)
 {
     User user=new User();
     user.setUsername(username);
     user.setPassword(password);
     return user;//返回的是一个JSON格式的数据
 }

 

三)上传文件

 

3.1)上传文件:我们想把文件传递给电脑上面,用的方法是transferTo,里面一共有两个参数,一个是File,一个是Path

3.2)@MultipartFile是专门用来接收文件的一个注解,在@RequestPart注解里面,这个Key值可以任意设置,里面填写的相当于是input标签里面的name属性,transferTo方法的主要作用是把当前文件的二进制流,放到一个目录底下

@RequestMapping("/file")
@ResponseBody
    public String upload(@RequestPart("myfile")MultipartFile file) throws IOException {
//保存文件
     file.transferTo(new File(""d:/loggs/test.jpg""));//里面要创建一个新的文件对象
     return "上传成功";
 }

当我们想要上传头像的时候通常要加两个参数,一个是上传图片文件,另一个是这个图片是谁传递过来的,相当于是图片的唯一身份标识,不要去传递name属性,因为name属性有可能重复

1)我们直接可以进行点击Body中的form-data,Key值选择myfile,右键选择file就可以进行上传文件了

2)我们过来的文件一个是给开发环境用的,一个是给生产环境用的

3)我们这里面的@RequestMapping里面的参数表示路由地址,表示的是url中的地址,但是@RequestPart里面的参数表示的是form-data中的Key值

4)假设你想要修改头像,你要修改哪一个人的头像,你要注意此时不可以传名字属性,你要传入唯一的属性叫做ID,我们要根据ID来进行查找到数据库中的唯一的语句,然后进行头像修改

5)这里面要存放路径+文件名称

1)但是从目前的情况来看,当前写的上传图片的代码是有问题的;

2)上传图片的路径是写死的,图片内容是写死的,况且后上传的图片会把前面的人上传的图片给覆盖掉;

3)这里面传输图片的时候,key相当于是form表单中的name属性,idea天生支持yml的配置文件里面

那么我们如何来解决这个问题呢?主要就是从两个角度来出发:

1)文件目录怎么办?

在程序里面写死,本地上运行是没有问题的,但是最终项目我们要是在linux服务器上面是有问题的,linux没有C盘D盘,就是我可以针对不同的环境写不同的配置文件,上线的时候只需要改一个参数即可

 

2)图片名称,每一个人的图片名称不能重复

3)获取原上传图片的格式,不能写死.png,万一是一个gnf,导致图片上传而导致文件格式发生变化

1)目录:设置到配置文件里面,一个设置开发环境的路径,有C盘D盘,一个是线上环境的路径,设置为linux的路径,这样就可以在不同的环境写不同的配置文件,上线的时候只需要改参数就可以了,甚至说有的公司还有开发平台,生产平台,测试平台,每一个平台都对应着一个不同的路径;

假设你要将100个图片放在100个不同的路径底下,我们只需要进行修改配置文件里面就可以了,这样就就可以保证我们每进行修改一次配置文件,就换了一个不同的存放目录,还要有主配置文件

2)图片名称,一种是使用时间戳,一种是使用UUID,一种是用用户的唯一身份标识自增主键

3)获取到原图片上传的格式:先获取到文件的具体名字,在进行字符串截取文件格式是文件名的一部分

因为在不同环境下面我们可以设置不同打印日志信息,在开发环境我们可以日志级别是设置trace,因为在开发环境争取看到更多的配置信息,在生产环境我们就可以设置日志级别是warn,这样就可以使在生产环境下看到主要的报错信息

application.properties里面的代码设置配置文件的活跃性:spring.profiles.active=dev1
//开发环境就设置配置文件是dev1(windoes上面的路径),如果是生产环境就设置配置文件是dev2(linux环境上面的路径)
@Controller
public class UserController {
    @Value("${FilePath.url}")//读取配置文件里面的url
    private String url;

    @PostConstruct
    public void start()
    {
        System.out.print(url);
    }

    @RequestMapping("/file")
    @ResponseBody
    public String Upload(@RequestPart("myfile") MultipartFile file) throws IOException {
//1上传文件路径,从配置文件中读取,小心文件名重复而造成覆盖
        String BasePath=url;
//2生成动态的文件名,没传过来一个文件都要生成动态的文件名:xx.jpg
String filename= UUID.randomUUID()+(file.getOriginalFilename()
.substring(file.getOriginalFilename()
.lastIndexOf(".")));
        System.out.println(filename);
        file.transferTo(new File(BasePath+filename));
        return "上传成功";
    }
}

1)我们在创建不同平台的yml配置文件;

2)在主配置文件中设置运行的配置文件;

application-dev.yml

spring:
  profiles:
     active: dev1

application-dev1.yml里面的代码:

#表示生产环境的配置文件,里面进行存放的是本地Windows系统上面的图片保存路径(父亲路径)
img:
  ImageFatherPath: D:/Data/ #表示要存放图片的父亲目录

application-dev2.yml里面的代码:

#表示开发环境的配置文件,最终保存在linux服务器上面,我们在这里面是要进行指定图片的保存路径的(因为他们没有C盘D盘)
img:
   ImageFatherPath: /root/img
//因为我们返回的是字符串,所以我们不光要添加对应的路由映射
还要添加返回的格式是一个字符串而不是一个页面
@Controller
public class UserController {
    //从配置文件中读取我们上传的image图片保存的图片父亲路径
    @Value("${img.ImageFatherPath}")
    private String fatherPath;

    @RequestMapping("/Java100")
    @ResponseBody
    public String run(@RequestPart("myfile")MultipartFile file) throws IOException {
        //1.获取到原来要进行保存的文件的父亲路径:fatherPath
        //2.获取到文件的名称
        //3.获取到原文件上传的格式UUID是全球唯一ID
        String filename=file.getOriginalFilename();//xxx.png------得到原图片的名称
        filename=filename.substring(filename.lastIndexOf("."));
//subString表示表示从指定位置开始截取到最后一个位置
Substring(参数1,参数2); 截取字串的一部分,参数1为左起始位数,参数2为截取几位
//png---得到原图片的后缀
        filename=UUID.randomUUID().toString()+filename;
        file.transferTo(new File(fatherPath+filename));
        return "上传成功";
    }
}

4)获取到Cookie和Session和Header头

1)这些都是系统自己产生的,不是用户进行自定义的;

2)每一个方法都默认支持了两个隐藏参数,所有的SpringMVC里面,所有映射方法中,都会内置两个参数,HttpServletRequest和HttpServletResponse这两个参数;

3)通过上面的方式就可以进行设置Cookie了 

4.1)通过原生Servlet的方式来获取到Cookie

4.2)我们也是可以通过@CookieValue(名字),名字就是Key值实现了读取特定名称的Cookie

@Controller
public class User1Controller {
    @RequestMapping("/hello")
    @ResponseBody
    public String run(@CookieValue("username") String username,@CookieValue("password") String password){
//上面的这种@CookieValue的方式是根据Cookie种的Key来进行获取到value
        return username+password;
    }
}

 

通过上述在浏览器控制台上面我们也是可以进行添加Cookie的,随便加的;

4.3)使用这种SpringMVC的专用方法也是可以获取到Cookie字段的,通过@RequestHeader("Cookie")的方式来一次性读取到所有的Cookie

@Controller
class UserController{
    @RequestMapping("/Java")
    @ResponseBody
   public String GetHeader(@RequestHeader("Cookie") String Cookie)
    {
          return Cookie;
    }
}

@Slf4j//这个注解是一个类注解,而不是一个方法注解
@Controller
public class User1Controller {
    @RequestMapping("/hello")
    @ResponseBody
    public void run(@RequestHeader("Cookie")String cookies){
//这个注解必须用一个字符串来进行接收,况且@RequestHeader里面填写要获取到哪一个字段
        String[] strings=cookies.split(" ");
        for(String s:strings)
        {
            System.out.println(s);
        }
    }
}
//从上面结果也是可以看出,也是可以按照空格来进行分割的
username=abc;
password=cde

 

获取Header头:

@Controller
class UserController{
    @RequestMapping("/Java")
    @ResponseBody
   public String GetHeader(@RequestHeader("Host") String userAgent)
    {
          return userAgent;
    }
}

@Controller
public class UserController {
  @RequestMapping("/Java100")
    @ResponseBody
    public void run(HttpServletRequest req, HttpServletResponse resp) throws IOException {
      resp.setContentType("text/html;charset=utf-8");
      Cookie[] cookies=req.getCookies();
      String username=req.getParameter("username");
      String password=req.getParameter("password");
      String data=req.getHeader("Host");//使用Servlet的方式获取Header头
      String accept=req.getHeader("Accept");
      resp.getWriter().write("你好呀"+username+password+data+accept);
  }
}

@Controller
public class UserController {
  @RequestMapping("/Java100")
    @ResponseBody
    public String run(@RequestHeader("User-Agent") String UserAgent,@RequestHeader("Host") String host) throws IOException {
    return UserAgent+host;//host=127.0.0.1:8080

  }
}

设计登陆界面:-----存储Session,获取Session我们在POSTman是无法模拟Session的,因此Session非常安全

@Controller
class UserController{
  @RequestMapping("/Java100")
  @ResponseBody
    public String login(HttpServletRequest req, String username, String password, HttpServletResponse resp) throws IOException {
     if(password==null||password.equals("")||username==""||username.equals(""))
     {
          return "用户名或者密码错误";
     }
     if(!username.equals("李佳伟")||!password.equals("12503487"))
     {
         return "用户名错误或者密码错误";
     }
      HttpSession httpSession=req.getSession(true);
//自动根据SessionID去查找HttpSession
//没有回话就创建会话,r如果有回话就使用会话,没有回话就创建会话
      httpSession.setAttribute("username",username);
      resp.sendRedirect("/Java101");
     return "";
  }
  @RequestMapping("/Java101")
  @ResponseBody
  public String GetSession(HttpServletRequest req)
  {
      HttpSession session=req.getSession();
      if(session==null||session.equals(""))
      {
          return "当前用户没有进行登录";
      }
      String username=(String)session.getAttribute("username");
      if(username==null||username.equals(""))
      {
          return "当前用户没有进行登录";
      }
      return username+"当前用户已经登陆成功";
  }
}

下面写一种更加简单的获取Session的方法:(两种方法)

@RequestMapping("/Java101")
  @ResponseBody
  public String GetSession(@SessionAttribute(value="username",required = false) String username)
  {
//required=false,表示如果不进行添加的话那么当Session中不存在该属性的时候会发生报错
         return username;
  }

 小结:SpringMVC进行获取用户的请求信息:

Session:Map<String,Object>

String:SessionID,Object:HttpSession

0)以后的SessionID返回给客户端之后,下一次客户端再次访问浏览器的时候

Cookie:JSESESSIONID:一大堆字符串------>等价于是SessionID

1)获取到单个参数:我们在方法里面进行获取到对应的参数就可以实现(方法名的参数和前端的参数要一致)

2)获取对象:在方法里面直接写对象就可以进行实现,但是对象中的属性要和前端url或者表单的参数是一致的

3)获取到JSON对象:@RequestBody加到方法的参数的前面,表示服务器要进行读取JSON格式的数据

4)获取文件:@RequestPart,里面填写的是前端已经上传的key的属性+@MultipartFile+自定义名字

5)获取用户的Cookie/Session/Header:

@CookieValue(里面填写的是已知Cookie字段中的Key)+String XXX

/@SessionSttribute(value=里面填写的是HttpSession中的Key)+String xxx

1)会自动根据SessionID来进行获取到Session键值对中的HttpSession

2)还会自动根据里面填写的value中的值作为HttpSession中的Key

3)根据HttpSession中的Key来自动获取到Session字段并填充到咱们的String里面

4)如果说此时客户端请求的Http报文里面没有Session信息那么代码会直接报错,返回400直接报错

/@RequestHeader(里面填写的是HTTP请求报文中的原字段名)+String XXX

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

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

相关文章

读懂下文,安装数据库不再求人

想要数据存储必须要有数据库为支撑。在项目运行的时候也是要提前安装好并导入表结构和数据。通俗点来说&#xff0c;学会了万事不求人。 这里就整理了一份关于Windows和Linux系统下安装Mysql的操作命令。 Windows下安装MySQL 1、设置环境变量 设置环境变量是为了让你在任何…

小程序接口封装、异步加载、Promise

目录 1、页面准备 2、在app.js中处理当前环境以便切换api的环境、公共变量 3、定义post、get请求方法 request.js 4、api.js 接口列表调用index.js的post、get请求 5、index.js 需要返回数据的页面 api.js 、index.js 示例 异步实现 async、await 1、页面准备 目录结构…

JAVA 常用类型之String结构

String在java中我们是用来操作字符串的&#xff0c;但它的底层结构确是一个char[]数组&#xff0c;通过数组的方式将每个字符进行保存。 使用时&#xff1a;String str"ABCD"&#xff0c;内部存value确是&#xff1a;value[A,B,C,D]; 如下图&#xff1a; 参考String源…

七大排序算法的多语言代码实现

文章目录 前言 一、排序算法 1.原理简述 2.分类与复杂度 二、实例代码 1.冒泡排序 C Python Java Golang Rust Dephi 2.选择排序 C Python Java Golang Rust Dephi 3.插入排序 C Python Java Golang Rust Dephi 4.希尔排序 ​编辑 C Python Java Gola…

Linux网络技术学习(五)—— 网络设备初始化(I)

文章目录什么时候进行的设备初始化&#xff1f;设备注册和初始化NIC&#xff08;网卡 Network Interface Card&#xff09;初始化的基本目标设备与内核之间的交互硬件中断中断类型传送节流方式为了改善效率中断共享IRQ处理函数映射的组织irqaction结构体存储方式什么时候进行的…

android fwk模块之Sensor架构

本文基于Android 12源码整理&#xff0c;包含如下内容&#xff1a; 通信架构应用层实现使用方式SensorManager抽象接口具体实现fwk层的实现native中的SensorManager的初始化流程native中的消息队列初始化与数据读取sensorservice实现HAL层的实现通信架构 应用层实现 涉及代码&…

C#开发的OpenRA的只读字典IReadOnlyDictionary实现

C#开发的OpenRA的只读字典IReadOnlyDictionary实现 怎么样实现一个只读字典? 这是一个高级的实现方式,一般情况下,开发人员不会考虑这个问题的。 毕竟代码里,只要小心地使用,还是不会出问题的。 但是如果在一个大型的代码,或者要求比较严格的代码里,就需要考虑这个问题了…

51单片机——中断系统之外部中断实验,小白讲解,相互学习

中断介绍 中断是为使单片机具有对外部或内部随机发生的事件实时处理而设置的&#xff0c;中断功能的存在&#xff0c;很大程度上提高了单片机处理外部或内部事件的能力。它也是单片机最重要的功能之一&#xff0c;是我们学些单片机必须要掌握的。 为了更容易的理解中断概念&…

1.3配置P2P网络类型

1.3.1实验3:配置P2P网络类型 实验需求实现单区域OSPF的配置实现通过display命令查看OSPF的网络类型实验拓扑实验拓扑如图1-11所示 图1-11 配置P2P网络类型 实验步骤步骤1:[1] 配置IP地址 路由器R1

关于“档案大数据”的非主流看法

近日&#xff0c;反复拜读了前国家档案局局长杨冬权先生今年6.9档案日的大作《从“选时代”到“全时代”——智慧社会档案工作的历史性转折》&#xff0c;作为档案信息化从业者那真是倍感振奋&#xff0c;壮怀激烈&#xff01; 这篇文章绝对可以用气势磅礴、高屋建瓴这样的词语…

Oracle Data Guard 角色转换(Role Transitions)

查询视图V$DATABASE的DATABASE_ROLE列可以看到数据库当前的角色。 1&#xff0e;角色转换介绍 Oracle Data Guard让你可以使用SQL语句或者通过Oracle Data Guard broker界面来动态更改数据库的角色&#xff0c;Oracle Data Guard支持以下的角色转换&#xff1a; 1&#xff0…

C语言——指针、数组的经典笔试题目

文章目录前言1.一维数组2.字符数组3.二维数组4.经典指针试题前言 1、数组名通常表示首元素地址&#xff0c;sizeof(数组名)和&数组名两种情况下&#xff0c;数组名表示整个数组。 2、地址在内存中唯一标识一块空间&#xff0c;大小是4/8字节。32位平台4字节&#xff0c;64位…

hive数据存储格式

1、Hive存储数据的格式如下&#xff1a; 存储数据格式存储形式TEXTFILE行式存储SEQUENCEFILE行式存储ORC列式存储PARQUET列式存储 2、行式存储和列式存储 解释&#xff1a; 1、上图左面为逻辑表&#xff1b;右面第一个为行式存储&#xff0c;第二个温列式存储&#xff1b; …

【C语言】程序环境和预处理|预处理详解|定义宏(上)

主页&#xff1a;114514的代码大冒险 qq:2188956112&#xff08;欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ &#xff09; Gitee&#xff1a;庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 一、程序的翻译环境和执行环境 二、详解编译和链接 1.翻译环境 2.编…

TCP协议十大特性

日升时奋斗&#xff0c;日落时自省 目录 1、确认应答 1.1、序号编辑 2、超时重传 3、连接管理 3.1、三次握手 3.2、四次挥手 4、滑动窗口 5、流量控制 6、拥塞控制 7、延时应答 8、捎带应答 9、面向字节流 10、异常情况 TCP协议&#xff1a; 特点&#xff1a;有…

浅析EasyCVR安防视频能力在智慧小区建设场景中的应用及意义

一、行业需求 城市的发展创造了大量工作机会&#xff0c;人口的聚集也推动了居民住宅建设率的增长。人民生活旨在安居乐业&#xff0c;能否住得“踏实”是很多劳动工作者最关心的问题。但目前随着住宅小区规模的不断扩大、人口逐渐密集&#xff0c;在保证居住环境舒适整洁的同…

C++入门:初识类和对象

C入门&#xff1a;类和对象1 本节目录C入门&#xff1a;类和对象11.auto关键字&#xff08;C11)1.1类型别名思考1.2auto简介typeid运算符&#xff1a;获取类型信息1.3 auto的使用细则1.4auto不能推到的场景2.基于范围的for循环(C11)2.1范围for的语法2.2范围for的使用条件3.指针…

SpringCloud篇——什么是SpringCloud、有什么优缺点、学习顺序是什么

文章目录一、首先看官方解释二、Spring Cloud 的项目的位置三、Spring Cloud的子项目四、Spring Cloud 现状五、spring cloud 优缺点六、Spring Cloud 和 Dubbo 对比七、Spring Cloud 学习路线一、首先看官方解释 Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式…

【Azure 架构师学习笔记】-Azure Logic Apps(6)- Logic Apps调用ADF

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Logic Apps】系列。 接上文【Azure 架构师学习笔记】-Azure Logic Apps&#xff08;5&#xff09;- 标准和使用量类型的区别 前言 Logic Apps 和 ADF 的搭配使用是常见的组合&#xff0c;它们可以互相弥补各自的不足和…

opencv绘制椭圆

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…