初识SpringMVC(二)

简介: 初识SpringMVC

初识SpringMVC(一)https://developer.aliyun.com/article/1393172

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

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

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


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

代码运行:

image.png

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

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

image.png

没有传递参数时:

image.png

所以当这个重命名参数是非必传参数时,我们可以设置@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对象

image.png

传递的是 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:

image.png

Ⅴ、获取URL中参数@PathVariable🍓

后端实现代码:


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

image.png

这样写就很简洁,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 + " 上传成功.";
    }

文件夹什么都没有:

image.png

使用Postman进行上传文件:

image.png

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

image.png

上传成功:

image.png

我们也可以打开这张图片

image.png

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


@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 + " 上传成功";
    }

再随便上传一张图片

image.png

image.png

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

image.png

上传成功:

image.png

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

image.png

Ⅶ、获取Cookie/Session/header🍓

获取 Request 和 Response 对象 🍒


//Spring MVC(Spring Web) 内置了HttpServletRequest 和 HttpServletResponse
    @RequestMapping("/getparam")
    public String param10(HttpServletRequest request) {
        return request.getParameter("name");
    }

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

image.png

获取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:

image.png

浏览器访问 localhost:8080/getck

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

image.png

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


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

image.png

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

可以看下面:

image.png

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

是因为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;
}

浏览器:

image.png

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信息!

image.png

然后我们去存储Session:

image.png

再去读取Session就有了:

image.png

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

3、返回数据🍉

Ⅰ、返回静态页面🍓

创建前端页面 hello.html

image.png


<!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";
    }
}

image.png

Ⅱ、返回text/html🍓

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

image.png

Ⅲ、返回 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对象

image.png

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

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. 请求重定向与直接访问新地址效果⼀直,不存在原来的外部资源不能访问;请求转发服务器端转发有可能造成原外部资源不能访问。

请求转发如果资源和转发的页面不在⼀个目录下,会导致外部资源不可访问 。

相关文章
|
前端开发 Java 程序员
|
前端开发 Java 网络架构
|
XML 运维 前端开发
|
4月前
SpringMVC(一)(3)
SpringMVC(一)(3)
28 0
|
6月前
|
存储 JSON 前端开发
|
6月前
|
前端开发 Java API
|
前端开发 Java Maven
SpringMVC1
SpringMVC1
83 0
SpringMVC1
|
存储 前端开发 应用服务中间件
SpringMVC@RequestHeader
SpringMVC@RequestHeader
31 0