【Java_EE】Spring MVC

目录

[Spring Web MVC](#Spring Web MVC)

​编辑注解

@RestController

@RequestMapping

@RequestParam

@RequestParam

@RequestBody

@PathVariable

@RequestPart

参数传递

注意事项

​编辑参数重命名

@RequestParam

​编辑​编辑传递集合

@RequestParam

传递JSON数据

​编辑@RequestBody

​编辑获取URL中的参数

@PathVariable

​编辑上传文件

@RequestPart

Cookie和Session

Cookie和Session的区别

Cookie和Session的关系

设置session(2种方式)

获取cookie(2种方式)

获取session(3种方式)

获取header(2种方式)

返回响应

响应静态页面

响应html代码片段

响应JSON对象

设置Connect-Type

小结练习:

登录练习和留言练习

API的实现

进行前后端交互


Spring Web MVC

Spring Web MVC:是基于Servlet API构建的原始web框架,实现了mvc设计模式的思想,通常被称为spring mvc

Servlet:是一套Java Web开发的规范(技术标准),是一种实现动态页面的技术

MVC的定义:Model Controller View

注解

@RestController

这是一个类注解,加了这个注解,spring才会对该类进行扫描。@RestController = @Controller(返回视图) + @ResponseBody(返回数据),所以最后返回的就是数据

@RequestMapping

URL路由映射,是用来注册接口的路由映射的

访问路径=类路径+方法路径,路径不能重复

可以修饰类,也可以修饰方法

支持GET请求,也支持POST请求

@RequestParam

@RequestParam进行参数重命名时,参数就变成了必传参数(required默认为true),将required改为false就为非必传了(方法参数)

@RequestParam

传递集合参数和传递数组类似,只是集合需要使用@RequestParam绑定参数关系。默认情况下,请求中参数名相同的多个值,封装到数组;要封装到集合,则需要使用@RequestParam绑定参数关系(集合)

@RequestBody

@RequestBody 作用在请求正文的数据绑定,请求参数必须秀在请求正文中(json)

@PathVariable

@PathVariable 路径变量,作用在请求URL路径上的数据绑定,默认传递参数写在URL上,SpringMVC就可以获取到(url)

@RequestPart

@RequestPart 可用于文件重命名(文件)

参数传递

接收参数。对于包装类型,如果不传对应参数,Spring接收到的数据则是null;对于基本类型,如果不传对应参数,会报500错误

注意事项

使用基本类型接收参数时,参数必须传(除了boolean类型),否则会报500错误,类型不匹配时会报400错误

参数重命名

@RequestParam

@RequestParam进行参数重命名时,参数就变成了必传参数(required默认为true),将required改为false就为非必传了

传递集合

@RequestParam

传递集合参数和传递数组类似,只是集合需要使用@RequestParam绑定参数关系。默认情况下,请求中参数名相同的多个值,封装到数组;要封装到集合,则需要使用@RequestParam绑定参数关系

传递JSON数据

JSON:是一种轻量级的数据交互格式,JSON本质是字符串,主要负责在不同的语言中数据传递和交换

JSON字符串和Java对象互转:可以通过jackson、fastjson1、fastjson2、gson...在Spring MVC框架中集成了JSON转换工具jackson

jackson工具:使用ObjectMapper对象提供的两个方法,JSON和Java对象可以互转

writeValueAsString():把对象转为JSON字符串

readValue():把JSON字符串转为对象(需要有无参构造方法)

@RequestBody

@RequestBody 作用在请求正文的数据绑定,请求参数必须在请求正文中

获取URL中的参数

@PathVariable

@PathVariable 路径变量,作用在请求URL路径上的数据绑定,默认传递参数写在URL上,SpringMVC就可以获取到

上传文件

@RequestPart

@RequestPart 可用于文件重命名

Cookie和Session

Cookie和Session的区别

Cookie是保存在客户端的用户信息的一种机制,Session是保存在服务器端的用户信息一种机制,sessionId是两者之间的桥梁。

cookie是不安全的,可以伪造cookie;session是安全的。

session默认是保存在内存中,如果重启服务器session数据就会丢失。

Cookie和Session的关系

设置session(2种方式)

java 复制代码
// 设置Session
@RequestMapping("/setSession1")
    public String setSession1(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.setAttribute("name", "value1");
        session.setAttribute("age", 200);
        return "设置session成功 key1:value1 key2:200";
    }

// 设置Session
    @RequestMapping("/setSession2")
    public String setSession2(HttpServletRequest request, String value3, Integer value4) {
        HttpSession session = request.getSession();
        session.setAttribute("name", value3);
        session.setAttribute("age", value4);
        return "设置session成功! name:" + value3 + " age:" + value4;
    }

// 设置Session
    @RequestMapping("/setSession3")
    public String setSession3(HttpSession session, String name, Integer age) {
        session.setAttribute("name", name);
        session.setAttribute("age", age);
        return "设置session成功! name:" + name + " age:" + age;
    }

设置完一条Session就会自动生成一个Cookie

获取cookie(2种方式)

1:通过接口HttpServletRequest

2:通过注解@CookieValue

java 复制代码
@RequestMapping("/getCookie1")
    public String getCookie1(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if(cookies == null) {
            System.out.println("没有Cookie");
            return "没有Cookie";
        }
        for (Cookie cookie : cookies) {
            System.out.println("getCookie-》" + cookie.getName() + ":" + cookie.getValue());
        }
        return "获取Cookie成功";
    }
@RequestMapping("/getCookie2")
    public String getCookie2(@CookieValue("key3") String value) {
        return "获取Cookie成功! key:" + value;
    }

获取session(3种方式)

1:通过接口HttpServletRequest

2:通过接口HttpSession

3:通过注解SessionAttribute

此处获取需要进行对象转换,将Object对象转换成替他类型(String、Integer)

java 复制代码
// 获取Session
    @RequestMapping("/getSession1")
    public String getSession1(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String name = (String)session.getAttribute("name");
        Integer age = (Integer)session.getAttribute("age");
        return "获取session成功 key1:" + name + " key2:" + age;
    }

 // 获取Session
    @RequestMapping("/getSession2")
    public String getSession2(HttpSession session) {
        String name = (String)session.getAttribute("name");
        Integer age = (Integer)session.getAttribute("age");
        return "获取session成功 key1:" + name + " key2:" + age;
    }

// 获取Session
    @RequestMapping("/getSession3")
    public String getSession3(@SessionAttribute("name") String name, @SessionAttribute("age") Integer age) {
        return "获取session成功 key1:" + name + " key2:" + age;
    }

获取header(2种方式)

java 复制代码
// 获取header
    @RequestMapping("/getHeader1")
    public String getHeader1(HttpServletRequest request) {
        String connection = request.getHeader("Connection");
        return "获取header成功! header:" + connection;
    }

// 获取header
    @RequestMapping("/getHeader2")
    public String getHeader2(@RequestHeader("Connection") String connection) {
        return "获取header成功! header:" + connection;
    }

返回响应

响应静态页面

@RestController = @Controller(返回视图) + @ResponseBody(返回数据),所以最后返回的就是数据

@ResponseBody 作用在类上,该类上的所有方法返回都是数据;作用在方法上返回的都是数据

java 复制代码
@RequestMapping("/data")

    public String response() {

        return "index.html"; // 这是一个相对路径,就找不到这个页面

    }

@RequestMapping("/static_page_data")

    public String responseStaticPage() {

        return "/index.html"; 
        // 但是此处被是被为了字符串,原因是加了@RestController

        // @RestController = @Controller(返回视图) + @ResponseBody(返回数据),所以返回的是字符串,而不是视图,所以会找不到这个页面

        // 在类上使用@Controller注解,就会返回视图,就可以找到这个页面了

    }

响应html代码片段

java 复制代码
// 响应html代码片段
    @RequestMapping("/responseHtml")
    @ResponseBody
    // 不加@ResponseBody就找不到这个字符串
    // 因为@Controller返回的是视图
    // @RestController(返回数据) = @Controller(返回视图) + @ResponseBody(返回数据)
    public String responseHtml() {
        return "<h1>Hello World</h1>";
    }

响应JSON对象

java 复制代码
// 响应JSON对象
    @RequestMapping("/json")
    @ResponseBody
    public Person responseJSON() {
        Person person = new Person();
        person.setName("张三");
        person.setAge(20);
        person.setGender("男");
        return person;
    }

设置Connect-Type

复制代码
// 设置connect-type
    @ResponseBody
    @RequestMapping("/connect_type")
    public void setConnectType1(HttpServletResponse response) throws IOException {
        response.setContentType("text/plain"); // text/plain,返回的是纯文本
        response.getOutputStream().write("<h1>Hello World</h1>".getBytes(StandardCharsets.UTF_8));
    }

// 设置connect-type
    @ResponseBody
    @RequestMapping(value = "/setConnectType" , produces = "text/plain") 
    public String setConnectType2 (HttpServletResponse response) throws IOException {
        // response.getOutputStream().write("<h1>Hello World</h1>".getBytes(StandardCharsets.UTF_8));
        return "<h1>hello word</h1>";
    }

小结练习:

登录练习和留言练习

API的实现

java 复制代码
@RestController
@RequestMapping("/test")
public class TestController {

    @PostMapping("/login")
    public Boolean login(@RequestBody User user, HttpSession session) {
        System.out.println("参数到达后端:user " + user.toString());

        /**
         * 校验参数
         * TODO 校验密码是否正确
         */
        if(!StringUtils.hasLength(user.getUserName()) || !StringUtils.hasLength(user.getPassword())) {
            System.out.println("用户名或密码不规范");
            return false;
        }
        if("admin".equals(user.getUserName()) && "admin".equals(user.getPassword())) {

            // 存储用户
            session.setAttribute("userName", user.getUserName());
            session.setAttribute("password", user.getPassword());

            return true;
        }
        return false;
    }

    @GetMapping("/loginUser")
    public String loginUser(HttpServletRequest request) {
        System.out.println("登录用户的获取!");
        HttpSession session = request.getSession(false);
        // 判断Session是否有数据
        if(session != null) {
            String userName = (String)session.getAttribute("userName");
            return "登录用户:" + userName;
        }
        return  "没用用户登录";
    }

    List<Message> messages = new ArrayList<>();
    @PostMapping("publishMessage")
    public Boolean publishMessage(@RequestBody Message message) {
        System.out.println("留言参数到达后端 message:" + message);
        /**
         * 校验参数
         * 存储数据
         */
        if(!StringUtils.hasLength(message.getContent())
                || !StringUtils.hasLength(message.getReceiver())
                || !StringUtils.hasLength(message.getContent())) {
            System.out.println("请正确填写留言板!");
            return false;
        }
        messages.add(message); // 存储数据
        return true;
    }


    @GetMapping("/messageList")
    public List<Message> messageList() {
        System.out.println("所有留言展现!");
        return messages;
    }
}

进行前后端交互

html 复制代码
<body>
    <div class="container">
        <h1 style="color: #333;">留言板</h1>
        <p class="grey">输入后点击提交, 会将信息显示下方空白处</p>
        <div class="row">
            <span>谁:</span> <input type="text" name="" id="from">
        </div>
        <div class="row">
            <span>对谁:</span> <input type="text" name="" id="to">
        </div>
        <div class="row">
            <span>说什么:</span> <input type="text" name="" id="say">
        </div>
        <input type="button" value="提交" id="submit" onclick="submit()">
        <!-- <div>A 对 B 说: hello</div> -->
    </div>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>

        $.ajax({
            url:"/test/messageList",
            type:"get",
            success:function (messages) {
                // 遍历结果数组,将每个留言显示在页面上
                for(let message of messages) {
                    var msg = message.commenter + " 对 " + message.receiver + " 说: " + message.content;
                    var messageElement = $("<div>" + msg + "</div>");
                    $(".container").append(messageElement);
                }
            }
        });

        function submit() {
            // 获取数据
            var commenter = $('#from').val();
            var receiver = $('#to').val();
            var content = $('#say').val();

            // 调用后端接口
            $.ajax({
                url:"/test/publishMessage",
                type:"post",
                contentType:"application/json",
                data:JSON.stringify({
                    commenter:commenter,
                    receiver:receiver,
                    content:content
                }),
                success:function (result) {
                    if(result) {
                        // 在留言板上显示留言
                        var message = commenter + " 对 " + receiver + " 说: " + content;
                        var messageElement = $("<div>" + message + "</div>");
                        $(".container").append(messageElement);

                        // 清空输入框的值
                        $('#from').val("");
                        $('#to').val("");
                        $('#say').val("");
                    } else {
                        alert("留言失败!")
                    }
                }
            });
        }
    </script>
</body>
相关推荐
Tirson Yang4 分钟前
西安java面试总结1
java·面试
小猫咪怎么会有坏心思呢5 分钟前
华为OD机试-猴子爬山-dp(JAVA 2025A卷)
java·算法·华为od
保持学习ing8 分钟前
SpringBoot 前后台交互 -- CRUD
java·spring boot·后端·ssm·项目实战·页面放行
啾啾Fun1 小时前
Java反射操作百倍性能优化
java·性能优化·反射·缓存思想
20岁30年经验的码农1 小时前
若依微服务Openfeign接口调用超时问题
java·微服务·架构
曲莫终1 小时前
SpEl表达式之强大的集合选择(Collection Selection)和集合投影(Collection Projection)
java·spring boot·spring
ajassi20002 小时前
开源 java android app 开发(十二)封库.aar
android·java·linux·开源
q567315232 小时前
Java使用Selenium反爬虫优化方案
java·开发语言·分布式·爬虫·selenium
kaikaile19952 小时前
解密Spring Boot:深入理解条件装配与条件注解
java·spring boot·spring
广州山泉婚姻2 小时前
解锁高效开发:Spring Boot 3和MyBatis-Flex在智慧零工平台后端的应用实战
人工智能·spring boot·spring