Servlet学习2

1. ServletConfig类

  ServletConfig类从类名上看,ServletConfig是Servlet程序的配置信息类。

  1.1 ServletConfig类的三大作用

  (1)可以获取Servlet程序的别名servlet-name的值。(2)获取初始化参数int-param。(3)获取Servlet Context对象。

  作用一:

  <servlet>
        <servlet-name>Servlet5</servlet-name>
        <servlet-class>com.example.web_02.Servlet4</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Servlet5</servlet-name>
        <url-pattern>/servlet5</url-pattern>
    </servlet-mapping>
复制代码
package com.example.web_02;

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

public class Servlet5 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("servlet5的别名是:"+servletConfig.getServletName());
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
复制代码

按照以上程序显然无法实现功能一(因为servlet-class中的全类名我没改),将4修改为5即可,运行结果如下:

 

   作用二:首先在xml中定义初始化变量

复制代码
 <servlet>
        <servlet-name>Servlet5</servlet-name>
        <servlet-class>com.example.web_02.Servlet5</servlet-class>
        <init-param>
            <!---->
            <param-name>username</param-name>
            <!---->
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/test</param-value>
        </init-param>
    </servlet>
复制代码
复制代码
package com.example.web_02;

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

public class Servlet5 implements Servlet {

    public Servlet5() {
        System.out.println("servlet5的构造方法被执行");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("servlet5的别名是:"+servletConfig.getServletName());
        System.out.println("初始化参数username的值是:"+servletConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值是:"+servletConfig.getInitParameter("url"));

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
复制代码

运行结果:

  

 

   

功能三:获取ServletContext对象。

  

复制代码
package com.example.web_02;

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

public class Servlet5 implements Servlet {

    public Servlet5() {
        System.out.println("servlet5的构造方法被执行");
    }

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("servlet5的别名是:"+servletConfig.getServletName());
        System.out.println("初始化参数username的值是:"+servletConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值是:"+servletConfig.getInitParameter("url"));
        System.out.println("ServletContext对象是:"+servletConfig.getServletContext());
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}
复制代码

运行结果:

  

 

 

2.  ServletConfig类的补充说明

  Servlet程序和ServletConfig对象都是由Tomcat负责创建,我们负责使用。Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象,ServletConfig对象封装了一些初始化配置信息。

  

复制代码
<servlet>
        <servlet-name>Servlet4</servlet-name>
        <servlet-class>com.example.web_02.Servlet4</servlet-class>
        <init-param>
            <!---->
            <param-name>username</param-name>
            <!---->
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/test</param-value>
        </init-param>
    </servlet>
复制代码
复制代码
package com.example.web_02;

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

public class Servlet4 extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletConfig servletConfig = getServletConfig();
        System.out.println("servlet4的别名是:"+servletConfig.getServletName());
        System.out.println("初始化参数username的值是:"+servletConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值是:"+servletConfig.getInitParameter("url"));
        System.out.println("ServletContext对象是:"+servletConfig.getServletContext());
    }

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

    }
}
复制代码

运行后结果:

  

 

3. ServletContext类

  3.1 ServletContext是一个接口,他表示Servlet上下文对象。

  3.2 一个web工程只有一个ServletContext对象实例。

  3.3 ServletContext对象是一个域对象。

  3.4 ServletContext是在web工程部署启动的时候创建,在web工程停止的时候销毁。

  域对象:是可以像Map一样存取数据的对象,叫域对象。这里的域是数据的存取范围,范围是整个web工程。Map存数据的操作是put(),ServletContext存数据的操作是setAttribute();Map取数据的操作是get(),ServletContext取数据的操作是getAttribute();Map存删除数据的操作是remove(),ServletContext删除数据的操作是removeAttribute();

  3.5 ServletContext类的四个常见作用

    作用一:获取web.xml中配置的上下文参数context-param。作用二:获取当前的工程路径,格式:/ 工程路径。作用三:获取工程部署后在服务器硬盘上的绝对路径。

 

复制代码
package com.example.web_02;

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

public class Servlet6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //作用一:获取web.xml中配置的上下文参数context-param
        ServletContext context = getServletConfig().getServletContext();
        System.out.println("context-param的参数user是"+context.getInitParameter("user"));
        System.out.println("context-param的参数password是"+context.getInitParameter("password"));
        //作用二:获取当前工程路径
        System.out.println("当前工程路径是:"+context.getContextPath());
        //作用三:获取工程部署后在服务器硬盘上的绝对路径。
        System.out.println("当前工程的绝对路径是:"+context.getRealPath("/"));
    }

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

    }
}
复制代码
复制代码
    <context-param>
        <param-name>user</param-name>
        <param-value>rensaihang</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>123456</param-value>
    </context-param>
