登录业务

1. 登录业务

  1. 有两个页面: 登录页面, 首页(html)
  2. 业务:

在这里插入图片描述

  1. Servlet 解析请求数据
    在这里插入图片描述

2. 页面跳转

2.1 客户端

html: <a href="跳转的路径">链接标签, 点击跳转
js代码: window.location.href = "跳转路径";

2.2 服务端

服务端Servlet跳转页面:

  1. 转发
  2. 重定向

2.2.1 转发:

在这里插入图片描述
服务算Servlet转发到home.html:

  1. url路径没有变

  2. 只有一次http请求

在这里插入图片描述

2.2.2 重定向:

  1. 请求路径:在这里插入图片描述
  2. 请求后的路径
    在这里插入图片描述

(1) url会发生变化
(2) 两次http请求

  • 第一次http请求: 响应: 301/302/307 表示重定向的状态码Location的头信息, 指定要跳转的url
  • 第二次http请求: 由浏览器解析第一次响应, 发现是 3xx 状态码,就会自动跳转到Location绑定的url地址
    在这里插入图片描述

2.3 客户端 + 服务端

客户端js代码发送ajax异步请求

使用主流前端框架实现 Vue.js(前端js框架, dom元素和变量等双向绑定) + axios(发ajax框架)

请求数据, 响应数据格式: json(Content-Type绑定的body中的数据类型)

服务端基于json的格式来解析请求/ 返回响应
在这里插入图片描述

3. 关于json

  • 前段有json对象:
var person = {firstName:"John", lastName:"Doe", age:50, eyeColor:"blue"};
  • 请求/响应数据(body), 也可以是 json
    此时Content-Type 值为 application/json

java 代码完成对象和 json 字符串转变为 java 对象

  • 反序列化, 把json 字符串转变为 java 对象
// 反序列化. 把json 字符串转变为 java 对象
String s ="{\"username\":\"猴哥和我\",\"password\":\"救救我\"}";
User u2 = mapper.readValue(s, User.class);
  • 序列化, 把 java对象转变为 json 对象
// 序列化, 把 java对象转变为 json 对象
String json = mapper.writeValueAsString(user);

4. 关于 Vuejs 框架使用

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

对于HttpServletRequest, 回去请求数据:

  1. queryString: getParameter 通过键获取值
  2. Content-Type 为 x-www-form-urlencoded (表单数据类型) ,
    body格式和queryString一样, 也通过getParameter获取
  3. 请求体 (body) 由数据, 此时 Content-Type 一定要指定数据类型
  4. 后端都可以通过 request.getInputStream() 获取输入流 (包含 body 内容), 只是要自己去解析 body
    (表单格式相对来说, getParameter要更方便)

application/json: 使用 json 框架来解析
文件上传: 把输入流二进制获取就是获取文件

关于响应
在这里插入图片描述

5. 其他

登录页面 + 后端登录功能, 存在问题?

  1. 访问敏感资源(前端的敏感资源, 后端的敏感资源)

未登录不允许访问:

前段页面跳转到登录页面
后端接口(Servlet)返回 401 状态码 (Unauthorized未授权访问)/ 返回json数据
  1. 技术实现:

Session 和 Cookie

目前比较好的解决方案: Filter

其他方案:
(1)提供一个校验用户是否登录的接口, 每次前段都请求
(2)每个Servlet都去验证一下用户是否登录

6. 代码

Main

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Main {
    public static void main(String[] args) throws JsonProcessingException {
        // 序列化, 把 java对象转变为 json 对象
        ObjectMapper mapper = new ObjectMapper();
        User user = new User();
        user.setUsername("猴哥");
        user.setPassword("救救我");
        String json = mapper.writeValueAsString(user);
        System.out.println(json);


        // 反序列化. 把json 字符串转变为 java 对象
        String s ="{\"username\":\"猴哥和我\",\"password\":\"救救我\"}";
        User u2 = mapper.readValue(s, User.class);
        System.out.println(u2);

        // 反序列化, json键必须对应类中的成员变量, 找不到就会报错
//        String s3 = "{\" username1\":\"猴哥和你\",\"password\":\"救救我\"}";
//        User u3 = mapper.readValue(s3, User.class);
//        System.out.println(u3);

    }
}

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
    <h2>登录页面</h2>
    <form action="login" method="post">
        用户名:<input type="text" name="username">
        <br><br>
        密码:<input type="password" name="password">
        <br><br>
        <input type="submit" value="登录">
    </form>
    <br><br>
    <!--绑定按钮的点击事件, 在用户点击时, 调用绑定的js函数    -->
    <!--js 方式跳转    -->
    <button onclick="goto()">点我跳转</button>
    <br><br>
    <!-- 服务端的方式跳转   -->
    <button onclick="goto2(1)">服务端转发</button>
    <button onclick="goto2(2)">服务端重定向</button>

