目录

分析程序报错的步骤

案例

一.加法计算器

二.实现用户登录

1.登录接口

2.获取用户的登录信息

三.留言板

1.接口定义

2.完成后端代码

3.测试后端代码

四.图书管理系统

1.定义接口

2.后端代码

3.测试后端代码

4.前端交互代码

应用分层

1.三层架构


分析程序报错步骤

1.定位前端还是后端:通过日志

1)前端:F12、看控制台

2)后端:接口控制台

2.判断请求是否到达后端

1)后端代码在相应方法第一行通过打印一些标记字符串判断运行后如果没有打印内容请求没有到达后端

2)抓包查看访问接口是否正确

3.当感觉前端代码没有错,后端却接收不到请求

测试接口:http地址中加上后端参数访问测试后端代码是否可以实现

4.查看缓存问题

常见的是当前端有代码覆盖后,后面新的代码运行成功却在页面显示的是覆盖前的页面,这时在Maven面板点击clean清除缓存

案例

一.加法计算器

前端代码calc.html

<!DOCTYPE html>
<html lang="en">
<head&gt;
    <meta charset="UTF-8"&gt;
    <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>

后端实现相加

package com.example.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/calc")
@RestController
public class calcController {

    @RequestMapping("/sum")
    public String sum(Integer num1,Integer num2){
        Integer sum=num1+num2;
        return "计算结果为:"+sum;
    }
}

二.实现用户登录

1.登录接口

/user/login

userName = ? &amp; password = ?

接口返回校验成功/失败

true   密码正确

false  密码错误

2.获取用户登录信息

/user/getUserInfo

接口返回当前登录用户名称

