Javaweb94-99:JavaWeb(二)

Servlet接口实现类

新建module
Javaweb94-99:JavaWeb(二)
添加framework support

Javaweb94-99:JavaWeb(二)

写一个Servlet类

  • HttpServlet是一个抽象类,他的爸爸实现了Servlet接口
  • 抽象类作用:降低接口实现类对接口实现过程难度
  • 将接口中不需要使用抽象方法教给抽象类进行完成
  • 这样接口实现类只需要对接口需要的方法进行重写
  • Servlet接口有五个方法,其中只有一个对我们的类有帮助
  • oneServlet->(abstract)HttpServlet->(abstract)GenericServlet->servlet接口
  • 爷爷辈实现了四个方法,留了需要用的作为抽象方法
package com.example.ServletTest;

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


public class OneServlet extends HttpServlet {
    //请求方式有7种,我们只需要用get方法和post方法
    //这里需要重写

    //通过父类决定在何种情况下调用子类中方法-------【设计模式】---模板设计模式
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是Get方式");
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("这是Post方式");
        super.doPost(req, resp);
    }
}

Javaweb94-99:JavaWeb(二)

找到web.xml
为网站登录时的URL重命名

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--servlet接口实现类类路径地址交给Tomcat-->
    <servlet>
        <servlet-name>oneServlet</servlet-name>
        <servlet-class>com.example.ServletTest.OneServlet</servlet-class>
    </servlet>
    <!--设置别名-->
    <servlet-mapping>
        <servlet-name>oneServlet</servlet-name>
        <url-pattern>/one</url-pattern>
    </servlet-mapping>
</web-app>

此时将网站重命名为one
此时可以得知使用的get方法

Javaweb94-99:JavaWeb(二)
Javaweb94-99:JavaWeb(二)
Javaweb94-99:JavaWeb(二)

Servlet接口实现类

  • servlet接口来自于servlet规范下一个接口,这个接口存在http服务器提供jar包
  • Tomcat服务器下lib文件有一个servlet-api.jar存放servlet接口(javax.servlet.servlet接口)
  • servlet规范中任务,Http服务器能调用的【动态资源文件】必须是一个servlet接口实现类

添加Servlet对象,右键-New-Servlet
就不需要像上面一样手动写了
Javaweb94-99:JavaWeb(二)
注意Java EE 6+的勾要取消掉

此时再取别名
Javaweb94-99:JavaWeb(二)
我们比较两种情况

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.example.Servlet_Period.MyServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/Test</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>TwoServlet</servlet-name>
        <servlet-class>com.example.Servlet_Period.TwoServlet</servlet-class>
        <!--给一个大于零的数就可以了-->
        <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>TwoServlet</servlet-name>
        <url-pattern>/Test2</url-pattern>
    </servlet-mapping>
</web-app>

我们在建立TwoServlet的时候,采用的自启动方式

比较两种情况

package com.example.Servlet_Period;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("MyServlet Get Method");
    }

    public MyServlet() {
        System.out.println("MyServlet Create");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("MyServlet Post Method");
    }
}

package com.example.Servlet_Period;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

@WebServlet(name = "TwoServlet", value = "/TwoServlet")
public class TwoServlet extends HttpServlet {
    public TwoServlet() {
        System.out.println("TwoServlet create");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("TwoServlet Get Method");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("TwoServlet Post Method");
    }
}

Javaweb94-99:JavaWeb(二)

刚启动Tomcat时,就会创建TwoServlet
此时输入MyServlet的别名Test,将会创建MyServlet对象,调用Get方法
输入TwoServlet别名Test2,将不会会创建TwoServlet对象,因为之前已经创建了,不会再创新的,但还是会调用Get方法
Javaweb94-99:JavaWeb(二)

HttpServletResponse接口

  • HttpservletResponse接口实现类由Http服务器负责提供
  • HttpservletResponse接口负责将doGet/doPost方法执行结果写入到[【响应体】交给浏览器

习惯将该接口修饰的对象叫做【响应对象】

package com.example.ServletResponse;

public class OneServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet Creates");
        String result = "Yao Ming";//执行结果
        int money = 50;
        //通过响应对象获得输出流
        PrintWriter out = resp.getWriter();
        //通过二进制写入响应体中
        out.write(result);
        out.println();
        out.println(money);
        out.write(money);
    }
    //Tomcat把响应包推送给了浏览器
}

推送回去之后,我们可以看到,输出String对象正常
输出println正常,输出write里面给一个数字,那么会被当做asc码输出,所以之后还是用print比较稳妥
Javaweb94-99:JavaWeb(二)

再注意一点就是编码问题和HTML标记的使用
都要对ContentType进行设置

package com.example.ServletResponse;


public class ThreeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String result2 = "Java<br/>MySQL<br/>HTML<br/>";
        String result3 = "姚明";
        //response.setContentType("text/html");
        response.setContentType("text/html;charset=utf-8");
        //response.setCharacterEncoding("GB2312");也可以这样设置编码集
        PrintWriter out = response.getWriter();
        out.println(result2);
        out.println(result3);
    }
}

