Spring MVC(2)--- 介绍响应数据,具体案例和三层架构

(一).响应数据

对于响应的数据,Http响应结果可以是数据,也可以是静态页面,也可以针对响应设置状态码,Header信息

1.返回静态页面

关于静态页面存放的位置,我们通常存放在"resources"包底下的"static"包中

java 复制代码
@RestController
@RequestMapping("/response")
public class ResponseController {

    @RequestMapping("/r1")
    public String r1(){
        return "/html1.html";
    }
}

当我们访问的时候,发现,并没有返回页面

java 复制代码
package org.review.blog.springbootblog.controller;


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

@Controller
@RequestMapping("/response")
public class ResponseController {

    @RequestMapping("/r1")
    public String r1(){
        return "/html1.html";
    }
}

但是,当我们将@RestController修改成@Controller之后,发现就可以正常访问了。

这是因为,随着互联网的发展,目前项目开发流行"前后端分离"模式,Java主要用于后端开发,所以不再处理前端相关的内容了,所以MVC的概念也逐渐发生了变化,View不再返回视图,而是返回显示视图时需要的数据。所以@RestController 其实是用来返回数据的。@RestController=@Controller+@ResponseBody,@Controller:定义一个控制器,在Spring框架启动时加载,把这个对象交给Spring来进行管理;@ResponseBody:定义返回的数据格式为"非视图",返回一个text/html信息。

总的来说,@ResponseBody是用来返回数据的,而不是用来返回视图的,如果想要返回视图,只需要@Controller就行了。
总结:

如果一个类中既有返回页面的方法,又有返回数据的方法,则使用@Controller,在返回数据的方法上加上@ResponseBody

如果一个类全部返回数据,可以使用@RestController,或者是@Controller+@ResponseBody

如果一个类全部返回页面,则使用@Controller

java 复制代码
    @ResponseBody
    @RequestMapping("/r2")
    public String r2(){
        return "返回数据需要用@ResponseBody";
    }

2.返回前端片段(html类型)

java 复制代码
    @ResponseBody
    @RequestMapping("/r3")
    public String r3(){
        return "<h1>返回h1标题</h1>";
    }

可以看到,返回的页面,但是这个返回的页面是将<h1>当成了html标签来返回的

通过抓包工具可以看到,返回的格式为html类型

那么,如果我要返回的<h1>不是标签,而是文字,该如何解决?

事实上,我们直接修改返回的数据的格式类型即可

java 复制代码
    @ResponseBody
    @RequestMapping(value = "/r3",produces = "text/plain")
    public String r3(){
        return "<h1>返回h1标题</h1>";
    }

可以看到,我在@RequestMapping中加了一个produces属性,将返回的页面的格式由html类型转成了文本类型

通过抓包结果也可以看到

3.返回JSON

java 复制代码
    @ResponseBody
    @RequestMapping("/r4")
    public TestUserInfo r4(){
        TestUserInfo userInfo=new TestUserInfo();
        userInfo.setName("zhangsan");
        userInfo.setAge(21);
        userInfo.setGender(1);
        return userInfo;
    }

这里的@ResponseBody通过调用Jackson的消息转换器用ObjectMapper把java对象序列化成json字符串

重点:

@ResponBody 和 @RequestBody(上一章介绍到的)

@ResponBody为"响应体",负责把Java对象转为JSON,写入服务端发挥的响应体中

@RequstBody为"请求体",负责客户端发来的请求体中读JSON,转为Java对象

4.设置状态码

java 复制代码
    @ResponseBody
    @RequestMapping("/r5")
    public String r5(HttpServletResponse response){
        response.setStatus(404);  //通过setStatus()方法修改状态码
        return "设置成功";
    }

注意:我们手动设置的状态码的404,和真实的页面返回的404是不一样的,手动设置的状态码不会影响页面的展示

5.设置响应Header

java 复制代码
    @ResponseBody
    @RequestMapping("/r6")
    public String r6(HttpServletResponse response){
        response.setHeader("myheader","header");
        return "设置成功";
    }

关于HttpServletRequest和HttpServletResponse

用户希望从http请求中获得什么,都可以从httpServletRequest中获取;

用户希望给客户端返回什么,都可以通过HttpServletResponse来返回

