javaWeb基础之Servlet

Posted 知道什么是码怪吗?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaWeb基础之Servlet相关的知识,希望对你有一定的参考价值。

运行环境

系统:windows

服务器:Tomcat 8.0.50

IDEA:2021.3版本

目录

什么是Servlet?

Servlet生命周期

post、get请求的分发处理

HTTP协议内容

Servlet继承体系

ServletConfig类的使用

ServletContext类的使用

HttpServletRequest类的使用

 HttpServletResponse类的使用

请求转发

请求重定向


什么是Servlet?

1.Servlet是javaEE规范之一。

2.Servlet是javaWeb三大组件之一。三大组件分别是:Servlet程序、Filter过滤器、Listener监听器。

3.Servlet是运行在服务器上的一个java程序,可以接收客户端发过来的请求,并响应数据给客户端。

Servlet生命周期

通过代码演示,不多做赘述。

servlet程序代码

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import java.io.IOException;

public class Servlet_001 extends HttpServlet 

    public Servlet_001() 
        System.out.println("1   构造器方法");
    

    @Override
    public void init(ServletConfig servletConfig) throws ServletException 
        System.out.println("2   init初始化");
    

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException 
        System.out.println("3   servlet服务");
    

    @Override
    public void destroy() 
        System.out.println("4   destroy销毁");
    

web.xml配置内容

<!--servlet标签给Tomcat配置Servlet程序-->
    <servlet>
        <servlet-name>Servlet_001</servlet-name><!--给servlet程序起一个别名(一般是类名)-->
        <servlet-class>Servlet_001</servlet-class><!--全类名-->
    </servlet>
    <!--给servlet程序配置访问地址-->
    <servlet-mapping>
        <servlet-name>Servlet_001</servlet-name><!--告诉服务器当前配置的地址给哪个servlet程序使用-->
        <url-pattern>/servlet</url-pattern><!--配置访问地址-->
    </servlet-mapping>

启动服务器输出结果                         

关闭服务器输出结果

post、get请求的分发处理

表单的提交有post和get两种方式,不同的提交方式需要编写不同的代码进行处理。

HTML表单代码

<form action="http://localhost:8080/WEBProject_war_exploded/servlet" method="post">
<input type="submit">
</form>

serlvet程序代码

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

public class Servlet_001 extends HttpServlet 

    protected void doGet()
        //编写具体的逻辑
        System.out.println("请求的方式:GET");
    

    protected void doPost() 
        //编写具体的逻辑
        System.out.println("请求的方式:POST");
    

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException 
        System.out.println("Servlet_001程序被访问");
        HttpServletRequest httpServletRequest=(HttpServletRequest) servletRequest;
        if(httpServletRequest.getMethod()=="GET")
            doGet();
        else
            doPost();
        
    

 这样就实现了根据请求方式的不同而实现不同的程序逻辑。

HTTP协议内容

 GET请求

POST请求

 响应HTTP协议

 常用的响应码

200        表示请求成功

302        表示请求重定向

404        表示服务器收到请求,但要的数据不存在,请求地址错误

500        表示服务器收到请求,但是服务器内部存在错误。

Servlet继承体系

ServletConfig类的使用

由Tomcat服务器创建,不同类之间的ServletConfig数据并不互通,只能获取当前类的数据。

ServletConfig类的三个作用:

1.可以获取Servlet程序的别名servlet-name,即获取xml配置文件中servlet-name对应的别名。

2.可以获取初始化参数init-param。

3.可以获取ServletContext对象。

修改web.xml配置内容

<servlet>
        <servlet-name>小猪佩奇</servlet-name><!--给servlet程序起一个别名(一般是类名)-->
        <servlet-class>Servlet_001</servlet-class><!--全类名-->
        <init-param>
            <param-name>number</param-name><!--参数名-->
            <param-value>66666</param-value><!--参数值-->
        </init-param>
    </servlet>
    <!--给servlet程序配置访问地址-->
    <servlet-mapping>
        <servlet-name>小猪佩奇</servlet-name><!--告诉服务器当前配置的地址给哪个servlet程序使用-->
        <url-pattern>/servlet</url-pattern><!--配置访问地址-->
    </servlet-mapping>

servlet程序代码