<servlet>
        <servlet-name>Servlet6</servlet-name>
        <servlet-class>com.example.web_02.Servlet6</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Servlet6</servlet-name>
        <url-pattern>/servlet6</url-pattern>
    </servlet-mapping>
复制代码

 

   作用四:存取数据

  

复制代码
package com.example.web_02;

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

public class Servlet7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        ServletContext servletContext = getServletContext();
        System.out.println("servletContext域数据username的值是:"+servletContext.getAttribute("username"));
        servletContext.setAttribute("username","rensaihang");
        System.out.println("servletContext获取域数据username的值是:"+servletContext.getAttribute("username"));

    }


}
复制代码

运行结果:

 

 4. HTTP协议

  4.1 HTTP协议是指客户端和服务器通信时,发送的数据,须遵守的规则,叫HTTP协议。HTTP协议中的数据又叫报文。

  4.2 请求的HTTP协议格式

  客户端给服务器发送数据叫请求,服务器给客户端回传数据叫响应。请求又分为GET请求和POST请求两种。

  GET请求:请求行(请求的方式GET,请求的资源路径+?+请求参数,请求的协议版本号HTTP/1.1),请求头(key:value组成,不同的键值表示不同的含义。常用请求头:Accept(告诉服务器客户端可以接受的数据类型)、Accept-Language(告诉服务器客户端可以接收的语言类型)、User-Agent(就是浏览器的信息)、Accept-Encoding(告诉服务器客户端可以接收的数据编码、压缩格式)、Host(表示请求的服务器ip和端口号)、Connection(告诉服务器请求连接如何处理))。

  POST请求:请求行(),请求头(),空行,请求体。

  4.3 哪些是GET请求,哪些是POST请求

  GET请求:form标签 method=get、a标签、link标签、Script标签引入css、img标签引入图片、iframe引入html页面、在浏览器地址栏输入地址后回车。

  POST请求:form标签 method=post  

  4.4 响应的HTTP协议格式

    响应行(响应的协议和版本号、响应状态码、响应状态描述符),响应头(key:value组成,不同的键值表示不同的含义。),空行,响应体。常用状态码(200表示请求成功、302表示请求重定向、404表示服务器收到请求,但数据不存在,请求地址错误、500表示服务器已收到请求,但服务器内部错误,代码错误)

5. HttpServletRequest类

  5.1 HttpServletRequest类的作用

    每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(doGet和doPost)中给我们使用。我们可以通过HttpServletRequest对象,获取到所有请求的信息。

  5.2 HttpServletRequest类的常用方法

    getRequestURI(),getRequestURL(),getRemoteHost(),getHeader(),

  

复制代码
package com.example.web_03;

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

@WebServlet(name = "Servlet1", value = "/Servlet1")
public class Servlet1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //请求的资源路径
        System.out.println("URI->"+request.getRequestURI());
        System.out.println("----------------------------");
        //请求的统一资源定位符(绝对路径)
        System.out.println("URL->"+request.getRequestURL());
        System.out.println("----------------------------");
        //获取客户端的ip地址
        System.out.println("客户端ip地址->"+request.getRemoteHost());
        System.out.println("----------------------------");
        //获取请求头
        System.out.println("请求头User-Agent->"+request.getHeader("User-Agent"));
        System.out.println("----------------------------");
        //获取请求方式
        System.out.println("请求的方式:"+request.getMethod());
    }


}
复制代码

