servlet(2)—javaEE

1.获取请求数据

1.1开发前端发请求

ajax封装代码

// 参数 args 是一个 JS 对象, 里面包含了以下属性
// method: 请求方法
// url: 请求路径
// body: 请求的正文数据
// contentType: 请求正文的格式
// callback: 处理响应的回调函数, 有两个参数, 响应正文和响应的状态码
function ajax(args) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        // 0: 请求未初始化
        // 1: 服务器连接已建立
        // 2: 请求已接收
        // 3: 请求处理中
        // 4: 请求已完成,且响应已就绪
        if (xhr.readyState == 4) {
            args.callback(xhr.status, xhr.responseText)
        }
    }
    xhr.open(args.method, args.url);
    if (args.contentType) {
        xhr.setRequestHeader('Content-type', args.contentType);
    }
    if (args.body) {
        xhr.send(args.body);
    } else {
        xhr.send();
    }
}

html前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="u" type="text" placeholder="请输入账号">
    <br>
    <input id="p" type="password" placeholder="请输入密码">
    <br>
    <button onclick="send()">ajax get提交</button>
    <script src="ajax.js"></script>
    <script>
        var username = document.querySelector("#u");
        var password = document.querySelector("#p");
        function send() {
            ajax({
                method: "GET",
                url:"request/get?username="+username.value+"&password="+password.value,
                callback: function(status,resp){
                    alert("响应状态码:"+status+",响应正文:"+resp)
                }
            })
        }
    </script>
</body>
</html>

1.2开发后端servlet

package org.example.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/request/get")
public class requestGet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.printf("username=%s,password=%s\n",username,password);
    }
}

在这里插入图片描述

打印结果:
在这里插入图片描述

2.客户端发送请求

2.1ajax发请求

(1)8的获取请求数据使用的就是ajax发请求
(2)get方法的执行流程
①点击get提交按钮到绑定的点击事件
②执行绑定的点击事件的函数(ajax代码)
③执行后端代码
在这里插入图片描述
(2)可能出现的问题
①按钮点击以后没有反应,抓包解决
在这里插入图片描述

②没有发http请求,一定是前端代码的问题,开发者工具,源代码才是浏览器真正运行的代码解决
在这里插入图片描述

③抓包出现404,检查请求路径和服务端资源路径
在这里插入图片描述
请求路径:
绝对路径写法:
在这里插入图片描述

相对路径写法:
在这里插入图片描述

④出现405,方法不支持,检查后端代码,看是否提供对应的服务方法
在这里插入图片描述

在这里插入图片描述

2.2发送form表单格式的请求数据

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="u" type="text" placeholder="请输入账号">
    <br>
    <input id="p" type="password" placeholder="请输入密码">
    <br>
    <button onclick="send()">ajax form表单提交</button>
    <script src="ajax.js"></script>
    <script>
        var username = document.querySelector("#u");
        var password = document.querySelector("#p");
        function send() {
            ajax({
                method: "POST",
                url:"request/post",
                contentType: "application/x-www-form-urlencoded",
                body:"username="+username.value+"&password="+password.value,
                callback: function(status,resp){
                    alert("响应状态码:"+status+",响应正文:"+resp)
                }
            })
        }
    </script>
</body>
</html>

后端代码:

package org.example.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/request/post")
public class requestFormAjax extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.printf("username=%s,password=%s\n",username,password);
    }
}

抓包看到的请求正文的结果
在这里插入图片描述

2.3发送JSON格式的请求数据

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="u" type="text" placeholder="请输入账号">
    <br>
    <input id="p" type="password" placeholder="请输入密码">
    <br>
    <button onclick="send()">ajax json提交</button>
    <script src="ajax.js"></script>
    <script>
        var username = document.querySelector("#u");
        var password = document.querySelector("#p");
        function send() {
            // json对象
            var data = {
                username:username.value,
                password:password.value
            };
            ajax({
                method: "POST",
                url:"request/json",
                contentType: "application/json",
                // 将JSON对象转换为JSON字符串
                body: JSON.stringify(data),
                callback: function(status,resp){
                    alert("响应状态码:"+status+",响应正文:"+resp)
                }
            })
        }
    </script>