(二).再谈@RequestMapping

java 复制代码
 @Target({ElementType.TYPE, ElementType.METHOD})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Mapping
 public @interface RequestMapping {
     String name() default "";

     @AliasFor("path")
     String[] value() default {};   // 指定映射的URL   可以和path相互替换,当使用Requstmapping时只传递这一个属性的时候,value可以省略

     @AliasFor("value")
     String[] path() default {};   //可以和value进行替换

     RequestMethod[] method() default {};   //指定请求的method类型,例如GET,POST等等
    
     String[] params() default {};    //指定request中必须包含某些参数值,即参数绑定或必传

     String[] headers() default {};   //指定request中必须包含某些指定的header值

     String[] consumes() default {};   //指定处理request的提交内容类型,例如appliacation/json

     String[] produces() default {};    //指定返回的内容类型,还可以同时设置返回值的字符编码
 }

上面是@RequestMapping的原码,注释里面包含了属性的介绍

(三).具体案例

这里,只提供了几个简单的案例。同时,对于前端代码不做解释,因为俺也不会前端,主要是后端,前端代码俺也是复制粘贴的,重点的前端会做出一定的解释。

1.计算器

前端代码

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
     <form action="calc/add" method="post">
        <h1>计算器</h1>
        数字1:<input name="num1" type="text"><br>
        数字2:<input name="num2" type="text"><br>
        <input type="submit" value=" 点击相加 ">
    </form>
</body>

</html>

后端代码

可以发现,我后端的代码是分层调用的,这样做的目的在下面介绍到"三层架构"的时候再给具体介绍

关于这个计算器的案例,后端代码没有什么可以介绍的,后端只需要接收两个值就可以了,然后判断一下是否合法,如果合法的话就进行计算,如果不合法的话,就直接返回"参数不合法"即可

2.留言板

这是效果图

前端代码

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>留言板</title>
    <style>
        .container {
            width: 350px;
            height: 300px;
            margin: 0 auto;
            /* border: 1px black solid; */
            text-align: center;
        }

        .grey {
            color: grey;
        }

        .container .row {
            width: 350px;
            height: 40px;

            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .container .row input {
            width: 260px;
            height: 30px;
        }

        #submit {
            width: 350px;
            height: 40px;
            background-color: orange;
            color: white;
            border: none;
            margin: 10px;
            border-radius: 5px;
            font-size: 20px;
        }
    </style>
</head>

<body>
    <div class="container">
        <h1>留言板</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="js/jquery.min.js"></script>
    <script>

        $.ajax({
            type: "get",
            url: "message/getList",
            success:function (messages){
                if (messages!=null && messages.length>0){
                    var finalHtml="";
                    for(var msg of messages){
                        finalHtml+="<div>"+msg.from +"对" + msg.to + "说:" + msg.message+"</div>"
                    }
                    $(".container").append(finalHtml)
                }
            }
        });
 
        function submit(){
            //1. 获取留言的内容
            var from = $('#from').val();
            var to = $('#to').val();
            var say = $('#say').val();
            if (from== '' || to == '' || say == '') {
                return;
            }

            var data={
                from:from,
                to:to,
                message:say
            };
            $.ajax({
                type:"post",
                url:"message/publish",
                contentType:"application/json",
                data:JSON.stringify(data),  //JSON.stringify() 将对象转为JSON         JSON.parse()  //将JSON转为对象
                success:function (result){
                    if (result.ok==1){   //由于后端返回的是JSON,所以前端可以直接从返回结果中取值
                        //成功
                        //2. 构造节点
                        var divE = "<div>"+from +"对" + to + "说:" + say+"</div>";
                        //3. 把节点添加到页面上
                        $(".container").append(divE);

                        //4. 清空输入框的值
                        $('#from').val("");
                        $('#to').val("");
                        $('#say').val("");
                    }else{
                        //失败
                        alert("留言发布失败")
                    }
                }
            });



        }
        
    </script>
</body>

</html>

在前后端交互的代码中,使用的ajax,大家可以自行了解

对于后端来说,要实现一个功能,就是当留言板的页面刷新的时候,之前留言的内容依旧在页面上

lombook介绍