运行结果:

 

 getParameter(),getParameterValues(),getMethod()方法

    

复制代码
package com.example.web_03;

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

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //当请求参数为多值时,用getParameterValues()方法
        String []hobby = request.getParameterValues("hobby");
        String address = request.getParameter("address");

        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("爱好:"+Arrays.asList(hobby));
        System.out.println("住址:"+address);
    }

 
}
复制代码
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:8080/web_03/servlet2" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
        <input type="checkbox" name="hobby" value="java">Java
        <input type="checkbox" name="hobby" value="js">JavaScript <br>
        住址:<input type="checkbox" name="address" value="BeiJing">BeiJing
        <input type="checkbox" name="address" value="ShangHai">ShangHai
        <input type="checkbox" name="address" value="GuangZhou">GuangZhou <br>
        <input type="submit">&nbsp;&nbsp;<input type="reset">
    </form>
</body>
</html>
复制代码

运行结果:

 

   注意post请求的中文乱码问题:

  

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="http://localhost:8080/web_03/servlet2" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password"><br>
        兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
        <input type="checkbox" name="hobby" value="java">Java
        <input type="checkbox" name="hobby" value="js">JavaScript <br>
        住址:<input type="checkbox" name="address" value="BeiJing">BeiJing
        <input type="checkbox" name="address" value="ShangHai">ShangHai
        <input type="checkbox" name="address" value="GuangZhou">GuangZhou <br>
        <input type="submit">&nbsp;&nbsp;<input type="reset">
    </form>
</body>
</html>
复制代码
复制代码
package com.example.web_03;

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

public class Servlet2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //当请求参数为多值时,用getParameterValues()方法
        String []hobby = request.getParameterValues("hobby");
        String address = request.getParameter("address");

        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("爱好:"+Arrays.asList(hobby));
        System.out.println("住址:"+address);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        //设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题,必须在获取参数前调用才有效
        request.setCharacterEncoding("UTF-8");
        String password = request.getParameter("password");
        //当请求参数为多值时,用getParameterValues()方法
        String []hobby = request.getParameterValues("hobby");
        String address = request.getParameter("address");
        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("爱好:"+Arrays.asList(hobby));
        System.out.println("住址:"+address);
    }
}
复制代码

  5.4 请求转发

    相关方法setAttribute(key,value),getAttribute(key),getRequestDispatcher()获取请求转发对象

    请求转发:客户端(浏览器)通过http://ip:port/工程名/servlet1到Servlet1程序,Servlet1检查有没有带请求的参数,Servlet1处理完相应业务,加上标记,再寻找到Servlet2的路径,将请求传递到Servlet2,Servlet2程序获取请求的参数,检查有无Servlet1的标记,在处理自己的业务,然后经过Servlet1使用户收到最终的结果。

  

复制代码
package com.example.web_03;

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

public class Servlet3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        //获取请求参数
        String username = request.getParameter("username");
        System.out.println("在servlet3中的username:"+username);
        //Servlet1处理自己的业务
        System.out.println("Servlet3处理自己的业务");
        //Servlet1处理完自己的业务,加盖自己标记
        request.setAttribute("key3","servlet3的标记");
        //询问Servlet2的路径,传递请求到Servlet4
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet4");
        requestDispatcher.forward(request,response);
    }
}
复制代码
复制代码
package com.example.web_03;

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

public class Servlet4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        String username = request.getParameter("username");
        System.out.println("在Servlet4中username:"+username);
        Object key3 = request.getAttribute("key3");
        System.out.println("是否有标记"+key3);
        System.out.println("Servlet4处理自己的业务");
    }
}
复制代码