</body>
<script>
    function goto() {
        window.location.href = "home.html";
    }

    function goto2(type) {
        window.location.href = "goto?type=" + type;

    }
</script>
</html>

home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>登录成功</h1>
</body>
</html>

LoginServlet.java

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.io.PrintWriter;

@WebServlet("/login")

public class LoginServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");

        // 解析请求: header, method, url, 请求数据
        // 通过键获取值, 如果改键没有值, 返回 null
        String username = req.getParameter("username");
        String password = req.getParameter("password");


        PrintWriter pw = resp.getWriter();

        // 数据库根据客户端用户输入的账号密码, 查询有没有该数据
        // 简单的模拟

        if ("abc".equals(username) && "123".equals(password)) {
            pw.println("<h1>欢迎你 " + username + "</h1>");
        } else {
            pw.println("<h1>用户名或密码错误</h2>");
        }
    }
}

GotoServlet.java

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("/goto")
public class GotoServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        req.setCharacterEncoding("UTF-8");
//        resp.setCharacterEncoding("UTF-8");


        // 解析请求数据: 键为type, 为1转发. 为2重定向
        String type = req.getParameter("type");
        if ("1".equals(type)) {
            // 转发
            req.getRequestDispatcher("home.html")
                    .forward(req, resp);
        } else {
            // 重定向
            resp.sendRedirect("home.html");
        }
    }
}

login2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
    <h2>用户登录</h2>
    <div id="app">
        用户名:<input type="text" v-model="username">
        <br><br>
        密码:<input type="password" v-model="password">
        <br><br>
        <button v-on:click="login()">登录</button>

        <p style = "color: red" v-if="msg">{{msg}}</p>
    </div>
    <!-- 生产环境版本,优化了尺寸和速度 -->
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        new Vue({
            el: "#app",
            data: {
                username: "",
                password: "",
                msg: false
            },
            methods: {
                login: function () {
                    let vm = this;
                    this.msg = false;
                    // alert("用户名:"+this.username+"\n密码:"+this.password)
                    //Content-Type:application/json, 请求数据为json字符串(body)
                    axios.post("login2",{
                        username: vm.username,
                        password: vm.password
                    }).then(function (resp) { // 200 状态码执行
                        // 获得响应体
                        // console.log(resp)
                        let json = resp.data;
                        if (json.ok) {
                            // 业务操作成功, 页面跳转
                            window.location.href="home.html";

                        } else {
                            // 业务操作失败, 显示错误信息
                            alert("错误码:" + json.code + "\n错误信息:" + json.msg);
                            vm.msg = json.msg;

                        }
                    }).catch(function (err) {
                        console.error(err)// 打印对象
                        console.error(JSON.stringify(err))
                    })
                }
            }
        })
    </script>
</body>
</html>

Login2Servlet.java

import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.demo.User;

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.io.InputStream;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

@WebServlet("/login2")
public class Login2Servlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Servlet 返回json字符串, 统一代码
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json");


        /**
         * 1. 解析请求数据
         *   (1) request.getParameter("键") 获取值
         *       queryString, body格式 和 queryString 一样
         *   (2) 请求头 Content-Type 为 application/json
         *       此时请求体 (body) 为json字符串
         *       request.getInputStream()获取属土流
         *       通过输入流来获取body数据
         */
        // 目前是 json 字符串作为请求体内容, 需要反序列化为 java对象
        ObjectMapper mapper = new ObjectMapper();
        // 通过 request 获取输入流(包含body数据)
        InputStream is = req.getInputStream();
        // 请求数据反序列化为java对象, 其实就是用户输入的数据
        User input = mapper.readValue(is, User.class);

        PrintWriter pw = resp.getWriter();
        Map<String, Object> map = new HashMap<>();

        // 2. 根据请求数据执行业务
        if ("abc".equals(input.getUsername()) && "123".equals(input.getPassword())) {
            // 业务操作成功, 有些接口需要返回业务数据
            map.put("ok", true);
        } else {
            // 业务操作失败, 返回错误码(开发人员), 错误信息(用户看)
            map.put("ok", false);
            map.put("code", "LOG001");
            map.put("msg", "用户名或密码错误");
        }

        // 3. 返回响应的业务数据
        pw.println(mapper.writeValueAsString(map));
    }
}
  • 17
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值