在写后端代码之前,先给大家介绍一个依赖,这个依赖为"lombook"

"lombook"的作用主要是通过"注解"的方式,实现对类自动添加get(),set(),toString(),equals()等方法

添加lombook的方式有多种,第一种就是通过maven仓库,搜索lombook,然后选择对应的版本即可;另一种是在idea中下载一个插件,叫做"EditStarters"

这个插件的通就是可以直接导入Spring项目需要的依赖

通过上面的步骤,就将lambook依赖添加进来了

通过添加一个"@Data"注解,就可以不需要写get(),set()等方法了

上图是target文件中的MessageInfo类中的内容。

解释:target文件,即程序运行起来时,对应的.java文件

如果说,只想要让lombook生成get()和set()方法,不需要生成其他的方法,那么就可以将"@Data"注解,转换成"@Getter()"和"@Setter()"

如果只想给某个属性提供"get()"和"set()"方法,那么也可以单独给某个属性加这个注解

后端代码

可以看到,后端的代码也是是分层调用的

java 复制代码
package org.review.blog.springbootblog.controller;

import org.review.blog.springbootblog.model.MessageInfo;
import org.review.blog.springbootblog.service.MessageService;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/message")
public class MessageController {

    MessageService messageService=new MessageService();

    @RequestMapping(value = "/publish",produces = "application/json")
    public String publish(@RequestBody MessageInfo messageInfo){
        return messageService.publish(messageInfo);
    }

    @RequestMapping("/getList")
    public List<MessageInfo> getList(){
        return messageService.getList();
    }
}

这是,MessageController中的代码

java 复制代码
    @RequestMapping(value = "/publish",produces = "application/json")

上面这一行代码中的," produces="application/json" "的意思是,强制要求前端往后端传数据的时候,使用json格式进行传输,如果不适用json格式进行传输,则直接报错

java 复制代码
public String publish(@RequestBody MessageInfo messageInfo)

@RequstBody为"请求体",负责客户端发来的请求体中读JSON,转为Java对象

java 复制代码
package org.review.blog.springbootblog.dao;

import org.review.blog.springbootblog.model.MessageInfo;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

public class MessageDao {
    List<MessageInfo> list=new ArrayList<>();   //用于保存结果

    //发表留言,发表之后,使用list来统计发表的留言
    public String publish(MessageInfo messageInfo){
        if (!StringUtils.hasLength(messageInfo.getFrom())||
            !StringUtils.hasLength(messageInfo.getTo())||
            !StringUtils.hasLength(messageInfo.getMessage())){
            return "{\"ok\": 0}";
        }
        list.add(messageInfo);
        return "{\"ok\": 1}";
    }

    //获取全部留言
    public List<MessageInfo> getList(){
        return list;
    }
}

上图是MessageDao中的代码

这个StringUtils,可以理解为是"String" 的一个工具类,然后"hasLength()"方法

当点开原码的时候,发现hasLength()方法,主要是判断字符串是否为空的

关于retrun的返回值,也是为了响应后端要给前端返回JSON格式的数据而设计的

现在,即使我再刷新,之前的留言数据也不会消失

3.图书系统

(1).功能介绍

总体来说,我们只需要实现两个功能,一个是用户登录,一个是图书的列表展示

(2).前端代码

Ⅰ.登录页
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <link rel="stylesheet" href="css/login.css">
    <script type="text/javascript" src="js/jquery.min.js"></script>
</head>

<body>
    <div class="container-login">
        <div class="container-pic">
            <img src="pic/computer.png" width="350px">
        </div>
        <div class="login-dialog">
            <h3>登陆</h3>
            <div class="row">
                <span>用户名</span>
                <input type="text" name="userName" id="userName" class="form-control">
            </div>
            <div class="row">
                <span>密码</span>
                <input type="password" name="password" id="password" class="form-control">
            </div>
            <div class="row">
                <button type="button" class="btn btn-info btn-lg" onclick="login()">登录</button>
            </div>
        </div>
    </div>
    <script src="js/jquery.min.js"></script>
    <script>
        function login() {
            $.ajax({
                type:"post",
                url:"user/load",
                data:{
                    name:$("#userName").val(),
                    password:$("#password").val()
                },
                success:function (result){
                    if (result){
                        //账号密码正确
                        location.href="book_list.html"
                    }else{
                        alert("账号密码错误")
                    }
                }
            });
        }
    </script>
