Web开发 自定义Servlet(java)

1.实现servlet接口

每次请求该Servlet都会调用一次Servlet的service方法,对应的生命周期方法中还有初始化的init方法,销毁时的destroyed方法,默认情况下Servlet采用一种立即加载的方式,即在Servlet运行之前会把运行需要的资源全部加载完毕,即执行Servlet的初始化,然后才会开启Servlet,开始运行,运行期间,每次请求都会调用service方法进行处理,而Servlet一旦销毁则会执行destroy方法。

Servlet在web.xml中的配置:

<servlet>
    <servlet-name>mys</servlet-name>
    <servlet-class>com.mycat.web.MySecondServlet</servlet-class>
    <!--在Servlet中定义变量init-param关键字,可选-->
    <init-param>
        <param-name>tom</param-name>
        <param-value>123</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>mys</servlet-name>
    <url-pattern>/myser</url-pattern>
</servlet-mapping>

请求的发起者是index.jsp页面

当然这里采用HTML页面也可以,只需要把${pageContext.servletContext.contextPath}改成/项目名即可。

<%--
  Created by IntelliJ IDEA.
  User: mycat
  Date: 2019/2/22
  Time: 19:22
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <a href="${pageContext.servletContext.contextPath}/myser">去Mys</a>
  </body>
</html>

这里a标签链接请求的url ${pageContext.servletContext.contextPath}/myser即请求自定义的Servlet(com.mycat.web.MySecondServlet,映射地址是/myser),这个与web.xml中配置的url-pattern映射值对应。

请求自定义的MyFirstServlet:

package com.mycat.web;

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

/**
 * 自定义的Servlet必须实现Servlet接口
 */
public class MyFirstServlet implements Servlet {

    private ServletConfig servletConfig;
    private ServletRequest servletRequest;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        this.servletConfig=servletConfig;
        System.out.println("Servlet的初始化方法...");
    }

    @Override
    public ServletConfig getServletConfig() {

        return servletConfig;
    }

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

        System.out.println("service....运行时方法");

        System.out.println("获得Servlet的配置对象:"+this.getServletConfig());
        System.out.println("变量tom的值:"+servletConfig.getInitParameter("tom"));
        
        // 解决页面乱码,同时指定页面类型为HTML
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        
        PrintWriter writer = servletResponse.getWriter();
        writer.println("===============================");
        writer.println("<a href='myser2?username=2'>去myser2</a>");
    }

    @Override
    public String getServletInfo() {
        return servletRequest.getServletContext().getServerInfo();
    }

    @Override
    public void destroy() {
        System.out.println("Servlet的销毁方法...");
    }
}

上面分别对Servlet生命周期方法进行了测试,获得运行时Servlet的初始化参数(变量),响应回一个页面

运行结果

控制台

Servlet的初始化方法…
service…运行时方法
获得Servlet的配置对象:org.apache.catalina.core.StandardWrapperFacade@3367576
变量tom的值:123

页面

去Mys

=>(点击跳转到)

===============================?myser2

如上面所示,我从页面index.jsp跳到myser(Servlet)没有经过JSP或者HTML,直接跳到另一个myser2(Servlet),但是相对于myser,他的实现却有所不同 (继承自HttpServlet)。

2.继承自HttpServlet类

本身HttpServlet实际上是Servlet接口的实现类GenericServlet的子类,它的设计目的是为了更好地对Http通信的请求进行处理。

当然配置也是一样的:(直接给出整个web.xml,包括上面的Servlet定义)

<?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的接口的实现定义自己的Servlet-->
    <servlet>
        <servlet-name>mys</servlet-name>
        <servlet-class>com.mycat.web.MyFirstServlet</servlet-class>
        <init-param>
            <param-name>tom</param-name>
            <param-value>123</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>mys</servlet-name>
        <url-pattern>/myser</url-pattern>
    </servlet-mapping>

    <!--第二个自定义实现的Servlet,但是不同的是本次采用是继承自httpServlet的
    分别重写了HttpServlet的doPost和doGet方法,以及Servlet接口的service方法
    注意:HttpServlet是Servlet的实现类GenericServlet的子类-->
    <servlet>
        <servlet-name>mys2</servlet-name>
        <servlet-class>com.mycat.web.MySecondServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>mys2</servlet-name>
        <url-pattern>/myser2</url-pattern>
    </servlet-mapping>
</web-app>

当然也可以以注解的形式进行配置,这样就可以不用在web.xml中写配置文件了.

对于myser:只需在com.mycat.web.MyFirstServlet类上加上注解(initParams即初始化参数,value是默认的,即url-pattern的值)

@WebServlet(value = “/myser”,initParams = @WebInitParam(name=“tom”,value=“123”))

对于myser2:只需在com.mycat.web.MySecondServlet类上加上注解

@WebServlet( “/myser2”)

然后com.mycat.web.MySecondServlet实现:

这样写的话(注解配置的方式),web.xml中就需要将myser2的配置删除

package com.mycat.web;

import javax.jws.WebService;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(value = "/myser2")  
public class MySecondServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("执行post的实现...");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println("username:"+username);
        req.setAttribute("username", username);
        req.getRequestDispatcher("goal.jsp").forward(req, resp);
        System.out.println("执行get请求的实现...");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //加入不调用父类的service方法
        System.out.println("================ 重写的service方法 ================");
    }
}

现在点击刚刚页面的链接,即请求myser2:

结果显示

控制台:

Servlet的初始化方法…
service…运行时方法
获得Servlet的配置对象:org.apache.catalina.core.StandardWrapperFacade@3367576
变量tom的值:123
================ 重写的service方法 ================ //新增的(访问myser2的输出)

页面:(请求到的是http://localhost:8080/my/myser2?username=2)

页面是空的,也就是没有达到预期的HttpServlet设计的分请求类型处理(Get或者Post,对应doGet和doPost方法)。而且最重要的是没有调用doGet方法,跳转到goal.jsp目标页面。

结果分析

链接到myser2后,因为调用了重写的service方法,但是该重写方法没有调用父类的service方法,也就是说Servlet的配置没有传递给doGet或者doPost方法,结果很明显。也就不会调用doGet方法,因此处理方案是,在重写的service方法中调用父类的service方法,即super.sservice(req,resp).

修改service方法

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //加入不调用父类的service方法
    System.out.println("================ 重写的service方法 ================");
    super.service(req, resp);
}

结果显示

控制台:

Servlet的初始化方法…
service…运行时方法
获得Servlet的配置对象:org.apache.catalina.core.StandardWrapperFacade@3367576
变量tom的值:123
================ 重写的service方法 ================

username:2 // 新增的
执行get请求的实现…

页面:(因为前面传递的username为2)

欢迎2来到目标的JSP页面!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值