自学内容网 自学内容网

Servlet

一、servlet概述

Servlet是运行在Web服务器端的Java应用程序,它使用Java语言编写。与Java程序的区别是,Servlet 对象主要封装了对HTTP请求的处理,并且它的运行需要Servlet容器的支持。

Servlet容器

Servlet由Servlet容器提供,Servlet容器是指提供了Servlet 功能的服务器(使用Tomcat)。Servlet容器将Servlet动态地加载到服务器上。与HTTP 协议相关的Servlet使用HTTP请求和HTTP响应与客户端进行交互。因此,Servlet容器支持所有HTTP协议的请求和响应。

二、servlet接口

针对Servlet技术的开发,SUN公司提供了一系列接口和类,其中最重要的是javax.servlet.Servlet接口。Servlet就是一种实现了Servlet接口的类,它由Web容器负责创建并调用,用于接收和响应用户的请求。

2.1 servlet接口的方法

Servlet接口中有5个方法中,其中init()、service()和destroy()这三个方法可以表现Servlet的生命周期,它们会在某个特定的时刻被调用。需要注意的是,Servlet容器指的就是Web服务器。

剩下的两个方法,ServletConfig getServletConfig() 是用于获取Servlet对象的配置信息,返回Servlet的ServletConfig对象。String getServletInfo() 是用于返回一个字符串,其中包含关于Servlet的信息。

2.2 servlet 接口的实现类

servlet接口的实现类有两个,分别是GenericServlet和HttpServlet。

GenericServlet是一个抽象类,提供了部分实现,并没有实现HTTP请求处理。HttpServlet是GenericServlet的子类,它继承了GenericServlet的所有方法,并且为HTTP请求中的POST、GET等类型提供了具体的操作方法。

因此,我们在使用的时候一般直接继承HttpServlet

2.3 第一个Servlet

创建一个Web工程项目,添加servlet相关的jar包。servlet有两种方式配置方式,一种是配置xml文件,一种是利用@WebServlet注解。

配置文件方式

在Web目录下的WEB-INF中的web.xml进行配置。

    <servlet>
        <servlet-name>ServletDemo1</servlet-name>
        <servlet-class>com.wyy.Serv.ServletDemo1</servlet-class>
    </servlet>
<!--映射路径-->
    <servlet-mapping>
        <servlet-name>ServletDemo1</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

查找步骤 

两个servlet-name一定要相同。 

@WebServlet注解属性

使用:在对应的类上添加@WebServlet("填写路径")注解。填写的路径不是固定的,可自己命名。

@WebServlet("name = "HelloServlet",urlPatterns = "/HelloServlet"")
<!--这里的name等价于<servlet-name> urlPatterns指的映射路径-->
public class Servlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        super.doGet(request,response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().write("Hello World");
    }
}

 2.4 servlet生命周期

注意,在Servlet的整个生命周期内,它的init()方法只被调用一次,如果servlet已被创建,就不会再执行init()方法。对于Servlet的每一次访问请求,Servlet容器都会调用一次Servlet的service()方法,并且创建新的ServletRequest和ServletResponse对象,也就是说,service()方法在Servlet的整个生命周期中会被调用多次。

@WebServlet("/servletDemo03")
public class live extends HttpServlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("初始化...");
    }

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

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        servletResponse.setContentType("text/html;charset=utf-8");
        PrintWriter out = servletResponse.getWriter();
        System.out.println("Hello Servlet");
        System.out.println("执行中...");
    }

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

    @Override
    public void destroy() {
        System.out.println("被摧毁..");
    }

启动Tomcat服务器, 控制台信息打印。

停止服务器才servlet容器才会被摧毁。

三、ServletContext接口

当Servlet容器启动时,会为每个Web应用创建一个唯一的ServletContext对象代表当前Web应用。ServletContext对象不仅封装了当前Web应用的所有信息,而且实现了多个Servlet之间数据的共享。

ServletContext接口中定义了用于增加、删除、设置ServletContext域属性的四个方法。

3.1 设置域对象并获取

demoServlet03类中设置域对象

@WebServlet("/demoServlet03")
public class demo03GetServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取servletContext对象
        ServletContext servletContext = this.getServletContext();
        //设置域对象属性
        servletContext.setAttribute("name","zhanSan");
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPut(req, resp);
    }
}

demoServlet04 中获取域对象