</body>

</html>
Ⅱ.图书列表页
html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图书列表展示</title>
    <link rel="stylesheet" href="css/bootstrap.min.css">

    <link rel="stylesheet" href="css/list.css">
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/bootstrap.min.js"></script>
    <script src="js/jq-paginator.js"></script>

</head>

<body>
    <div class="bookContainer">
        <h2>图书列表展示</h2>
        <div class="navbar-justify-between">
            <div>
                <button class="btn btn-outline-info" type="button" onclick="location.href='book_add.html'">添加图书</button>
                <button class="btn btn-outline-info" type="button" onclick="batchDelete()">批量删除</button>
            </div>
        </div>

        <table>
            <thead>
                <tr>
                    <td>选择</td>
                    <td class="width100">图书ID</td>
                    <td>书名</td>
                    <td>作者</td>
                    <td>数量</td>
                    <td>定价</td>
                    <td>出版社</td>
                    <td>状态</td>
                    <td class="width200">操作</td>
                </tr>
            </thead>
            <tbody>
<!--                <tr>-->
<!--                    <td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>-->
<!--                    <td>1</td>-->
<!--                    <td>大秦帝国第一册</td>-->
<!--                    <td>我是作者</td>-->
<!--                    <td>23</td>-->
<!--                    <td>33.00</td>-->
<!--                    <td>北京出版社</td>-->
<!--                    <td>可借阅</td>-->
<!--                    <td>-->
<!--                        <div class="op">-->
<!--                            <a href="book_update.html?bookId=1">修改</a>-->
<!--                            <a href="javascript:void(0)" onclick="deleteBook(1)">删除</a>-->
<!--                        </div>-->
<!--                    </td>-->
<!--                </tr>-->
<!--                <tr>-->
<!--                    <td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>-->
<!--                    <td>2</td>-->
<!--                    <td>大秦帝国第二册</td>-->
<!--                    <td>我是作者</td>-->
<!--                    <td>23</td>-->
<!--                    <td>33.00</td>-->
<!--                    <td>北京出版社</td>-->
<!--                    <td>可借阅</td>-->
<!--                    <td>-->
<!--                        <div class="op">-->
<!--                            <a href="book_update.html?bookId=2">修改</a>-->
<!--                            <a href="javascript:void(0)" onclick="deleteBook(2)">删除</a>-->
<!--                        </div>-->
<!--                    </td>-->
<!--                </tr>-->
<!--                <tr>-->
<!--                    <td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>-->
<!--                    <td>3</td>-->
<!--                    <td>大秦帝国第三册</td>-->
<!--                    <td>我是作者</td>-->
<!--                    <td>23</td>-->
<!--                    <td>33.00</td>-->
<!--                    <td>北京出版社</td>-->
<!--                    <td>可借阅</td>-->
<!--                    <td>-->
<!--                        <div class="op">-->
<!--                            <a href="book_update.html?bookId=3">修改</a>-->
<!--                            <a href="javascript:void(0)" onclick="deleteBook(3)">删除</a>-->
<!--                        </div>-->
<!--                    </td>-->
<!--                </tr>-->
<!--                <tr>-->
<!--                    <td><input type="checkbox" name="selectBook" value="1" id="selectBook" class="book-select"></td>-->
<!--                    <td>4</td>-->
<!--                    <td>大秦帝国第四册</td>-->
<!--                    <td>我是作者</td>-->
<!--                    <td>23</td>-->
<!--                    <td>33.00</td>-->
<!--                    <td>北京出版社</td>-->
<!--                    <td>可借阅</td>-->
<!--                    <td>-->
<!--                        <div class="op">-->
<!--                            <a href="book_update.html?bookId=4">修改</a>-->
<!--                            <a href="javascript:void(0)" onclick="deleteBook(4)">删除</a>-->
<!--                        </div>-->
<!--                    </td>-->
<!--                </tr>-->
            </tbody>
        </table>

        <div class="demo">
            <ul id="pageContainer" class="pagination justify-content-center"></ul>
        </div>
        <script>

            getBookList();
            function getBookList() {
                $.ajax({
                    type:"post",
                    url:"book/getList",
                    success:function (books){
                        var finalHtml=""
                        for(var book of books){
                            //进行字符串拼接
                            finalHtml+='<tr>'
                            finalHtml+='<td><input type="checkbox" name="selectBook" value="1"'+book.bookId+' id="selectBook" class="book-select"></td>'
                            finalHtml+='<td>'+book.bookId+'</td>'
                            finalHtml+='<td>'+book.bookName+'</td>'
                            finalHtml+='<td>'+book.author+'</td>'
                            finalHtml+='<td>'+book.num+'</td>'
                            finalHtml+='<td>'+book.price+'</td>'
                            finalHtml+='<td>'+book.publish+'</td>'
                            finalHtml+='<td>'+book.status+'</td>'
                            finalHtml+='<td><div class="op">'
                            finalHtml+='<a href="book_update.html?bookId='+book.bookId+'">修改</a>'
                            finalHtml+='<a href="javascript:void(0)" onclick="deleteBook('+book.bookId+')">删除</a>'
                            finalHtml+='</div></td></tr>'
                        }
                        $("tbody").append(finalHtml)
                    }
                });
            }
    
            //翻页信息
            $("#pageContainer").jqPaginator({
                totalCounts: 100, //总记录数
                pageSize: 10,    //每页的个数
                visiblePages: 5, //可视页数
                currentPage: 1,  //当前页码
                first: '<li class="page-item"><a class="page-link">首页</a></li>',
                prev: '<li class="page-item"><a class="page-link" href="javascript:void(0);">上一页<\/a><\/li>',
                next: '<li class="page-item"><a class="page-link" href="javascript:void(0);">下一页<\/a><\/li>',
                last: '<li class="page-item"><a class="page-link" href="javascript:void(0);">最后一页<\/a><\/li>',
                page: '<li class="page-item"><a class="page-link" href="javascript:void(0);">{{page}}<\/a><\/li>',
                //页面初始化和页码点击时都会执行
                onPageChange: function (page, type) {
                    console.log("第"+page+"页, 类型:"+type);
                }
            });
            function deleteBook(id) {
                var isDelete = confirm("确认删除?");
                if (isDelete) {
                    //删除图书
                    alert("删除成功");
                }
            }
            function batchDelete() {
                var isDelete = confirm("确认批量删除?");
                if (isDelete) {
                    //获取复选框的id
                    var ids = [];
                    $("input:checkbox[name='selectBook']:checked").each(function () {
                        ids.push($(this).val());
                    });
                    console.log(ids);
                    alert("批量删除成功");
                }
            }

        </script>
    </div>