</body>
</html>

servlet代码的第一种写法,了解就行

package org.example.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

@WebServlet("/request/json")
public class requestJSON1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收请求body为json格式的数据,需要使用inputStream
        InputStream is = req.getInputStream();
        //接收到的是字节流,需要使用字节字符转换流来转换
        InputStreamReader isr = new InputStreamReader(is, "UTF-8");
        //最终是:字符流(字节字符转换流(字节流))
        BufferedReader br = new BufferedReader(isr);
        String str;
        //读取一行到字符串,如果不为空,表示没有结束
        while ((str=br.readLine()) != null){
            System.out.println(str);
        }
    }
}

抓包看到的请求正文的结果
在这里插入图片描述
测试JSON在java中的使用:
引入依赖:

<dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     <version>2.11.3</version>
</dependency>

测试JSON在java中的使用

package org.example.servlet;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;

public class textJSON {
    public static void main(String[] args) throws JsonProcessingException {
        // json反序列化:JSON字符串转java对象
        String json = "{\"username\":\"in\",\"password\":\"123\"}";
        // 需要使用Jackson框架提供的api来完成
        // 这个对象就是辅助完成JSON字符串和java对象相互转化
        ObjectMapper objectMapper = new ObjectMapper();
        // 可以转换为map,但是还是不但方便
        HashMap map = objectMapper.readValue(json,HashMap.class);
        System.out.println(map);//结果:{password=123, username=in}
        // 建议:自定义一个类型,成员变量名就是JSON字符串的键名,类型要保持一致
        User user = objectMapper.readValue(json,User.class);
        System.out.println(user);//结果:User{username='in', password='123'}
    }
}

用户类:

package org.example.servlet;

public class User {
    private String username;
    private String password;

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

servlet代码的第二种写法,也建议这样完成

package org.example.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

@WebServlet("/request/json")
public class requestJSON2 extends HttpServlet {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //接收请求body为json格式的数据,需要使用inputStream
        InputStream is = req.getInputStream();
        // json反序列化:将JSON字符串转化为java对象
        User user = objectMapper.readValue(is,User.class);
        System.out.println(user);
    }
}

2.4发送form-data格式的数据

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="u" type="text" placeholder="请输入账号">
    <br>
    <input id="p" type="password" placeholder="请输入密码">
    <br>
    <button onclick="send()">ajax form-data提交</button>
    <script src="ajax.js"></script>
    <script>
        var username = document.querySelector("#u");
        var password = document.querySelector("#p");
        function send() {
            // form-data数据提交使用FormData对象
            var data = new FormData();
            data.append("username",username.value);
            data.append("password",password.value);
            ajax({
                method: "POST",
                url:"request/form-data",
                // form-data不要设置contentType字段,发数据的时候ajax会自动生成
                body: data,
                callback: function(status,resp){
                    alert("响应状态码:"+status+",响应正文:"+resp)
                }
            })
        }
    </script>
</body>
</html>

后端代码:

package org.example.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/request/form-data")
//要获取form-data格式的数据就必须加上这个注解
@MultipartConfig
public class requestFormData extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.printf("username=%s,password=%s\n",username,password);
    }
}

2.5发送form-data格式的数据(文件上传)

(1)代码:
前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="u" type="text" placeholder="请输入账号">
    <br>
    <input id="p" type="password" placeholder="请输入密码">
    <br>
    <input id="f" type="file">
    <br>
    <button onclick="send()">ajax form-data提交</button>
    <script src="ajax.js"></script>
    <script>
        var username = document.querySelector("#u");
        var password = document.querySelector("#p");
        var head = document.querySelector("#f");
        function send() {
            // form-data数据提交使用FormData对象
            var data = new FormData();
            data.append("username",username.value);
            data.append("password",password.value);
            var choosedFiles = head.files[0];
            if(choosedFiles){
                data.append("head",choosedFiles);
            }
            ajax({
                method: "POST",
                url:"request/form-data-file",
                // form-data不要设置contentType字段,发数据的时候ajax会自动生成
                body: data,
                callback: function(status,resp){
                    alert("响应状态码:"+status+",响应正文:"+resp)
                }
            })
        }
    </script>
