初识SpringMVC,2024年最新真香系列

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注运维)
img

正文

如果我们传递了多个参数,其中有所需要的(参数名字相同),那它会自动匹配:

多个参数也是一样传递,而且我们通过上面,也发现了参数的顺序并不影响参数的传递。

总结说明:当有多个参数时,前后端进行参数匹配时,是以参数的名称进行匹配的,因此参数的位置 是不影响后端获取参数的结果

Ⅱ、传递对象🍓

当参数个数过多时,可以进行传递对象,将参数封装成一个类。

Person对象

package com.example.mvcdemo.controller;

import lombok.Data;
@Data
public class Person {
    private int id;
    private String name;
    private String password;
}

TextController

package com.example.mvcdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

/*@Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问])
@ResponseBody//告诉程序我返回的是一个数据而非页面*/
@RestController//@Controller+@ResponseBody
/*@RequestMapping("/text")//路由注册*/
public class TextController {

    /*@RequestMapping(value = "/hi",method= RequestMethod.POST)//路由注册*/
    /*@PostMapping("/hi")*/
    @GetMapping("/hi1")
    public String sayHi1(Person p){
        return "Hi "+p.getId()+" "+p.getName()+" "+p.getPassword();
    }
}

运行代码+传递参数:

注意事项🍒

在Spring Boot(Spring MVC)中传参一定要是包装类型,而非基础类型。

package com.example.mvcdemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

/*@Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问])
@ResponseBody//告诉程序我返回的是一个数据而非页面*/
@RestController//@Controller+@ResponseBody
/*@RequestMapping("/text")//路由注册*/
public class TextController {

    /*@RequestMapping(value = "/hi",method= RequestMethod.POST)//路由注册*/
    /*@PostMapping("/hi")*/
    @GetMapping("/num")
    public String sayHi2(int num){
        return "num="+num;
    }
}

我们先正常传递参数:

但是如果我们忘记传递或是没有传递(前后端工作人员沟通不及时时),则会报错,而且这是非常严重的。

这个时候就很莫名其妙,也找不到错误。

如果我们将int换成它的包装类时:

正常传递参数可以正常显示:

没有传递参数时它则会显示null,这就会很明显发现错误的来源。

所以注意:参数类型应该设置为包装类

Ⅲ、后端参数重命名(后端参数映射)🍓

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,比如前端传递了⼀个 time 给后端,而后端又是用 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现 这种情况,我们就可以使用 @RequestParam 来重命名前后端的参数值。

具体示例如下,后端实现代码:

@RequestMapping("/m4")
public Object method_4(@RequestParam("time") String createtime) {
        System.out.println("时间:" + createtime);
        return "Hi "+createtime;
    }

代码运行:

这就说明参数的重命名生效了。

还有需要注意的是使用了@RequestParam(),则这个参数是必须要传递的,我们可以看@RequestParam()源码:

没有传递参数时:

所以当这个重命名参数是非必传参数时,我们可以设置@RequestParam 中的required=false 来避免不传递时报错

@RequestMapping("/m4")
public Object method_4(@RequestParam(value = "time", required = false) String createtime) {
        System.out.println("时间:" + createtime);
        return "Hi "+createtime;
    }+ createtime);
Ⅳ、@RequestBody 接收JSON对象🍓

我们先来试试看接受对象的是否可以接收JSON对象:

@GetMapping("/hi1")
    public String sayHi1(@RequestBody Person p){
        return p.toString();
    }

使用Postman 传递JSON对象

传递的是 0 null null ,就发现传递不了。那我们传递JSON对象时应该任何传递?

使用@RequestBody 注解。

    @PostMapping("/hi1")
    public String sayHi1(@RequestBody Person p){
        return "Hi "+p.getId()+" "+p.getName()+" "+p.getPassword();
    }

不过当@RequestBody传递JSON格式对象时需要配合PostMapping一起使用,因为@RequestBody传递JSON格式对象时是Post类型传参。

Postman:

Ⅴ、获取URL中参数@PathVariable🍓

后端实现代码:

@PostMapping("/m6/{name}/{password}")
    public Object method_6(@PathVariable String name, @PathVariable String password) {
        return "name:" + name+" password:" + password;
    }

这样写就很简洁,SEO(Search Engine Optimization 是指搜索引擎优化)效果很好。