</body>

</html>

(3).后端代码

Ⅰ.登录页
java 复制代码
package org.review.blog.springbootblog.service;

import jakarta.servlet.http.HttpSession;
import org.review.blog.springbootblog.dao.UserDao;

public class UserService {

    private UserDao userDao=new UserDao();

    public Boolean load(String name, String password, HttpSession session){
        Boolean load = userDao.load(name, password);
        if(load==true){
            //将用户名放到Session中
            session.setAttribute("name",name);  //创建一个会话
            return true;
        }else{
            return false;
        }
    }
}

这是UserService类中的代码

当从userDao.load()返回true之后,说明用户名和密码都正确了,此时站在服务器的角度,就需要创建一个会话,然后保存下用户的基本信息。

java 复制代码
package org.review.blog.springbootblog.dao;

import org.springframework.util.StringUtils;

public class UserDao {
    public Boolean load(String name,String password){
        if (!StringUtils.hasLength(name) ||
            !StringUtils.hasLength(password)){
            return false;
        }
        //校验用户名和密码是否正确
        if ("admin".equals(name) && "admin".equals(password)){
            return true;
        }
        return false;
    }
}

这是UserDao类中的代码。在进行用户名和密码的校验的时候,我是把"admin"写在了前面,即把常量字符串写在了前面。这是因为,对于equals()来说,是会发生"空指针异常"的,即"NullpointException",所以将常量字符串写在了前面

测试

密码正确

密码错误

Ⅱ.图书列表页