@WebServlet("/demoServlet04")
public class demo04GetServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取servletContext对象
        ServletContext servletContext = this.getServletContext();
        //获取域对象属性
        Object name = servletContext.getAttribute("name");
        System.out.println(name);
    }
    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPut(req, resp);
    }
}

 再tomcat中启用时,要先访问demoServlet03,让对象存放进去,再访问demoServlet04去获取,否则访问不到。

控制台输出

四、HttpServletResponse对象

4.1 发送状态码

当Servlet向客户端回送响应消息时,需要在响应消息中设置状态码,状态码代表着客户端请求服务器的结果。为此,HttpServletResponse接口定义了3个发送状态码的方法。

  • setStatus(int status)方法用于设置HTTP响应消息的状态码,并生成响应状态行。
  • sendError(int sc)方法用于发送表示错误信息的状态码
  • sendError(int code, String message)方法除了设置状态码,还会向客户端发出一条错误信息。

4.2 发送Http响应头方法

设置各种头字段

  • addHeader(String name, String value):设置HTTP协议的响应头字段,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。增加同名的响应头字段
  • setHeader(String name, String value):设置HTTP协议的响应头字段,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。覆盖同名的头字段
  • addIntHeader(String name, int value):设置包含整数值的响应头。
  • setIntHeader(String name, int value):设置包含整数值的响应头。

设置字符编码

  • setContetType():设置Servlet输出内容的MIME类型,对于HTTP协议来说,就是设置Content-Type响应头字段的值。
  • setLoacale():设置响应消息的本地化信息
  • setCharacterEncoding():设置输出内容使用的字符编码,对HTTP 协议来说,就是设置Content-Type头字段中的字符集编码部分。

4.3 发送响应体方法

getWriter()对应字符流输出对象

@WebServlet("/servletDemo02")
public class demo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.write("Hello World!");
    }
}

 

getOutputStream()对应字节输出流对象

@WebServlet("/servletDemo02")
public class demo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletOutputStream outputStream = resp.getOutputStream();
        String str = "你好,世界!";
//        str是字符,要先转变为字节,再可以输出
        outputStream.write(str.getBytes());
        outputStream.print("\n" + str);
    }
}

 

4.4 重定向

 在某些情况下,针对客户端的请求,一个Servlet类可能无法完成全部工作。这时,可以使用请求重定向来完成。所谓请求重定向,指的是Web服务器接收到客户端的请求后,可能由于某些条件限制,不能访问当前请求URL所指向的Web资源,而是指定了一个新的资源路径,让客户端重新发送请求。

为了实现请求重定向,HttpServletResponse接口定义了一个sendRedirect()方法,该方法用于生成302响应码和Location响应头,从而通知客户端重新访问Location响应头中指定的URL。

登录案例测试重定向

准备三个页面

登录页面

注意这里的表单提交,要和下面的servlet类中的注解配置路径一样,否则无法访问。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/loginServlet" method="get">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <button type="submit">登录</button>
</form>
</body>
</html>

成功页面 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录成功</h1>
</body>
</html>

失败页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>用户名或密码错误</h1>
</body>
</html>

 创建一个servlet类

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        if ("admin".equals(username) && "123456".equals(password)){
            resp.sendRedirect("success.html");
        }else{
            resp.sendRedirect("faile.html");
        }
    }
    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPut(req, resp);
    }
}

登录成功

登录失败

五、HttpServletRequest接口

getRequestDispatcher()方法返回封装了某条路径所指定资源的RequestDispatcher对象。其中,参数 path 必须以“/”开头,用于表示当前 Web 应用的根目录。需要注意的是,WEB-INF目录中的内容对RequestDispatcher对象也是可见的。因此,传递给 getRequestDispatcher(String path) 方法的资源可以是 WEB-INF 目录中的文件。

forward()方法用于将请求从一个 Servlet 传递给另一个 Web 资源。在 Servlet 中,可以对请求做一个初步处理,然后通过调用forward()方法,将请求传递给其他资源进行响应。需要注意的是,该方法必须在响应提交给客户端之前被调用,否则将抛出 IllegalStateException 异常。

演示

在WEB-INF目录中创建一个forward.html页面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>请求转发成功</h1>
</body>
</html>

 servlet类

@WebServlet("/forwardServlet")
public class ForwardServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/forward.html");
        requestDispatcher.forward(req,resp);
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPut(req, resp);
    }
}

 

成功,说明可以访问到WEB-INF目录并且请求转发成功。


原文地址:https://blog.csdn.net/2301_80768157/article/details/143519090

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!