注意事项:@PostMapping(“/m6/{name}/{password}”) 中的 {password} 参数不能省略。

这是因为在Spring的路径映射中使用了占位符(即{})来表示可变的路径段。

/m6/{name}/{password}中的{name}{password}都是路径变量,它们需要被具体的值替代才能匹配相应的请求路径。

参数的位置和个数都必须保持一致。

Ⅵ、上传文件@RequestPart🍓
@RequestMapping("/m9")
    public String upFile(@RequestPart("myfile") MultipartFile file) throws IOException {
        // ⽂件保存地址
        String filePath = "C:\\Users\\lin\\Pictures\\JiangHai\\11.png";
        // 保存⽂件
        file.transferTo(new File(filePath));
        return filePath + " 上传成功.";
    }

文件夹什么都没有:

使用Postman进行上传文件:

随便选择一张图片(文件名为myFile)

上传成功:

我们也可以打开这张图片

但是我们发现我们把路径定死了,这在实际开发中是不可能的,那我们现在来写一个最终版的文件上传:

@RequestMapping("/upfile")
    public String myUpFile(@RequestPart("myupfile") MultipartFile file) throws IOException {
        //根目录
        String path ="C:\\Users\\lin\\Pictures\\JiangHai\\";
        //根目录+唯一文件名(进行随机取名)
        path+=UUID.randomUUID().toString();
        //根目录+唯一文件名+文件的后缀 ex: aaa.aaa.png
        path+=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            file.transferTo(new File(path));
            return path + " 上传成功";
    }

再随便上传一张图片

我们也可以上传一个.txt文件:

上传成功:

注意:字段myfile允许的最大大小为1048576字节(即上传的文件是有大小限制的)

Ⅶ、获取Cookie/Session/header🍓
获取 Request 和 Response 对象 🍒
//Spring MVC(Spring Web) 内置了HttpServletRequest 和 HttpServletResponse
    @RequestMapping("/getparam")
    public String param10(HttpServletRequest request) {
        return request.getParameter("name");
    }

通过获取Request对象获取参数:

获取Cookie🍒
@RequestMapping("/getck")
    public String getCookie( HttpServletRequest request) {
        // 获取所有 cookie 信息
        Cookie[] cookies = request.getCookies();
        for(Cookie item:cookies){
            log.error(item.getName()+" "+item.getValue());
            //log的使用需要添加@Slf4j注解
        }
        return "get cookie!";
    }

打开浏览器开发人员工具(F12) ,手动添加结果Cookie:

浏览器访问 localhost:8080/getck

控制台就会将我们的Cookie打印出来:

上面我们是获取全部Cookie,我们也可以去获取指定的Cookie:

@RequestMapping("/getck2")
    public String getCookie2(@CookieValue("zhangsan") String val) {
        return "Cookie Value: "+val;
    }

明明你在请求时没有加Cookie,为什么可以拿到呢?这是因为浏览器,浏览器自己实现了这个机制,浏览器会在你每一次访问网站时,将这个网站的所以Cookie传送给你的后端。

可以看下面:

为什么浏览器会去实现这个机制呢?

是因为HTTP协议是一种无状态协议,服务器无法知道用户之前的状态信息。

为了解决这个问题,Web应用使用了Cookie机制来跟踪和记录用户的状态。当用户首次访问一个网站时,服务器会在响应中设置一个或多个Cookie,并将它们发送到用户的浏览器。浏览器会将这些Cookie保存起来。

随后,当用户再次访问同一网站时,浏览器会将之前保存的Cookie附加到请求中,然后发送给服务器。这样,服务器可以通过读取Cookie中的信息来识别并恢复用户的状态,例如登录信息、用户偏好等。

因此,浏览器在每次访问网站时将所有与该网站相关的Cookie传送给后端,以便服务器能够根据这些Cookie识别用户并提供相应的服务。

需要注意的是,浏览器会根据Cookie的设置规则来决定是否发送Cookie,例如Cookie的过期时间、域名限制等。

简洁获取 Header—@RequestHeader🍒
@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
     return "userAgent:"+userAgent;
}

浏览器:

Session 存储和获取🍒

Session 存储和 Servlet 类似,是使⽤ HttpServletRequest 中获取的,如下代码所示