</body>
</html>

后端代码:

package org.example.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;

@WebServlet("/request/form-data-file")
//要获取form-data格式的数据就必须加上这个注解
@MultipartConfig
public class requestFormDataFile extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // form-data上传简单类型的数据通过getParameter获取
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // form-data上传文件通过getPath获取,返回值part对象就可以获取文件的相关信息,也可以对其进行操作
        Part head = req.getPart("head");
        String path = "E:/TMP/" + head.getSubmittedFileName();
        head.write(path);//保存客户端上传的文件到服务端本地
        System.out.println(head.getSubmittedFileName());//获取上传的文件名
        System.out.println(path);
        System.out.println(head.getSize());//获取上传文件的字节数
        System.out.printf("username=%s,password=%s\n",username,password);
    }
}

抓包结果:
在这里插入图片描述
在这里插入图片描述

打印结果:
在这里插入图片描述
(2)保存的文件如何设计
①文件较小且上传文件的数据量不大,可以考虑使用数据库,将二进制数据转换为字符串(Base64),然后保存;文件较大,不考虑使用数据库保存,一般使用单独的服务器来做
②文件较大,放在服务器的本地硬盘上,但是注意不能放在项目的目录下,对于访问问题,可以自己写代码提供服务资源,请求数据包含一些信息就可以返回不同文件的响应

3.服务端返回响应

3.1返回HTML格式的数据(servlet返回动态网页)

(1)原因:HTML是静态的,不通过ajax是无法访问一个网页构造不同的内容
(2)servlet返回动态网页就是根据条件来拼接HTML字符串

package org.example.servlet;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/response/html")
public class responseHtml extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String userId = req.getParameter("userId");
        String html = "<P>欢迎你,%s</P>";
        String name = "张三";
        if(!"1".equals(userId)){
            name = "李四";
        }
        String body = String.format(html,name);
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        resp.getWriter().write(body);
    }
}

在这里插入图片描述
在这里插入图片描述

3.2返回JSON格式的数据

(1)序列化和反序列化

序列化:站在自己程序的角度,把自己程序中的对象转化为其他格式,用于返回响应数据
反序列化:站在自己程序的角度,把其他格式的数据转化为自己程序中的对象,用于接收请求数据

(2)测试json在Java中的使用
成员类:

package org.example.servlet;

public class User {
    private String username;
    private String password;

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

班级类:

package org.example.servlet;

import java.util.List;

public class classes {
    private int id;
    private String name;
    private List<User> student;

    @Override
    public String toString() {
        return "classes{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", student=" + student +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<User> getStudent() {
        return student;
    }