import javax.servlet.ServletConfig;
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 Servlet_001 extends HttpServlet 

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        //获取ServletConfig对象
        ServletConfig servletConfig = getServletConfig();
        //获取Servlet程序的别名servlet-name
        System.out.println("Servlet_001的别名:" + servletConfig.getServletName());
        //获取初始化参数init-param
        System.out.println("参数number对应的值:" + servletConfig.getInitParameter("number"));
        //获取ServletContext对象
        System.out.println("ServletContext对象:" + servletConfig.getServletContext());
    

输出结果

ServletContext类的使用

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

2.一个web工程只能有一个ServletContext对象实例。

3.ServletContext对象是一个域对象。(可以类似于Map一样存取数据,表示存取数据的范围)

4.ServletContext是在web工程部署启动的时候创建,在web工程停止的时候销毁,所以不同类之间数据可以互通。

ServletContext类的四个作用:

1.获取web.xml中配置的上下文参数context-param。

2.获取当前的工程路径。

3.获取工程部署后在服务器硬盘上的绝对路径。

4.像Map一样存储数据。

web.xml配置文件

<!--context-param上下文参数,属于整个web工程-->
    <context-param>
        <param-name>username</param-name>
        <param-value>小明</param-value>
    </context-param>

    <servlet>
        <servlet-name>Servlet_002</servlet-name>
        <servlet-class>Servlet_002</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Servlet_002</servlet-name>
        <url-pattern>/servlet2</url-pattern>
    </servlet-mapping>

servlet程序代码

import javax.servlet.ServletContext;
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 Servlet_002 extends HttpServlet 

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        // 获取ServletContext实例对象
        ServletContext servletContext = getServletContext();
        // 1.获取web.xml中配置的上下文参数context-param。
        System.out.println("context-param中username的值:" + servletContext.getInitParameter("username"));
        // 2.获取当前的工程路径。
        System.out.println("当前工程路径:" + servletContext.getContextPath());
        // 3.获取工程部署后在服务器硬盘上的绝对路径。
        System.out.println("工程部署在服务器硬盘上的绝对路径:" + servletContext.getRealPath("/"));
        // 4.像Map一样存储数据。
        servletContext.setAttribute("小红", "红红红");//在其它类当中也可以获取这组数据
        servletContext.setAttribute("小蓝", "蓝蓝蓝");
        System.out.println(servletContext.getAttribute("小红"));
        System.out.println(servletContext.getAttribute("小蓝"));
    

输出结果

HttpServletRequest类的使用

当请求进入Tomcat服务器后,Tomcat服务器将请求的HTTP协议信息解析好封装到Request对象中,然后传递到service方法(doGet和doPost)中供我们使用。我们可以通过HttpServletRequest类来获取请求的信息。HttpServletRequest类由服务器创建对象传递给Servlet程序。

HTML代码

<form action="http://localhost:8080/WEBProject_war_exploded/request3" method="get">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    爱好:<input type="checkbox" name="hobby" value="足球">足球<input type="checkbox" name="hobby" value="篮球">篮球
    <input type="checkbox" name="hobby" value="排球">排球<br/>
    国籍:
    <select name="country">
        <option>--请选择国籍--</option>
        <option selected="selected" value="中国">中国</option>
        <option value="日本">日本</option>
        <option value="韩国">韩国</option>
        <option value="美国">美国</option>
    </select>
    <input type="submit">
</form>

servlet程序代码

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 Request_003 extends HttpServlet 

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 

        //获取请求的资源路径
        System.out.println("资源路径:" + req.getRequestURI());
        //获取请求的统一资源定位符(绝对路径)
        System.out.println("统一资源定位符(绝对路径):" + req.getRequestURL());
        //获取客户端的IP地址,由于使用的localhost访问,所以得到的IP地址是127.0.0.1,如果使用真实的IP地址访问,获取的当然是真实的IP地址
        System.out.println("IP地址:" + req.getRemoteHost());
        //获取请求头
        System.out.println("请求头:" + req.getHeader("Accept"));//参数中写想要获取的请求头
        //获取请求的方式(GET 或 POST)
        System.out.println("请求的方式:" + req.getMethod());
        //获取客户端传输过来的参数
        System.out.println("username:" + req.getParameter("username"));
        System.out.println("password:" + req.getParameter("password"));
        System.out.println("country:" + req.getParameter("country"));
        String[] hobby = req.getParameterValues("hobby");
        for (String value : hobby) 
            System.out.print(value + "  ");
        

    