@RequestMapping("/setsess")
    public String setsess(HttpServletRequest request) {
        // 获取 HttpSession 对象,参数设置为 true 表示如果没有 session 对象就创建⼀个session
        HttpSession session = request.getSession(true);
        if(session!=null){
            session.setAttribute("username","username");
        }
        return "session 存储成功";
    }

读Session①

//读Session1
    @RequestMapping("/getsess")
    public String sess(HttpServletRequest request) {
        // 如果 session 不存在,不会⾃动创建
        HttpSession session = request.getSession(false);
        String username = "暂⽆";
        if(session!=null && session.getAttribute("username")!=null){
            username = (String) session.getAttribute("username");
            return (String)session.getAttribute("username");
        }
        return "暂无Session信息!";
    }

读Session②(更简洁的方式)

//读Session2
    @RequestMapping("/getsess2")
    public String sess2(@SessionAttribute(value = "username",required = false)
                        String username) {
        return "username:"+username;
    }

我们先去读Session,可以发现浏览器显示:暂无Session信息!

然后我们去存储Session:

再去读取Session就有了:

当然Session是默认存在内存中的,如果当我们程序重新启动时,就没了,这是因为内存中的数据不具有持久性,无法跨越程序重启的边界。

3、返回数据🍉

Ⅰ、返回静态页面🍓

创建前端页面 hello.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>hello,spring mvc</title>
    <script src="index.js"></script>
</head>
<body>
<h1>Hello,Spring MVC.</h1>
</body>
</html>

创建控制器 RespController:

package com.example.mvcdemo.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/resp")
public class RespController {
    @RequestMapping("/hi")
    public String sayHi(String name){
        return "/hello.html";
    }
}

Ⅱ、返回text/html🍓

如果我们加上@ResponseBody,则显示:

Ⅲ、返回 JSON 对象🍓
@ResponseBody
    @RequestMapping("/m8")
    public HashMap<String, String> method_8() {
        HashMap<String, String> map = new HashMap<>();
        map.put("Java", "Java Value");
        map.put("MySQL", "MySQL Value");
        map.put("Redis", "Redis Value");
        return map;
    }

当你使用字典(键值对)类型时,Spring MVC会自动将其转换成JSON对象

Ⅳ、请求转发或请求重定向🍓

forward VS redirect

return 不但可以返回⼀个视图,还可以实现跳转,跳转的方式有两种:

  • forward :请求转发;
  • redirect:请求重定向。

请求转发和重定向的使用对比:

// 请求重定向
@RequestMapping("/hello")
public String hello(){
     return "redirect:/hello.html";
}
// 请求转发
@RequestMapping("/hello2")
public String hello2(){
     return "forward:/hello.html";
}

forward(请求转发)和 redirect(请求重定向)的区别,举例来说,例如,你告诉你妈妈,你想吃辣条,如果你妈妈,说好,我帮你去买,这就是 forward 请求转发;如果你妈妈让你自己去买,那么就是请求 redirect 重定向。

“转发”和“重定向”理解:在中国官⽅发布的内容越少事也越大, “转发”和“重定向”也是⼀样:字越少,责任越大 。转发是服务器帮转的,而重定向是让浏览器重新请求另⼀个地址。

forward 和 redirect 具体区别如下:

  1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
  2. 请求重定向地址发⽣变化,请求转发地址不发⽣变化。
  3. 请求重定向与直接访问新地址效果⼀直,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ello2")
public String hello2(){
return “forward:/hello.html”;
}



> 
> forward(请求转发)和 redirect(请求重定向)的区别,举例来说,例如,你告诉你妈妈,你想吃辣条,如果你妈妈,说好,我帮你去买,这就是 forward 请求转发;如果你妈妈让你自己去买,那么就是请求 redirect 重定向。
> 
> 
> 




> 
> 
> “转发”和“重定向”理解:在中国官⽅发布的内容越少事也越大, “转发”和“重定向”也是⼀样:字越少,责任越大 。转发是服务器帮转的,而重定向是让浏览器重新请求另⼀个地址。
> 
> 




forward 和 redirect 具体区别如下: 

1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
2. 请求重定向地址发⽣变化,请求转发地址不发⽣变化。
3. 请求重定向与直接访问新地址效果⼀直,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问。





**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)**
[外链图片转存中...(img-0g4qghnH-1713225246873)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值