结果显示:

 

 请求转发的特点:浏览器地址栏没有变化,只是一次请求,共享Request与中的数据,可以转发到WEB-INF目录下,不可以访问工程以外的的资源。

6. base标签的作用

  base设置相对路径的工作地址。例:添加base设置相对路径的工作地址便都可跳转。

  工程路径:

 

   

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    这是web下的首页 <br>
    <a href="a/b/c.html">a/b/c.html</a>
    <a href="http://localhost:8080/web_03/servlet5">请求转发:a/b/c.html</a>
</body>
</html>
复制代码
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <base href="http://localhost:8080/web_03/a/b/">

</head>
<body>
<p>这是a下的b下的c.html</p>
<!- base设置相对路径工作室的参照地址->
<a href="../../index.html">跳转到index页面</a>
</body>
</html>
复制代码
复制代码
package com.example.web_03;

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

public class Servlet5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("经过了Servlet5程序");
        request.getRequestDispatcher("/a/b/c.html").forward(request,response);
    }

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

    }
}
复制代码

 

7. web中“/"的不同意义

  / 在浏览器中被解析为:http://ip:port/,例<a href="/">斜杠</a>

  / 在服务器中被解析为http://ip:port/工程路径,例:

  <url-pattern>/servlet1</url-pattern>,servletContext.getRealPath("/"),request.getRequestDispather("/")

  特殊情况:response.sendRedirect("/"):把斜杠发送给浏览器解析。得到:http://ip:port/

8.  HttpServletResponse类

  HttpServletResponse类和HttpServletRequest类一样。每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有相应信息。如果需要设置返回给客户端的信息,都可以通过HttpServletResponse对象来设置。

  HttpServletResponse对象通过两个输出流返回给客户端信息。两个流是字节流和字符流。字节流:getOutputStream(),常用于下载和传递二进制数据。字符流:getWriter()常用于回传字符串(常用)。注意:两个流同时只能使用一个。

  如何向客户端回传数据

  

复制代码
package com.example.web_03;

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

public class Servlet6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();
        writer.write("web_03");
    }

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

    }
}
复制代码

解决响应的中文乱码:

  两种方式选一种即可。

复制代码
package com.example.web_03;

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

public class Servlet6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //方式一
        //设置服务器字符集
        response.setCharacterEncoding("UTF-8");
        //通过响应头,设置浏览器的字符集
        response.setHeader("Content-Type","text/html;charset=UTF-8");
        //方式二
        //同时设置服务器和客户端的字符集
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.write("我真帅");
    }

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

    }
}
复制代码

9. 请求重定向

  浏览器访问服务器的Response1程序,此时Response1程序由于某种原因不再使用,并由Response2程序所取代。Response1程序须向客户端反馈响应状态码和Location响应头,新地址。客户端再通过新地址访问Response2程序,Response2响应信息。

复制代码
package com.example.web_03;

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

public class Response1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("response1的响应");
        //设置响应状态码,表示重定向
        response.setStatus(302);
        //设置响应头,说明新的响应地址
        response.setHeader("Location","http://localhost:8080/web_03/response2");
    }

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

    }
}
复制代码
复制代码
package com.example.web_03;

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

public class Response2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("response2的响应");
    }

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

    }
}
复制代码

 

  请求重定向的特点:浏览器地址栏会发生变化,两次请求,不共享Request域中的数据,不能访问WEB-INF下的资源,可以访问工程外的资源。

  请求重定向常用方式

复制代码
package com.example.web_03;

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

public class Response1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("response1的响应");
        //设置响应状态码,表示重定向
        //response.setStatus(302);
        //设置响应头,说明新的响应地址
        //response.setHeader("Location","http://localhost:8080/web_03/response2");
        response.sendRedirect("http://localhost:8080/web_03/response2");
    }

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

    }
}
复制代码

 

加上昨天的就是所学的Servlet全部知识内容了。

posted @   几人著眼到青衫  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示