    public void setStudent(List<User> student) {
        this.student = student;
    }
}

测试JSON在java中的使用:

package org.example.servlet;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class textJSON {
    public static void main(String[] args) throws JsonProcessingException {
        // json反序列化:JSON字符串转java对象
        String json = "{\"username\":\"in\",\"password\":\"123\"}";
        // 需要使用Jackson框架提供的api来完成
        // 这个对象就是辅助完成JSON字符串和java对象相互转化
        ObjectMapper objectMapper = new ObjectMapper();
        // 可以转换为map,但是还是不但方便
//        HashMap map = objectMapper.readValue(json,HashMap.class);
//        System.out.println(map);//结果:{password=123, username=in}
        // 建议:自定义一个类型,成员变量名就是JSON字符串的键名,类型要保持一致
        User user = objectMapper.readValue(json,User.class);
        System.out.println(user);//结果:User{username='in', password='123'}
        //简单类型的JSON对象
        User user1 = new User();
        user1.setUsername("张三");
        user1.setPassword("123");
        String json1 = objectMapper.writeValueAsString(user1);//结果:{"username":"张三","password":"123"}
        System.out.println(json1);
        User user2 = new User();
        user2.setUsername("李四");
        user2.setPassword("456");
        //初始化list,包含user1和user2两个对象
        List<User> list = Arrays.asList(user1,user2);
        String json2 = objectMapper.writeValueAsString(list);//结果:[{"username":"张三","password":"123"},{"username":"李四","password":"456"}]
        System.out.println(json2);
        //复杂类型的JSON对象
        classes classes1 = new classes();
        classes1.setId(1);
        classes1.setName("hehe");
        classes1.setStudent(list);
        String json3 = objectMapper.writeValueAsString(classes1);
        System.out.println(json3);//结果:{"id":1,"name":"hehe","student":[{"username":"张三","password":"123"},{"username":"李四","password":"456"}]}
    }
}

(3)代码
前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h4>班级信息</h3>
    <p id="class_info"></p>
    <ul></ul>
    <script src="ajax.js"></script>
    <script>
        var classInfo = document.querySelector("#class_info");
        var studentList = document.querySelector("ul");
        ajax({
            method: "GET",
            url: "response/json",
            callback:function(status,resp){
                console.log("响应状态码:"+status+",响应正文:"+resp);
                var json = JSON.parse(resp);
                console.log(json);
                // 解析响应的班级信息的数据
                classInfo.innerHTML = `
                    班级id:${json.id},班级姓名:${json.name}
                `
                // 解析响应的学生列表的信息
                var content = '';
                for(var stu of json.student){
                    content += `
                        <li>学生姓名:${stu.username},账号密码:${stu.password}</li>
                    `
                }
                studentList.innerHTML = content;
            }
        });
    </script>
</body>
</html>

ajax封装的代码:

// 参数 args 是一个 JS 对象, 里面包含了以下属性
// method: 请求方法
// url: 请求路径
// body: 请求的正文数据
// contentType: 请求正文的格式
// callback: 处理响应的回调函数, 有两个参数, 响应正文和响应的状态码
function ajax(args) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        // 0: 请求未初始化
        // 1: 服务器连接已建立
        // 2: 请求已接收
        // 3: 请求处理中
        // 4: 请求已完成,且响应已就绪
        if (xhr.readyState == 4) {
            args.callback(xhr.status, xhr.responseText)
        }
    }
    xhr.open(args.method, args.url);
    if (args.contentType) {
        xhr.setRequestHeader('Content-type', args.contentType);
    }
    if (args.body) {
        xhr.send(args.body);
    } else {
        xhr.send();
    }
}

后端代码:

package org.example.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

@WebServlet("/response/json")
public class responseJSON extends HttpServlet {
    private static final ObjectMapper m = new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User user1 = new User();
        user1.setUsername("张三");
        user1.setPassword("123");
        User user2 = new User();
        user2.setUsername("李四");
        user2.setPassword("456");
        List<User> list = Arrays.asList(user1,user2);
        //复杂类型的JSON对象
        classes classes1 = new classes();
        classes1.setId(1);
        classes1.setName("hehe");
        classes1.setStudent(list);
        //返回给前端一个JSON字符串
        String json = m.writeValueAsString(classes1);
        //设置响应正文的数据格式
        resp.setContentType("application/json");
        //设置响应正文的编码
        resp.setCharacterEncoding("UTF-8");
        //设置到body中
        resp.getWriter().write(json);
    }
}

完成后端代码的结果
在这里插入图片描述
开发前端后的结果
在这里插入图片描述
(4)请求和响应
在这里插入图片描述

请求:前端如果是发送JSON:JSON.stringify(json对象);在这里插入图片描述
后端如果解析这个JSON:objectMapper.readValue(request.getInputStream, 类.class)在这里插入图片描述