Javaweb94-99:JavaWeb(二)
浏览器在接收到响应包之后,如果发现响应头中存在location属性,自动通过地址栏向location指定网站发送请求

package com.example.ServletResponse;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class ThreeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //通过响应对象,将地址赋值给响应头中location属性

        String result2 = "http://www.baidu.com";
        //会链接到新的链接
        response.sendRedirect(result2);
    }
}

HttpServletRequest接口

HttpservletRequest接口负责在doGet/doPost方法运行时读取ttp请求协议包中信息

习惯将该接口修饰的对象叫做【请求对象】
作用:

  • 可以读取Http请求协议包中【请求行】信息
  • 可以读取保存在Http请求协议包中【请求头】或则【请求体】中请求参数信息
  • 可以代替浏览器向Http服务器申请资源文件调用

我们来看一个例子
读取【请求行】的相关信息

package com.example.ServletRequest;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class ServletRequestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过请求对象,读取【请求行】中的uri和url对象
        String uri = request.getRequestURI().toString();
        String url = request.getRequestURL().toString();
        //通过请求对象,读取【请求行】中的method对象
        String method = request.getMethod();
        System.out.println("URI:" + uri);
        System.out.println("Method:" + method);
        System.out.println("URL:" + url);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

URI:/Request/Test
Method:GET
URL:http://localhost:8080/Request/Test

我们再来看看如何获取请求对象
首先有一个MyServlet对象

package com.example.ServletRequest;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.Enumeration;

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过请求对象获得【请求头】中【所有请求参数名称】
        Enumeration<String> Paras = request.getParameterNames();
        while (Paras.hasMoreElements()) {
            String paraName = Paras.nextElement();
            System.out.println("ParameterName is  " + paraName);
            String value = request.getParameter(paraName);
            System.out.println("ParameterValue is  " + value);
        }
    }   
}

该对象重命名为Two了
再写一个Two.html的文件
Javaweb94-99:JavaWeb(二)
给一个超链接

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<center>
    <a href="/Request/Two?username=mike&password=333">通过超链接访问TwoServlet并携带请求参数</a>
</center>
</body>
</html>

超链接的位置就是URI,然后接一个问号,以及传username和password

此时点击超链接,可以得到参数

ParameterName is  username
ParameterValue is  mike
ParameterName is  password
ParameterValue is  333

比较GET和POST

浏览器以GET方式发送请求,请求参数保存在==【请求头】,在Http请求协议包到达Http服务器之后,第一件事就是进行解码请求头二进制内容由Tomcat负责解码,Tomcat默认使用【utf-8】字符集,可以解释一切国家文字
浏览器以POST方式发送请求,请求参数保存在
【请求体】==,在Http请求协议包到达Http服务器之后,第一件事就是进行解码请求体二进制内容由当前请求对象(request)负责解码。request默认使用[ISO-8859-1]字符集,一个东欧语系字符集此时如果请求体参数内容是中文,将无法解码只能得到乱码

在Post请求方式下,在读取请求体内容之前,应该通知请求对象使用utf-8字符集对请求体内容进行一次重新解码

新建一个Three.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="Request/Two" method="get">
    请求参数<input type="text" name="username"></br>
    <input type="submit" value="get方式访问">
</form>

<form action="Request/Two" method="post">
    请求参数<input type="text" name="username"></br>
    <input type="submit" value="post方式访问">
</form>
</body>
</html>

这里设置好了两种请求方式

Javaweb94-99:JavaWeb(二)
不解码的话就会是这样
所以必须解码
完整如下

package com.example.ServletRequest;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.Enumeration;

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过请求对象获得【请求头】中【所有请求参数名称】
        Enumeration<String> Paras = request.getParameterNames();
        while (Paras.hasMoreElements()) {
            String paraName = Paras.nextElement();
            System.out.println("ParameterName is  " + paraName);
            String value = request.getParameter(paraName);
            System.out.println("ParameterValue is  " + value);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //解码的语句一定要写
        request.setCharacterEncoding("utf-8");
        Enumeration<String> Paras = request.getParameterNames();
        while (Paras.hasMoreElements()) {
            String paraName = Paras.nextElement();
            System.out.println("ParameterName is  " + paraName);
            String value = request.getParameter(paraName);
            System.out.println("ParameterValue is  " + value);
        }
    }
}

请求对象和响应对象生命周期

  • 在Http服务器接收到浏览器发送的【Http请求协议包】之后,
    自动为当前的【Http请求协议包】生成一个【请求对象】和一个【响应对象】
  • 在Http服务器调用docet/doPost方法时,负责将【请求对象】和【响应对象】作为实参传递到方法,确保doGet/doPost正确执行
  • 在Http服务器准备推送Http响应协议包之前,负责将本次请求关联的【请求对象】和【响应对象】销毁卸磨杀驴

结束时间:2021-06-30

上一篇:TernaryOperatorExercise


下一篇:CSDN最强软件测试需求分析与用例设计-等价类/边界值(送思维导图)