前端代码

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://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
    function login() {
      // 测试日志 检测前端请求是否能发出(onlick)的时候
      console.log("登录...")

      $.ajax({
        url:"/user/login",
        type:"post",
        data:{
          "userName":$("#userName").val(),
          "password":$("#password").val()
        },
        success:function(result){
          if(result){
            location.href ="/index2.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://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>
    // 页面加载时候就去调用后端请求
    $.ajax({
      url:"/user/getUserInfo",
      type:"post",
      success:function(userName){
        $("#loginUser").text(userName);
      }
    })
</script>
</body>

</html>

后端代码:

package com.example.demo.controller;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/login")
    public Boolean login(String userName, String password, HttpSession session){
        //校验参数的合法性
//        if(userName==null ||userName.length()==0 || password==null || password.length()==0){
//            return false;
//        }
        if(!StringUtils.hasLength(userName)||!StringUtils.hasLength(password)){
            return false;
        }
        //进行用户名密码校验
        if("admin".equals(userName)&amp;&amp;"admin".equals(password)){
            //设置session
            session.setAttribute("username","admin");
            return true;
        }
        return false;
    }

    @RequestMapping("/getUserInfo")
//    public String getUserInfo(HttpSession session){
//        //从session获取登录用户
//        String username=(String) session.getAttribute("username");
//        return username;

    public String getUserInfo(HttpServletRequest request){
        //从session获取用户
        HttpSession session= request.getSession(false);
        String username=null;
        if(session!=null){
            username=(String)session.getAttribute("username");
        }
        return username;
    }
}

三.留言板

前端页面

现在后端需要完成的是:把数据保存下来(内存数据库….)

1.接口定义

(1)提交留言 

/message/publish

参数:MessgaeInfo(from,to,message)

返回结果true/false

(2)查看所有留言

/message/getMessageList

参数:无

返回结果:List<MessageInfo>

后端代码

定义一个信息类,这时我们可以使用maven自带工具lombok自动定义set和get方法

针对所有属性加上set和get方法,@Data放在类的外面

2.完成后端代码

package com.example.demo;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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


@RequestMapping("/message")
@RestController
public class MessageController {
    private List<MessageInfo> messageInfos=new ArrayList<>();
    //发布留言
    @RequestMapping("/publish")
    public Boolean publishMassage(MessageInfo messageInfo){
       //进行参数校验
        if(!StringUtils.hasLength(messageInfo.getFrom()) ||
                !StringUtils.hasLength(messageInfo.getTo()) ||
                !StringUtils.hasLength(messageInfo.getMessage())){
            return false;
        }
        //添加留言
        messageInfos.add(messageInfo);
       return true;
    }

    //查看留言
    @RequestMapping("/getMessageInfo")
    public List<MessageInfo> getMessageInfo(){
        return messageInfos;
    }
}

3.测试后端代码

postman上进行测试

publish测试

getMessageInfo测试

由此可见后端代码正确

前端交互主要代码:

<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://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        //页面加载时,请求后端,获取留言列表
        $.ajax({
            url: "/message/getMessageInfo",
            type: "get",
            success: function (messages) {
                for (var m of messages) {
                    //2. 构造节点
                    var divE = "<div>" + m.from + "对" + m.to + "说:" + m.message + "</div>";
                    //3. 把节点添加页面上
                    $(".container").append(divE);
                }
            }
        })
        function submit() {
            //1. 获取留言内容
            var from = $('#from').val();
            var to = $('#to').val();
            var say = $('#say').val();
            if (from == '' || to == '' || say == '') {
                return;
            }

            //提交留言
            $.ajax({
                url: "/message/publish",
                type: "post",
                data: {
                    "from": from,
                    "to": to,
                    "message": say
                },
                success: function (result) {
                    if (result) {
                        //留言成功
                        //2. 构造节点
                        var divE = "<div>" + from + "对" + to + "说:" + say + "</div>";
                        //3. 把节点添加页面上
                        $(".container").append(divE);

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


        }

    </script>
</body>

四.图书管理系统

1.定义接口

(1)登录

url:  /user/login

参数:userName=?&amp;password=?

响应:True/False

(2)图书列表展示

url: /book/getBookList

参数:无

响应:List<BookInfo>

2.后端代码

  UserController

package com.lele.book;

import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/login")
    public Boolean login(String userName, String password, HttpSession session){
        //校验参数
        if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
            return false;
        }
        //if(userName.equals("admin")){}这种写法会报空指针异常
        //校验账号密码是否正确
        if("admin".equals(userName) &amp;&amp; "admin".equals(password)){
            //账号密码正确
            //存session
            session.setAttribute("userName",userName);
            return true;
        }
        return false;
    }
}

BookController

package com.lele.book;

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

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@RequestMapping("/book")
@RestController
public class BookController {
    @RequestMapping("/getBookList")
    public List<BookInfo> getBookList(){
        //1.获取图书数据
        //2.对图书数据进行修改
        //3.返回数据

        //mock表示虚拟的假数据
        List<BookInfo> bookInfos=mockData();
        for (BookInfo bookInfo:bookInfos){
            if(bookInfo.getStatus()==1){
                bookInfo.setStatusCN("可借阅");
            }else {
                bookInfo.setStatusCN("不可借阅");
            }
        }
        return bookInfos;
    }

    private List<BookInfo> mockData() {
        //对已知的数据量创建list建议指定初始化的值
        List<BookInfo> bookInfos=new ArrayList<>(15);
        //随机生成15条图书数据
        for (int i = 0; i < 15; i++) {
            BookInfo bookInfo=new BookInfo();
            bookInfo.setId(i);
            bookInfo.setBookName("图书"+i);
            bookInfo.setAuthor("作者"+i);
            bookInfo.setCount(new Random().nextInt(200));
            bookInfo.setPrice(new BigDecimal(new Random().nextInt(100)));
            bookInfo.setPublish("出版社"+i);
            bookInfo.setStatus(i%5==0?2:1);
            bookInfos.add(bookInfo);
        }
        return bookInfos;
    }
}

BookInfo

package com.lele.book;

import lombok.Data;

import java.math.BigDecimal;

@Data
public class BookInfo {
    private Integer id;
    private String BookName;
    private String author;
    private Integer count;
    private BigDecimal price;
    private String publish;
    private Integer status;//1-可借阅 2-不可借阅
    private String statusCN;

}

3.测试后端代码

测试接口是否可以正常使用

4.前端交互代码

前端登录页跳转到图书列表页面主要代码:

 function login() {
            $.ajax({
                url:"user/login",
                type:"post",
                data:{
                    "userName":$("#userName").val(),
                    "password":$("#password").val()
                },
                success:function(result){
                    if(result){
                        location.href="book_list.html";
                    }else{
                        alert("用户名密码错误!");
                    }
                }
            })
            location.href = "book_list.html";
        }

前端图书列表页获取到后端自动生成的图书:

 function getBookList() {
                $.ajax({
                    url:"/book/getBookList",
                    type:"get",
                    success:function(books){
                        var finalHtml="";
                        for(var book of books){
                           //根据每条记录拼接html,也就是一个tr
                           finalHtml +='<tr>' ;
                           finalHtml +='<td><input type="checkbox" name="selectBook" value="'+book.id+'" id="selectBook" class="book-select"></td>' ;
                           finalHtml +='<td>'+book.id+'</td>' ;
                           finalHtml +='<td>'+book.bookName+'</td>' ;
                           finalHtml +='<td>'+book.author+'</td>' ;
                           finalHtml +='<td>'+book.count+'</td>' ;
                           finalHtml +='<td>'+book.price+'</td>' ;
                           finalHtml +='<td>'+book.publish+'</td>' ;
                           finalHtml +=' <td>'+book.statusCN+'</td>';
                           finalHtml +='<td> <div class="op">';
                           finalHtml +=' <a href="book_update.html?bookId='+book.id+'">修改</a>';
                           finalHtml +='<a href="javascript:void(0)" onclick="deleteBook('+book.id+')">删除</a>';
                           finalHtml +='</div>';
                           finalHtml +='</td></tr>';
                        }
                        console.log(finalHtml);
                        $("tbody").html(finalHtml);
                    }
                })
            }

应用分层

以上代码已经是非常简单业务需求,但前后端代码的交互已经略显混乱。

MVC分层方式已经不足以满足现在的业务需求,取而代之的是三层架构

1.三层架构

(1)表现层:接收请求返回结果

(2)业务逻辑层:业务逻辑处理

(3)数据层:处理数据包含数据的存储、获取(增删改查

2.在Spring中的体现

类比上面的图书管理系统

对图书管理系统进行三层架构

目录分层

调整上述代码:

MVC强调数据和视图分离,将数据和数据处理分开,使用控制器对两者进行组合

三层架构强调不同维度数据处理:将交互界面业务处理数据库逻辑分开。

两者可以互相转换。两者的目的都是:解耦、分层、代码复用

原文地址:https://blog.csdn.net/weixin_67793092/article/details/134613210

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_24188.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注