后端资源定位及有关servlet的应用

servlet:

什么是servlet?
Servlet是用来处理客户端请求并产生动态网页内容的Java类

  • 概念:Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
  • 定位:Java Servlet用Java编写的服务器端程序(web application)。
  • 作用:其主要功能在于交互式地浏览和修改数据,生成动态Web内容
  • 理解:狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,我们将Servlet理解为后者。

注意IDEA中web项目部署中tomcat的配置,配置成功后,使用debug方式启动tomcat,同时也可以使用一些抓包工具,例如谷歌浏览器自身的抓包工具(开发者工具),postman,fiddler等

servlet对象的生命周期:

在这里插入图片描述
tomcat和servlet的关系tomcat属于web服务器,也称为servlet容器

如何定位后端资源?

url查找过程?(假设要去北京某个银行的某个营业厅办理转账业务)

  • ip对应主机地址(对应北京)
  • port对应进程(对应某个楼)
  • 应用上下文路径对应项目(对应营业厅)
  • uri对应项目中的资源(对应营业厅中多个窗口提供的服务)

浏览器向web服务器发送请求,首先根据ip、端口号找到远程某一台主机上tomcat进程,根据应用上下文路径去访问某一个对应项目,再根据uri定位到项目中提供的某个资源,找到后向浏览器返回资源
在这里插入图片描述
服务端: 存在服务器(软件系统、提供服务的程序),如数据库服务器、web服务器
用途:提供服务功能(服务器不同提供的功能不同)

  • 数据库服务器:提供数据存储,数据处理操作的服务
  • web服务器:提供http服务

提供服务的方式:通过网络(可以远程、也可以是本机)
存在请求、处理、响应

uri映射资源:

1.静态资源文件

2.程序提供的资源(servlet的路径及http请求响应资源)

转发和重定向:

1. 重定向:返回3xx状态码+Location响应头,表示要跳转的路径,浏览器接收到响应数据后自动跳转

2 .转发:一次请求,后端接收直接把转发路径的资源作为响应体返回

区别:
1.看url路径是否改变:重定向会改变,转发不会

2.看网络发起请求的次数:重定向两次,转发一次

在这里插入图片描述

if ("abc".equals(u) && "123".equals(p)) {
     //发送重定向:http响应状态码设置为301/302/307/,响应头为Location
     resp.sendRedirect("home.html"); //返回当前请求的响应数据
} else if ("abc".equals(u)) {
     //转发
     req.getRequestDispatcher("home.html").forward(req,resp);
} 
  • 在登录页面输入账号密码,当账号密码都输入正确时进入重定向代码块发起两次请求,路径改变
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 当只是输入正确的账号时,进入转发代码块,发起一次请求,路径不改变
    在这里插入图片描述
    实现页面不跳转的刷新(home.html),刷新后隐藏登录框
    在这里插入图片描述

在这里插入图片描述

代码实现:

home.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>home</title>
    <script src="js/jquery@3.3.1/jquery.js"></script>
    <script>
        $(function () { //页面加载完成后开始执行
            $("#loginBtn").click(function () { //按钮绑定点击事件
                $.ajax({
                    type:"post",
                    url:"loginJSON",
                    dataType:"json", //响应体中的数据格式 json格式
                    data:{ //提交的请求数据
                        username:$("#username").val(),
                        password:$("#password").val(),
                    },
                    success(r) {
                        //alert(JSON.stringify(r))
                        if (r.success) { //如果成功就隐藏
                            $("#container").hide();
                        } else { //提示错误
                            alert("用户名或密码错误")
                        }
                    }
                })
            })
        });
    </script>
</head>
<body>
    <div id="container">
    <!--文本框 type="text"  name表示请求数据的键-->
    用户名: <input id="username" type="text" name="username"><br>
    密码: <input id="password" type="password" name="password"><br>
    <!--submit 提交按钮  button 普通按钮-->
    <input id="loginBtn" type="button" value="登录"><br>
    </div>
   <p>第一篇文章</p>
   <p>第二篇文章</p>
</body>
</html>

LoginJSONServlet:

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

//注解 后面一定要加上属性,属性名为value时可以不写
//小括号包裹多个属性,属性名=属性值,多个之间逗号间隔
//例如:@WebServlet(value={"",""},name="")
//Servlet定义服务:注意服务路径必须时 / 开头,否则tomcat启动会报错 -- 对应uri
@WebServlet("/loginJSON")
public class LoginJSONServlet extends HttpServlet {
    //重写方法  提供服务
    //注意get和post的区别

