【JavaEE进阶】Spring MVC(3)

欢迎关注个人主页:逸狼


创造不易,可以点点赞吗

如有错误,欢迎指出~


返回响应

返回静态页面

复制代码
//@RestController
@Controller
@RequestMapping("/response")
public class ResponseController {
    @RequestMapping("/returnHtmlPage")
    public String returnHtmlPage(){
        return "/hello.html";
    }
}

创建前端页面hello.html(注意要放到static文件夹下面)

@RestController = @Controller+@ResponseBody(返回数据)

如果只加@Controller,返回的是视图页面,若加上@RestController,返回的就是数据了

@ResponseBody 既是类注解,又是方法注解,

  • 加在上,该类的所有方法都 返回数据,
  • 加在方法上,该方法 返回数据,其他方法不受影响

如果⼀个类的⽅法⾥,既有返回数据的,⼜有返回⻚⾯的,就把 @ResponseBody 注解添加到对应的⽅ 法上即可.

复制代码
@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        return "/index.html";
    }
    @ResponseBody
    @RequestMapping("/returnData")
    public String returnData(){
        return "该⽅法返回数据";
    }
}

如果将第二个方法returnDate中的注解**@ResponseBody去掉**,前端会报404的错误,因为程序会认为返回的是一个html页面,所以会在static文件夹找,没有找到就会报错

返回Html代码

后端数据中如果有html代码,会被浏览器解析

复制代码
    //返回Html的代码
    @ResponseBody
    @RequestMapping("/returnHtml")
    public String returnHtml(){
        return "<h1>returnHtml</h1>";
    }

通过Fiddler观察响应结果, Content-Type 为 text/html

响应中的Content-Type常⻅取值有以下⼏种:

  1. text/html :body数据格式是HTML
  2. text/css :body数据格式是CSS
  3. application/javascript :body数据格式是JavaScript
  4. application/json :body数据格式是JSON

返回json数据

复制代码
    //返回json
    @ResponseBody
    @RequestMapping("/returnJson")
    public User returnJson(){
        User user=new User();
        user.setName("zhangsan");
        user.setAge(18);
        return user;
    }

返回状态码

SpringMVC会根据我们⽅法的返回结果⾃动设置响应状态码,程序员也可以⼿动指定状态码 通过SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

复制代码
    //设置状态码
    @ResponseBody
    @RequestMapping("/setStatus")
    public User returnJson(HttpServletResponse response){
        User user=new User();
        user.setName("zhangsan");
        user.setAge(18);
        response.setStatus(500);
        return user;
    }

状态码不影响界面的展示

设置Header

复制代码
    //设置header
    @ResponseBody
    @RequestMapping(value="/setHeader",produces="application/json")
    public String setHeader(){
        return "{\"success\":true}";
    }

方法二

设置其他Header的话,需要使⽤SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

voidsetHeader(Stringname,Stringvalue)设置⼀个带有给定的名称和值的header.如果name 已经存在,则覆盖旧的值.

复制代码
    @ResponseBody
    @RequestMapping("/setHeader2")
    public String setHeader(HttpServletResponse response){
        response.setHeader("myKey","myValue");

        return "success";
    }

小案例实践1:实现一个加法计算器

约定前后端交互接⼝

