1.什么是Servlet

Servlet是一个Java程序,是在服务器上运行以处理客户端请求并作出响应的程序

2.Servlet类的基本结构

Servlet是一个Java类。Servlet类继承HttpServlet基类,用于处理HTTP协议请求

public class HelloServlet extends HttpServlet {
    /**
     * 处理POST请求
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	//返回给客户端信息
        response.getWriter().println("This is a POST Method");
        //同理request可以获取客户端发来的信息
    }
    /**
     * 处理GET请求
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("This is a GET Method");
    }
}

HttpServlet源码地址:http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServlet.html

为什么response.getWriter().println("")一写中文就乱码?

在这里插入图片描述
我们可以这样解决问题,我们打开乱码页面,按F12找到Response Headers;然后我们再打开一个不乱码界面(随意哪个都可以),找到name下面的第一个文件,单击一下
在这里插入图片描述
在这里插入图片描述
这时候我们是不是就知道为什么乱码了?就是因为发出去的的Response Headers里面没有加入content-type,所以我们在response.getWriter().println("")上面加如下代码就解决了乱码

  //注意:如果我们在下面代码的前面就有response.getWriter().println(""),那依然会乱码
 response.setContentType("text/html;charset=utf-8");

为什么response.getWriter().println(“xxx”)里面不可以使用"\n"换行符?

这里我们刷新一下页面,看一下Response里里面的内容就知道原因了。
在这里插入图片描述

3.Servlet数据交互

3.1使用Servlet获取客户端发送的数据

客户端提交的所有数据保存在HttpServletRequest request里面
这时候我们测试一下获取客户端和本地的数据

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("This is a GET Method");
        String s;
        System.out.println("request.getHeaderNames():"+request.getHeaderNames());
        System.out.println("request.getHeader(\"User-Agent\"):"+request.getHeader("User-Agent"));
        System.out.println("request.getHeader(\"referer\"):"+request.getHeader("referer"));

        System.out.println("request.getContentLength():"+request.getContentLength());
        System.out.println("request.getContentType():"+request.getContentType());

        System.out.println("request.getLocalAddr():"+request.getLocalAddr());
        System.out.println("request.getRemoteAddr():"+request.getRemoteAddr());

        System.out.println("request.getLocalName():"+request.getLocalName());
        System.out.println("request.getRemoteHost():"+request.getRemoteHost());

        System.out.println("request.getLocalPort():"+request.getLocalPort());
        System.out.println("request.getRemotePort():"+request.getRemotePort());

        System.out.println("request.getRequestURI():"+request.getRequestURI());

        System.out.println("request.getContextPath():"+request.getContextPath());

        System.out.println("request.getMethod():"+request.getMethod());
    }

我们用手机测试一下localhost发送一个get请求(请求网页就是一个默认的get请求)
在这里插入图片描述
LOG:
Iphone 手机Safari

request.getHeaderNames():org.apache.tomcat.util.http.NamesEnumerator@135e7428
request.getHeader("User-Agent"):Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Mobile/15E148 Safari/604.1
request.getHeader("referer"):null
request.getContentLength():-1
request.getContentType():null
//本地服务器的IP
request.getLocalAddr():192.168.3.89
request.getRemoteAddr():192.168.3.74
//本地服务器的name
request.getLocalName():LAPTOP-1RDHOGCR
//我手机的ip地址
request.getRemoteHost():192.168.3.74
//8894是我本地服务器的端口
request.getLocalPort():8894
//显然是客户端的端口号,所以这是我手机的端口号
request.getRemotePort():64397
request.getRequestURI():/Hello-JSP/test
request.getContextPath():/Hello-JSP
request.getMethod():GET

Iphone 谷歌浏览器仿电脑登录(请求切换到桌面版网站)

request.getHeaderNames():org.apache.tomcat.util.http.NamesEnumerator@39660f9
request.getHeader("User-Agent"):Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/75.0.3770.85 Mobile/15E148 Safari/605.1
request.getHeader("referer"):null
request.getContentLength():-1
request.getContentType():null
request.getLocalAddr():192.168.3.89
request.getRemoteAddr():192.168.3.74
request.getLocalName():LAPTOP-1RDHOGCR
request.getRemoteHost():192.168.3.74
request.getLocalPort():8894
request.getRemotePort():64535
request.getRequestURI():/Hello-JSP/test
request.getContextPath():/Hello-JSP
request.getMethod():GET

Android 华为自带的浏览器登录

request.getHeaderNames():org.apache.tomcat.util.http.NamesEnumerator@1b7fc9d3
request.getHeader("User-Agent"):Mozilla/5.0 (Linux; U; Android 9;zh-cn; STF-AL00 Build/HUAWEISTF-AL00) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.1 Mobile Safari/537.36
request.getHeader("referer"):null
request.getContentLength():-1
request.getContentType():null
request.getLocalAddr():192.168.3.89
request.getRemoteAddr():192.168.3.2
request.getLocalName():LAPTOP-1RDHOGCR
request.getRemoteHost():192.168.3.2
request.getLocalPort():8894
request.getRemotePort():48470
request.getRequestURI():/Hello-JSP/test
request.getContextPath():/Hello-JSP
request.getMethod():GET

我们现在看一下这个request.getHeader(“referer”):null为什么三次都是null呢?

因为这个getHeader(“referer”):的意思是获取当前用户从哪个页面来的,也就是说如果直接访问服务器地址,是肯定为null的。但是从其他页面的链接点进来,就会有url地址,为了方便测试,我这里创建了一个连接,http://localhost:8080/Hello-JSP/test(项目端口为:8080;项目名称为"Hello-JSP";webServlet为:@WebServlet("/test")),当你们把服务开启,点我的连接进去,就会发现这个getHeader(“referer”)的值为:request.getHeader(“referer”):https://blog.csdn.net/qq_41966009/article/details/104902780

request.getHeader(“User-Agent”)代表着什么?

//Iphone 手机Safari
request.getHeader("User-Agent"):Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.4 Mobile/15E148 Safari/604.1

//Iphone 谷歌浏览器仿电脑登录(请求切换到桌面版网站)
request.getHeader("User-Agent"):Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/75.0.3770.85 Mobile/15E148 Safari/605.1

//Android 华为自带的浏览器登录
request.getHeader("User-Agent"):Mozilla/5.0 (Linux; U; Android 9;zh-cn; STF-AL00 Build/HUAWEISTF-AL00) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.1 Mobile Safari/537.36

所以综上所述我们很容易得到用户手机的类型;根据ip地址禁用其登录;了解用户访问了本网站的哪个页面。了解用户通过哪个页面访问此页面的

3.2使用Servlet获取客户端提交的数据

既然是提交数据,那就要用到POST请求,所以我们假设客户端向我们发来一个POST请求,包含了name和age字段,所以我们doPost里就要这样写

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("This is a POST Method");
        System.out.println("request.getHeader(\"User-Agent\"):"+request.getHeader("User-Agent"));
        System.out.println("request.getParameter(\"name\"):"+request.getParameter("name"));
        System.out.println("request.getParameter(\"age\"):"+request.getParameter("age"));
    }

这时候后端代码写好了,就需要利用到PostMan软件模拟发送POST请求了。
在这里插入图片描述
点击send后,可以看到log

request.getHeader("User-Agent"):PostmanRuntime/7.23.0-beta.1
request.getParameter("name"):谁都不许动我的砖
request.getParameter("age"):21

所以综上完成了使用Servlet获取客户端提交的数据

3.3使用Servlet获取客户端提交的多条数据(表单数据)

先看效果
在这里插入图片描述
在这里插入图片描述
首先页面进入register.html(源码如下)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>录入数据</title>
</head>
<body>
<h2>录入数据</h2>
<hr>
//表单提交地址为Servlet对应的URL地址,使用POST方法提交。我的项目名称为:Hello-JSP可以看下面截图
<form action="/Hello-JSP/register" method="post">
    <table>
        <tr>
            <td align="right">用户名:</td>
            <td><input type="text"  name="username" value="马克"></td>
        </tr>
        <tr>
            <td align="right">手机号码:</td>
            <td><input type="text"  name="cellphone" value="12354666"></td>
        </tr>
        <tr>
            <td align="right">年龄:</td>
            <td><input type="text" name="age" value="30"></td>
        </tr>
        <tr>
            <td align="right">备注:</td>
            <td><textarea cols="80" rows="7" name="remark" >是个好学生!</textarea></td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="提交"></td>
        </tr>
    </table>

</form>
</body>

</html>

将register.html复制到/web目录下,register.html位置如下
在这里插入图片描述
创建一个名称为RegisterServlet的servlet,使用@WebServlet()映射到URL地址。

package jee.servlets;

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("/register")
public class RegisterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        String cellphone=request.getParameter("cellphone");
        String username=request.getParameter("username");
        String ageStr=request.getParameter("age");
        int age=Integer.parseInt(ageStr);
        String remark=request.getParameter("remark");
        System.out.println(username+remark);
        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out=response.getWriter();
        out.append("<html>").append("<body>");
        out.append("用户名:"+username+"</br>")
                .append("手机号码"+cellphone+"</br>")
                .append("年龄:"+age+"</br>")
                .append("备注:"+remark+"</br>");
        out.append("</body></html>");
        out.flush();

    }
}

重新运行一下,就可以实现使用Servlet获取客户端提交的多条数据(表单数据)

3.4使用Servlet实现页面跳转

功能说明:演示用户系统登录功能的实现,当用户登录成功时,跳转到登录成功界面,否则跳转到登录失败界面。

效果图:
输入账号面名
在这里插入图片描述
输入正确的账号密码后登录跳转成功

在这里插入图片描述
输入错误的账号密码登陆失败
在这里插入图片描述
这里我们可以使用两种方法实现跳转

3.4.1响应重定向

什么是响应重定向?

HTTP协议规定的一种响应重定向机制。
响应重定向的流程:

1.客户端发送请求,Servlet做出业务逻辑处理。
2.Servlet调用response.sendReadirect()方法,把要访问的目标资源作为response响应头信息发给客户端浏览器。
3.客户端浏览器重新访问服务器资源xxx.jsp,服务器再次对客户端浏览器做出响应。
在这里插入图片描述

3.4.2请求转发

流程:

1.客户端发送请求,Servlet做出业务逻辑处理。
2.Servlet调用forword()方法,服务器Servlet把目标资源返回给客户端浏览器。

3.4.3响应重定向和请求转发区别
  • 浏览器地址栏url的区别
    在这里插入图片描述
  • 客户端发出的请求数量的区别
    在这里插入图片描述

小结一下:

请求转发无法让客户端知道真实地址,且只能访问本服务器内的地址(访问本服务器网页);

请求转发的 / 表示当前工程的根目录

重定向是让客户端更改地址,并且可以访问所有能访问的地址(只要你电脑能访问的地址)

重定向的 / 表示服务器根目录

以下我分别使用重定向和请求转发来跳转页面

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        System.out.println("进入了/Hello-JSP/login页面");
        String usename=request.getParameter("username");
        String password=request.getParameter("password");
        if (!usename.equals("")&&!password.equals("")) {
            if (usename.equals("admin")&&password.equals("123456")){
                System.out.println("登录成功");
                //请求转发------相对路径
                request.getRequestDispatcher("/success.html")
                        .forward(request,response);

//                response.sendRedirect("/Hello-JSP/success.html");
            }else {
                System.out.println("账号密码错误");
                //重定向
                response.sendRedirect("/Hello-JSP/fail.html");
            }
        }else {
            System.out.println("账号密码为空");
            response.sendRedirect("/Hello-JSP/fail.html");
        }

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
    @Override
    public void init() throws ServletException {
        System.out.println("Servlet"+this.getServletName()+"has started.");
        System.out.println("学号:2017030401姓名:谁都不许动我的砖Servlet初始化");
    }
    @Override
    public void destroy() {
        System.out.println("Servlet"+this.getServletName()+"has stopp   ed.");
        System.out.println("Servlet销毁");
    }
}

请求转发跳转后的成功登录界面
在这里插入图片描述
重定向跳转后的登录失败界面
在这里插入图片描述
相信大家很快就会发现其中的不同,失败界面有一个html后缀,说明此时是跳转到了fail.html界面,而成功登陆的界面并没有,这就充分形象的说明了响应重定向和请求转发的区别。

4.Servlet的生命周期

Android开发有生命周期的概念,Servlet也有,上代码测试

public class LoginServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("Servlet"+this.getServletName()+"has started.");
        System.out.println("学号:2017030401037 姓名:张意 Servlet初始化");
    }
    @Override
    public void destroy() {
        System.out.println("Servlet"+this.getServletName()+"has stopp   ed.");
        System.out.println("Servlet销毁");
    }
}

通过代码测试很容易的出来结论:Servlet在页面第一次访问该Servlet的时候被创建,在Servlet服务关闭的时候被销毁

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