响应:后端返回JSON字符串:response.writer(objectMapper.writerValueAsString(java对象);在这里插入图片描述
前端解析响应:ajax的callback回调函数,JSON.parse(方法参数中的响应正文字符串)在这里插入图片描述

4.实现请求一个路径,实现跳转或返回其他页面内容

4.1实现方式一:前端发ajax,后端返回json,前端解析响应,判断是否要跳转

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="u" type="text" placeholder="请输入账号">
    <br>
    <input id="p" type="password" placeholder="请输入密码">
    <br>
    <input type="button" value="模拟用户登录(前端跳转)" onclick="login()">
    <br>
    <script src="ajax.js"></script>
    <script>
        var username = document.querySelector("#u");
        var password = document.querySelector("#p");
        // 实现方式一:前端发ajax,后端返回json,前端解析响应,判断是否要跳转
        function login(){
            ajax({
                method: "POST",
                url: "jump",
                contentType: "application/x-www-form-urlencoded",
                body: "username="+username.value+"&password="+password.value,
                callback: function(status,resp){
                    console.log("响应状态码:"+status+",响应正文:"+resp);
                    //转换响应正文JSON字符串为JSON对象
                    var json = JSON.parse(resp);
                    if(json.ok){
                        // 登录成功就跳转到这个路径
                        location.href = "request-ajax.html";
                    }else{
                        // 不成功给出弹窗提示
                        alert("账户或密码错误");
                    }
                }
            })
        }
    </script>
</body>
</html>

后端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input id="u" type="text" placeholder="请输入账号">
    <br>
    <input id="p" type="password" placeholder="请输入密码">
    <br>
    <input type="button" value="模拟用户登录(前端跳转)" onclick="login()">
    <br>
    <script src="ajax.js"></script>
    <script>
        var username = document.querySelector("#u");
        var password = document.querySelector("#p");
        // 实现方式一:前端发ajax,后端返回json,前端解析响应,判断是否要跳转
        function login(){
            ajax({
                method: "POST",
                url: "jump",
                contentType: "application/x-www-form-urlencoded",
                body: "username="+username.value+"&password="+password.value,
                callback: function(status,resp){
                    console.log("响应状态码:"+status+",响应正文:"+resp);
                    //转换响应正文JSON字符串为JSON对象
                    var json = JSON.parse(resp);
                    if(json.ok){
                        // 登录成功就跳转到这个路径
                        location.href = "request-ajax.html";
                    }else{
                        // 不成功给出弹窗提示
                        alert("账户或密码错误");
                    }
                }
            })
        }
    </script>
</body>
</html>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.2实现方式二:前端发ajax,后端登录成功直接跳转,登录失败还是跳转本页面

但是不建议返回HTML,这里就不详细介绍了(会出现重定向的问题)

5.转发和重定向

5.1转发

在这里插入图片描述
(1)特点:一次请求,路径不变
(2)服务端主动帮忙找资源

package org.example.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/jump2")
public class jump2Servlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("response-JSON.html").forward(req,resp);
    }
}

在这里插入图片描述
抓包:
在这里插入图片描述

在这里插入图片描述

5.2重定向

在这里插入图片描述
(1)特点:两次请求,路径会变
(2)原理:发送的请求返回301/302/307重定向状态码,响应头Location字段标识要跳转的路径;浏览器自动的发起第二次请求,地址栏会变成Location的路径
后端代码:

package org.example.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/jump3")
public class jump3Servlet extends HttpServlet {
    private static final ObjectMapper m = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //模拟用户登录验证账号密码是否正确
        if("abc".equals(username) && "123".equals(password)){
            resp.sendRedirect("response-JSON.html");
        }else {
            resp.sendRedirect("jump2.html");
        }
    }
}

前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="jump3" method="post">
        <input id="u" name="username" type="text" placeholder="请输入账号">
        <br>
        <input id="p" name="password" type="password" placeholder="请输入密码">
        <br>
        <input type="submit" value="模拟登录(后端跳转)">
    </form>
    <br>
    <script src="ajax.js"></script>
    <script>
        var username = document.querySelector("#u");
        var password = document.querySelector("#p");
        // 实现方式二:前端发ajax,后端登录成功直接跳转,登录失败还是在本页面(但是会刷新)
        function login(){
            ajax({
                method: "POST",
                url: "jump3",
                contentType: "application/x-www-form-urlencoded",
                body: "username="+username.value+"&password="+password.value,
                callback: function(status,resp){
                    console.log("响应状态码:"+status+",响应正文:"+resp);
                    //转换响应正文JSON字符串为JSON对象
                    var json = JSON.parse(resp);
                    if(json.ok){
                        // 登录成功就跳转到这个路径
                        location.href = "request-ajax.html";
                    }else{
                        // 不成功给出弹窗提示
                        alert("账户或密码错误");
                    }
                }
            })
        }
    </script>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
抓包:登录成功
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
登录不成功:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.总结

6.1请求和响应的前后端代码

在这里插入图片描述

6.2服务端获取数据的方式

在这里插入图片描述

6.3服务端返回数据的方式

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值