约定"前后端交互接⼝ "是进⾏Web开发中的关键环节 . 接⼝⼜叫API(Application Programming Interface),我们⼀般讲到接⼝或者API,指的都是同⼀个东 西.(就是允许客⼾端给服务器发送哪些HTTP请求 ,并且每种请求预期获取什么样的HTTP响应.

接⼝,其实也就是我们前⾯⽹络模块讲的的"应⽤层协议".把约定的内容写在⽂档上,就是"接⼝⽂档", 接⼝⽂档也可以理解为是应⽤程序的"操作说明书".

以实现上面的加法计数器 为例

需求分析

加法计算器功能,对两个整数进⾏相加,需要客⼾端提供参与计算的两个数,服务端返回这两个整数计算 的结果

接⼝定义

  1. 请求路径:calc/sum
  2. 请求⽅式:GET/POST
  3. 接⼝描述:计算两个整数相加

请求参数

响应数据

  1. Content-Type: text/html
  2. 响应内容: 计算机计算结果: 8

服务器给浏览器返回计算的结果

后端服务器代码

复制代码
@RestController
@RequestMapping("/calc")
public class CalcController {
    @RequestMapping("/sum")
    public String sum(@RequestParam("num1") Integer num1,
                      @RequestParam("num2") Integer num2){
        Integer sum=num1 + num2 ;
        return "计算器计算结果:"+sum;
    }
}

前端calc.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/sum" 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>

要记得将前端代码放到static文件夹下

小案例实践2:⽤⼾登录

需求分析

⽤⼾输⼊账号和密码, 后端进⾏校验密码是否正确

  1. 如果不正确,前端进⾏⽤⼾告知

  2. 如果正确,跳转到⾸⻚.⾸⻚显⽰当前登录⽤⼾

  3. 后续再访问⾸⻚,可以获取到登录⽤⼾信息

校验接口

接口定义

  1. 请求路径:/user/login
  2. 请求⽅式:POST
  3. 接⼝描述:校验账号密码是否正确

响应数据

  1. Content-Type: text/html
  2. 响应内容: true //账号密码验证成功
  3. false//账号密码验证失败

后端代码实现

复制代码
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping(value="/login",method= RequestMethod.POST)
    public Boolean login(String userName, String password, HttpSession session){//如果有session则返回,没有就创建
//        if(userName==null || "".equals(userName)){//将常量写在前面,防止userName为空,会报空指针异常
//            return false;
//        }
        //如果用户名和密码两者有一个为空,
        if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)){
            return false;
        }
        //不为空,校验账号和密码是否正确
        if("admin".equals(userName) && "admin".equals(password)){
            //登入成功,要设置session,把⽤⼾名存储在Session中 
            session.setAttribute("userName",userName);
            return true;
        }
        return false;
        //尽可能少些嵌套
    }

查询用户登入接口

接口定义

  1. 请求路径:/user/getLoginUser
  2. 请求⽅式:GET
  3. 接⼝描述:查询当前登录的⽤⼾

响应数据

  1. Content-Type: text/html
  2. 响应内容: zhangsan

返回当前登录的⽤⼾

后端代码实现

复制代码
@RequestMapping(value="/getLoginUser",method= RequestMethod.GET)
    public String getLoginUser(HttpSession session){
        if(session.getAttribute("userName")!= null){
            return (String) session.getAttribute("userName");
        }
        return "";
    }

前端login.html代码

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

<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>

<body>
<h1>用户登录</h1>
用户名:<input name="userName" type="text" id="userName"><br>
密码:<input name="password" type="password" id="password"><br>
<input type="button" value="登录" onclick="login()">

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
    function login() {
       $.ajax({
        type: "post",
        url: "/user/login",
        data: {
          "userName": $("#userName").val(),
          "password": $("#password").val()
        },
        success: function(body){
          if(body==true){
            //跳转到index页面
            location.href = "index.html";
          }else{
            //当前页面
            alert("密码错误");
          }
        }
       });
    }

  </script>
</body>

</html>

前端index.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>用户登录首页</title>
</head>

<body>
登录人: <span id="loginUser"></span>

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script>
        $.ajax({
            type: "get",
            url: "/user/getLoginUser",
            success: function(userName){
                $("#loginUser").text(userName);
            }
        });
    </script>
</body>

</html>

在浏览器中测试的结果如下

小案例实践3:留言板

需求分析

后端需要提供两个服务

  1. 提交留⾔:⽤⼾输⼊留⾔信息之后,后端需要把留⾔信息保存起来

  2. 展⽰留⾔:⻚⾯展⽰时,需要从后端获取到所有的留⾔信息

创建MessageInfo类