    /**
     * 每次http请求映射到某个Servlet的资源路径,都会调用service生命周期方法
     * 如果请求方法没有重写,就调用父类的doXX方法(对应的请求方法),返回405
     * 如果重写,会将请求数据包装为Request对象,这时候虽然还没有响应,但是也包装了一个Response响应对象
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应请求,响应编码及响应数据类型(为响应体设置Content-Type数据类型)
        req.setCharacterEncoding("UTF-8"); //设置请求体编码
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json"); //响应格式

        //解析请求数据
        //req.getParameter()方法获取请求数据:url和请求体,数据格式为k1=v1&k2=v2
        String u = req.getParameter("username");
        String p = req.getParameter("password");
        System.out.printf("===================用户名(%s)  密码(%s) %n",u,p);

        //返回响应数据
        PrintWriter pw = resp.getWriter(); //response获取io输出流
        if ("abc".equals(u) && "123".equals(p)) {
            pw.println("{\"success\":true}");

        } else {
            pw.println("{\"success\":false}");
        }
        pw.flush(); //有缓冲的io操作,需要刷新缓冲区,才会真正的发送数据  缓冲刷新
        pw.close(); //io流操作完,一定要记得关闭资源
    }
}



实现的页面结果

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

代码
Servlet:

Login301Servlet:

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

//注解 后面一定要加上属性,属性名为value时可以不写
//小括号包裹多个属性,属性名=属性值,多个之间逗号间隔
//例如:@WebServlet(value={"",""},name="")
//Servlet定义服务:注意服务路径必须时 / 开头,否则tomcat启动会报错 -- 对应uri
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    //重写方法  提供服务
    //注意get和post的区别

    /**
     * 每次http请求映射到某个Servlet的资源路径,都会调用service生命周期方法
     * 如果请求方法没有重写,就调用父类的doXX方法(对应的请求方法),返回405
     * 如果重写,会将请求数据包装为Request对象,这时候虽然还没有响应,但是也包装了一个Response响应对象
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应请求,响应编码及响应数据类型(为响应体设置Content-Type数据类型)
        req.setCharacterEncoding("UTF-8"); //设置请求体编码
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");

        //解析请求数据
        //req.getParameter()方法获取请求数据:url和请求体,数据格式为k1=v1&k2=v2
        String u = req.getParameter("username");
        String p = req.getParameter("password");
        System.out.printf("===================用户名(%s)  密码(%s) %n",u,p);

        //返回响应数据
        PrintWriter pw = resp.getWriter(); //response获取io输出流
        pw.println("登录成功");
        pw.println("<h3>欢迎您, " + u +"</h3>");
        pw.flush(); //有缓冲的io操作,需要刷新缓冲区,才会真正的发送数据  缓冲刷新
        pw.close(); //io流操作完,一定要记得关闭资源
        
    }
}

LoginServlet:

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

//注解 后面一定要加上属性,属性名为value时可以不写
//小括号包裹多个属性,属性名=属性值,多个之间逗号间隔
//例如:@WebServlet(value={"",""},name="")
//Servlet定义服务:注意服务路径必须时 / 开头,否则tomcat启动会报错 -- 对应uri
@WebServlet("/login301")
public class Login301Servlet extends HttpServlet {
    //重写方法  提供服务
    //注意get和post的区别

    /**
     * 每次http请求映射到某个Servlet的资源路径,都会调用service生命周期方法
     * 如果请求方法没有重写,就调用父类的doXX方法(对应的请求方法),返回405
     * 如果重写,会将请求数据包装为Request对象,这时候虽然还没有响应,但是也包装了一个Response响应对象
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应请求,响应编码及响应数据类型(为响应体设置Content-Type数据类型)
        req.setCharacterEncoding("UTF-8"); //设置请求体编码
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");

        //解析请求数据
        //req.getParameter()方法获取请求数据:url和请求体,数据格式为k1=v1&k2=v2
        String u = req.getParameter("username");
        String p = req.getParameter("password");
        System.out.printf("===================用户名(%s)  密码(%s) %n",u,p);

        if ("abc".equals(u) && "123".equals(p)) {
            //发送重定向:http响应状态码设置为301/302/307/,响应头为Location
            resp.sendRedirect("home.html"); //返回当前请求的响应数据

        } else if ("abc".equals(u)) {
            //转发
            req.getRequestDispatcher("home.html").forward(req,resp);
        } else {
            //返回响应数据
            PrintWriter pw = resp.getWriter(); //response获取io输出流
            pw.println("登录失败");
            pw.println("<h3>用户名: " + u +"或密码错误</h3>");
            pw.flush(); //有缓冲的io操作,需要刷新缓冲区,才会真正的发送数据  缓冲刷新
            pw.close(); //io流操作完,一定要记得关闭资源
        }
    }
}
HTML:

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
     <!--页面跳转-->
     <a href="login.html">注册/登录</a><br>
     <a href="home.html">跳转到主页</a><br>
     哈喽
</body>
</html>

login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
    <hr> <!--分割线-->
    请求login<br>
    <form method="post" action="login">
        <!--文本框 type="text"  name表示请求数据的键-->
        用户名: <input type="text" name="username"><br>
        密码: <input type="password" name="password"><br>
        <!--submit 提交按钮  button 普通按钮-->
        <input type="submit" value="登录"><br>
    </form>
    <hr>
    请求/login301<br>
    <form method="post" action="login301">
        <!--文本框 type="text"  name表示请求数据的键-->
        用户名: <input type="text" name="username"><br>
        密码: <input type="password" name="password"><br>
        <!--submit 提交按钮  button 普通按钮-->
        <input type="submit" value="登录"><br>
    </form>
    <hr>
</body>
</html>

Servlet依赖包配置:

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值