由于我们现在还没有介绍到数据库,所以在Dao层中创建的数据一些数据是一些假数据

测试

(四).应用分层

1.具体介绍

在前面写案例的时候,可以发现,我的代码都是按照层次分的

可以看到,都是有层次的。这就是应用分层。

应用分层主要是出自于"阿里巴巴开发手册"中。

应用分层是一种软件开发思想,将程序分成N个层次,这N个层次分别负责各自的职责,多个层次之间协同提供完整的功能。

咱们现在介绍的Spring MVC ,就是把整体的系统分成了 Model,View,Controller 三个层次,也就是将用户试图和业务处理隔离开,并且通过控制器连接起来,很好地实现了变现和逻辑的解耦,是一种标准的软件分层架构。

目前,更主流的方式是"前后端分离"的方式,后端不关心前端的实现。所以对于Java后端来说,又有了一种新的分层架构,把整体分为表示层,业务逻辑层,数据层 ,这种方式也称为"三层架构"

表示层对应的就是Controller层,主要负责和客户端进行交互,包括参数的接收,数据的返回

业务逻辑层对应的就是Service层,负责处理业务逻辑,里面有复杂业务的具体实现

数据层对应的就是Dao层,负责存储和管理数据

上图是访问的流程

上图是MVC和三层架构的层次对应关系。二者实现的共同目的就是"解耦","分层","代码复用"

2.高内聚 和 低耦合

高内聚:一个模块中各个元素之间的联系的紧密程度,如果各个元素之间的联系程度越高,则内聚性越高,则"高内聚"。

低耦合:软件中各个层、模块之间的依赖关联程序越低越好。修改一处代码,其他模块的代码改动越少越好。

下面,通过一个例子来介绍"高内聚"和"低耦合"

上图,是一个公司的部门分布。

此时,如果"财务人员1"家里有事,请假了,那么"财务人员2","财务人员3","财务人员4",这三个人都可以随时顶上,完成"财务人员1"的工作,此时就称为"高内聚"。

此时,即使今天"财务部门"的所有人员都请假了,那么也不会影响"行政部门"的人继续工作,此时就称"低耦合"。

可以发现,"高内聚"和"低耦合"并不矛盾。"高内聚"指的是一个模块中各个元素之间的联系紧密程度,例如"财务部门"的联系紧密程度;"低耦合"指的是各个模块之间的紧密程度,例如"行政部门"的联系紧密程度。

(五).总结

在介绍Spring MVC的时候,都是介绍各种Web开发需要用到的注解。

1.@RequestMapping :路由映射

2.@RequestParam :参数重命名

3.@RequestBody :接收JSON类型的数据

4.@PathVariable :接收路由参数

5.@ReuqestPart :上传文件

6.@ResponseBody :返回数据

7.@CookieValue :从Cookie中获取值

8.@SessionAttribute:从Session中获取值

9.@RequestHeader:从Header中获取值

10.@Controller :定义一个控制器,Spring框架启动时加载,把这个对象交给Spring管理,默认返回视图

11.@RestController=@Controller + @ResponseBody

相关推荐
仍然.1 天前
Spring MVC(1)---介绍Spring MVC 和 请求数据
java·spring·mvc
摇滚侠3 天前
Spring MVC 不是一个单独的框架,是 Spring 框架的一个模块
java·spring·mvc
我登哥MVP4 天前
Spring Boot 从“会用”到“精通”:SpringBoot MVC 请求处理全流程
java·spring boot·后端·spring·mvc·maven·intellij-idea
摇滚侠6 天前
JavaWeb 全套教程 MVC 模式 93
mvc
代码的小搬运工6 天前
【iOS】MVC架构
ios·架构·mvc
qq_2518364578 天前
基于MVC的学校食堂点餐管理系统的设计与实现
mvc
故渊at8 天前
系列一:架构思想进阶 | 第1篇 Android 架构演进实录:从 MVC 的“万能类”到 MVVM 的数据驱动
android·架构·mvc
RR13358 天前
Spring MVC and Spring Gateway 的差异,以及报错处理
spring·gateway·mvc
gCode Teacher 格码致知9 天前
AspNet Mvc教学:Route路由切换-由Deepseek产生
mvc