HTML页面内容

 服务端接收内容

由于我们使用的是get请求,并没有出现汉字编码问题,但是当我们修改请求的方式为post时,会出现汉字乱码。

这个时候我们需要设置编码方式,只需要在doPost中首先设置编码方式,然后再获取数据。

//使用Get获取请求不会出现字符编码问题,当使用Post获取信息的时候,中文会出现乱码
req.setCharacterEncoding("UTF-8");//设置编码方式为UTF-8,在获取请求参数之前先设置编码方式,后设置无效

 HttpServletResponse类的使用

和HttpSerlvetRequest类一样由服务器创建,供Servlet程序使用。HttpServletResponse表示所有响应的信息,可以通过这个类来设置返回给客户端的信息。

通过流的形式往客户端回传字符串数据,如果对javaIO流不太熟悉的话,可以看看下面这篇文章。

java I/O流基础(知识+代码示例)

servlet程序代码

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

public class Servlet_004 extends HttpServlet 

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        resp.setContentType("text/html;charset = utf-8");//传输中文的时候防止客户端中文出现乱码,设置编码方式
        PrintWriter writer = resp.getWriter();
        writer.write("这是服务端回传给客户端的数据。");
        writer.close();
    

网页显示结果

请求转发

服务器收到请求后,从当前资源跳转到另一个服务器资源的操作叫请求转发。

servlet4程序文件

import javax.servlet.RequestDispatcher;
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 Servlet_004 extends HttpServlet 

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        String value = req.getParameter("value");//获取值
        System.out.println("从Servlet_004中获取的value:" + value);
        req.setAttribute("key", value);
        //请求转发
        RequestDispatcher requestDispatcherToServlet5 = req.getRequestDispatcher("/servlet5");
        //跳转
        requestDispatcherToServlet5.forward(req, resp);
    

servlet5程序文件

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 Servlet_005 extends HttpServlet 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        System.out.println("从Servlet_005中获取的value:" + req.getAttribute("key"));
    

value值设置

输出结果

从输出结果可以看出执行完Servlet_004之后跳转到了Servlet_005,两个类都获取到了同一个值。

请求重定向

请求重定向是指客户端给服务器发送请求,服务器让客户端去新地址访问,而不是当前地址。之前的地址可能被废弃掉或者另有用途。

servlet4程序代码

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 Servlet_004 extends HttpServlet 

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        resp.getWriter().write("Servlet_004");
        //第一种方式
        //设置响应状态码,302表示重定向。在HTTP协议一栏末尾有响应状态码的介绍
        //resp.setStatus(302);
        //通过设置响应头来设置重定向的地址
        //resp.setHeader("Location", "http://localhost:8080/WEBProject_war_exploded/servlet5");

        //第二种方式
        resp.sendRedirect("http://localhost:8080/WEBProject_war_exploded/servlet5");
    

servlet5程序代码

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 Servlet_005 extends HttpServlet 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        resp.getWriter().write("Servlet_005");
    

显示结果

 这和之前的请求转发有什么区别?

1.请求次数:重定向是浏览器向服务器发送一个请求并收到响应后再次向一个新地址发出请求,转发是服务器收到请求后为了完成响应跳转到一个新的地址;重定向至少请求两次,转发请求一次;

2.地址栏不同:重定向地址栏会发生变化,转发地址栏不会发生变化;

3.是否共享数据:重定向两次请求不共享数据,转发一次请求共享数据(在request级别使用信息共享,使用重定向必然出错);

4.跳转限制:重定向可以跳转到任意URL,转发只能跳转本站点资源;

5.发生行为不同:重定向是客户端行为,转发是服务器端行为;

以上是关于javaWeb基础之Servlet的主要内容,如果未能解决你的问题,请参考以下文章

JavaWeb详解(第一篇)之Servlet基础简介

[Java拾遗三]JavaWeb基础之Servlet

javaWeb基础 之 servlet 过滤器理解

06-码蚁JavaWeb之Servlet生命周期与基本配置

javaweb学习总结二十三(servlet开发之线程安全问题)

JavaWeb详解(第二篇)之Servlet基础简介-会话技术介绍