复制代码
@Data//来自lombok,加上后不用写get和set方法了(自动帮助生成get和set方法)
public class MessageInfo {
    public String from;
    public String to;
    public String message;
}

接⼝定义

1. 获取全部留⾔

全部留⾔信息,我们⽤List来表⽰,可以⽤JSON来描述这个List数据.接口定义

2. 发表新留⾔

请求:body也为JSON格式.

后端代码实现

复制代码
@RestController
@RequestMapping("/message")
public class MessageController {

    //存储留言信息
    private List<MessageInfo> messageInfos=new ArrayList<>();
    @RequestMapping("/getList")
    public List<MessageInfo> getList(){
        return messageInfos;
    }

    //发表留言
    @RequestMapping(value = "/publish",produces = "application/json")//设置返回结果为json
    public String publish(@RequestBody MessageInfo messageInfo){
        if(StringUtils.hasLength(messageInfo.getFrom())
        && StringUtils.hasLength(messageInfo.getTo())
        && StringUtils.hasLength(messageInfo.getMessage())){
            messageInfos.add(messageInfo);
            return "{\"ok\":1}";
        }
        //发布失败
        return "{\"ok\":0}";

    }
}

前端代码实现

复制代码
<!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="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script>
        getList();
        function getList() {
            $.ajax({
                type: "get",
                url: "/message/getList",
                success: function (messages) {
                    for (let msg of messages) {
                        let html = "<div>" + msg.from + " 对 " + msg.to + " 说: " + msg.message + "</div>";
                        $(".container").append(html);
                    }
                }
            });
        }

        function submit() {
            let from = $("#from").val();
            let to = $("#to").val();
            let say = $("#say").val();

            if (from == "" || to == "" || say == "") {
                alert("请检查输入内容");
                return;
            }
            //检验完成之后, 发起后端请求
            $.ajax({
                url: "/message/publish",
                type: "post",
                // 设置Request ContentType
                contentType: "application/json",
                // 将对象转为json
                data: JSON.stringify({
                    from: from,
                    to: to,
                    message: say
                }),
                success: function (result) {
                    
                    if (result.ok == 1) {
                        //添加成功
                        alert("添加成功");
                        let html = "<div>" + from + " 对 " + to + " 说: " + say + "</div>";

                        $(".container").append(html);
                        $(":text").val("");
                    } else {
                        //失败
                        alert("添加失败");
                    }
                }

            });



        }

    </script>
</body>

</html>

引入lombok

Lombok是⼀个Java⼯具库,通过添加注解的⽅式,简化Java的开发.

lombok通过⼀些注解的⽅式,可以帮助我们消除⼀些冗⻓代码,使代码看起来简洁⼀些

在pom文件里加上lombok依赖

复制代码
        <dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
相关推荐
山海上的风2 小时前
Spring Batch终极指南:原理、实战与性能优化
spring·性能优化·batch·springbatch
找不到、了3 小时前
Spring的Bean原型模式下的使用
java·spring·原型模式
超级小忍3 小时前
Spring AI ETL Pipeline使用指南
人工智能·spring
Boilermaker19927 小时前
【Java EE】SpringIoC
前端·数据库·spring
写不出来就跑路7 小时前
Spring Security架构与实战全解析
java·spring·架构
sleepcattt8 小时前
Spring中Bean的实例化(xml)
xml·java·spring
小七mod8 小时前
【Spring】Java SPI机制及Spring Boot使用实例
java·spring boot·spring·spi·双亲委派
ruan1145149 小时前
Java Lambda 类型推断详解:filter() 方法与 Predicate<? super T>
java·开发语言·spring·stream
paopaokaka_luck9 小时前
基于SpringBoot+Vue的非遗文化传承管理系统(websocket即时通讯、协同过滤算法、支付宝沙盒支付、可分享链接、功能量非常大)
java·数据库·vue.js·spring boot·后端·spring·小程序
邓不利东14 小时前
Spring中过滤器和拦截器的区别及具体实现
java·后端·spring