1. 程式人生 > >使用Servlet3.0新特性進行web開發小demo

使用Servlet3.0新特性進行web開發小demo

在上一篇文章中我們使用了SpringMVC結合Servlet3.0的新特性進行web開發。在這一篇文章中我們用最原始的Servlet的方式來進行一個簡單的web開發的工作。在我們之前的web開發中我們會在web.xml中進行Servlet、Filter、初始化引數等資訊的配置。在Servlet3.0中為我們提供了一個介面:javax.servlet.ServletContainerInitializer。我們可以在這個介面的實現類中進行Servlet、Filter等資訊的配置。它的作用和web.xml是很像,可以用來取代web.xml。和ServletContainerInitializer可能同時使用的還有一個javax.servlet.annotation.HandlesTypes註解,這個註解可以把指定的類和它的子類作為引數傳入到ServletContainerInitializer的onStartup方法中,可以讓我們進行一些其他的擴充套件功能。主要功能程式碼如下:

javax.servlet.annotation.HandlesTypes註解指定的類:

package com.zkn.servlet3.initializer;

import javax.servlet.ServletContext;

/**
 * Created by zkn on 2017/10/30.
 */
public interface WebApplicationContextInitializer {
    /**
     * 容器初始化的時候做一些其他動作
     *
     * @param servletContext
     */
    void onStartup(ServletContext servletContext);
}
package com.zkn.servlet3.initializer;

import javax.servlet.ServletContext;

/**
 * Created by zkn on 2017/10/30.
 */
public class ContextWebApplicationContextInitializer implements WebApplicationContextInitializer {
    /**
     * 容器初始化的時候做一些其他動作
     *
     * @param servletContext
     */
    @Override
    public void onStartup(ServletContext servletContext) {
        System.out.println("我是ContextWebApplicationContextInitializer");
    }
}
package com.zkn.servlet3.initializer;

import javax.servlet.ServletContext;

/**
 * Created by zkn on 2017/10/30.
 */
public class ServletWebApplicationContextInitializer implements WebApplicationContextInitializer {
    /**
     * 容器初始化的時候做一些其他動作
     *
     * @param servletContext
     */
    @Override
    public void onStartup(ServletContext servletContext) {
        System.out.println("我是ServletWebApplicationContextInitializer");
    }
}

實現javax.servlet.ServletContainerInitiali介面的類

package com.zkn.servlet3;

import com.zkn.servlet3.filter.DemoFilter;
import com.zkn.servlet3.initializer.WebApplicationContextInitializer;

import javax.servlet.*;
import javax.servlet.annotation.HandlesTypes;
import java.lang.reflect.Modifier;
import java.util.EnumSet;
import java.util.Set;

/**
 * Created by zkn on 2017/10/30.
 */
@HandlesTypes(WebApplicationContextInitializer.class)
public class StartServletContainerInitializer implements ServletContainerInitializer {

    @Override
    public void onStartup(Set<Class<?>> classSet, ServletContext servletContext) throws ServletException {
        if (classSet != null && !classSet.isEmpty()) {
            classSet.forEach(e -> {
                //不是介面,也不是抽象類
                if (!e.isInterface() && !Modifier.isAbstract(e.getModifiers()) &&
                        WebApplicationContextInitializer.class.isAssignableFrom(e)) {
                    try {
                        WebApplicationContextInitializer webApplication = (WebApplicationContextInitializer) e.newInstance();
                        webApplication.onStartup(servletContext);
                    } catch (InstantiationException e1) {
                        e1.printStackTrace();
                    } catch (IllegalAccessException e1) {
                        e1.printStackTrace();
                    }
                }
            });
        }
        //新增Servlet
        ServletRegistration.Dynamic dynamicServlet = servletContext.addServlet("demoServlet", new DemoStartServlet());
        //請求路徑
        dynamicServlet.addMapping("/demo");
        //Servlet InitParam
        dynamicServlet.setInitParameter("demo", "demo");
        dynamicServlet.setLoadOnStartup(1);
        //新增過濾器
        FilterRegistration.Dynamic dynamicFilter = servletContext.addFilter("filter", new DemoFilter());
        dynamicFilter.addMappingForServletNames(EnumSet.of(DispatcherType.REQUEST), true, "demoServlet");
    }
}
在ServletContainerInitializer 的實現類中我們指定了Servlet、Filter、並且指定了Servlet的啟動順序。

指定的Servlet如下:

package com.zkn.servlet3;

import com.alibaba.fastjson.JSON;

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;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * Created by zkn on 2017/10/30.
 */
public class DemoStartServlet extends HttpServlet {
    /**
     * 處理GET請求
     *
     * @param request
     * @param response
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        Enumeration<String> parameters = request.getParameterNames();
        String paramterName;
        List<String> parameterValue = new ArrayList<>();
        parameterValue.add("請求引數:");
        if (parameters != null) {
            while (parameters.hasMoreElements()) {
                paramterName = parameters.nextElement();
                parameterValue.add(paramterName + "=" + request.getParameter(paramterName) + ";");
            }
        }
        String resultString = JSON.toJSONString(parameterValue);
        try {
            PrintWriter printWriter = new PrintWriter(response.getOutputStream());
            printWriter.write(resultString);
            printWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        System.out.println("我是Servlet,我被初始化了、、、、、");
        super.init(config);
    }
}
指定的Filter如下:
package com.zkn.servlet3.filter;

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

/**
 * Created by zkn on 2017/10/30.
 */
public class DemoFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化過濾器!");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("執行一個過濾器!");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        System.out.println("銷燬過濾器!");
    }
}

但是現在我們縮寫的功能還不能生效呢,要想使它生效的話,我們還需要進行一些簡單的配置:在META-INF下面建立一個services的資料夾,在這個資料夾下面建立一個javax.servlet.ServletContainerInitializer檔案,這個檔案的內容如下:com.zkn.servlet3.StartServletContainerInitializer。內容就是我們縮寫的ServletContainerInitializer的實現類的類路徑。到此我們的一系列準備工作是完成了,下面我們在TomCat中啟動一下,一些啟動日誌如下所示:


從上面的日誌中我們可以看出來:HandlesTypes中所指定的類的先與過濾器被初始化,過濾器先與Servlet被初始化。還有一點需要注意的是,因為HandlesTypes所指定的類是做為StartServletContainerInitializer中的onStartup方法的引數的,但是這個引數的型別是set型別的,所以HandlesTypes指定的類的順序可能是亂的,如果我們想讓它們順序指定的話,我們還需要手動的指定一個初始化的順序。

下面讓我們寫一個請求來測試一下:

http://localhost:8080/demo?userName=%E5%BC%A0%E4%B8%89&address=wwwe2323


相關推薦

使用Servlet3.0特性進行web開發demo

在上一篇文章中我們使用了SpringMVC結合Servlet3.0的新特性進行web開發。在這一篇文章中我們用最原始的Servlet的方式來進行一個簡單的web開發的工作。在我們之前的web開發中我們會在web.xml中進行Servlet、Filter、初始化引數等資訊的配

servlet3.0特性測試,檔案上傳(1)

servlet程式碼 @MultipartConfig() @WebServlet(name = "test", urlPatterns = "*.do", initParams = { @WebInitPa

使用Servlet3.0特性asyncSupported=true時拋異常 java.lang.IllegalStateException: Not support...

http://www.tuicool.com/articles/zYfmme 最近在運用Servlet3.0新特性:非同步處理功能的時候出現以下了2個問題: 執行時會丟擲以下兩種異常: 一月 19, 2014 3:07:07 下午 org.apache.catalina.core

Servlet3.0特性】第03節_檔案上傳

完整版見https://jadyer.github.io/2013/06/24/servlet30-new-feature/ 這是一個Web Project 首先是web.xml <?xml version="1.0" encoding="UTF-8"?&

[Servlet3.0特性]Serlvet檔案上傳

Servlet 3.0的另一個新特性就是提供了處理檔案上傳的功能,使用Servlet 3.0的內容實現檔案上傳需要以下幾個內容: 在處理檔案上傳的Servlet上增加@MultipartConfig

Android O 8.0特性(四) 官方Demo

主要採用的google翻譯,不當之處,還望指正.Code Samples 程式碼示例Use the code samples below to learn about Android 8.0 (API level 26) capabilities and APIs. To d

Spark 2.0視頻|快學Spark 2.0(特性、含真實項目、純Scala語言開發、CDH5.7)

spark快學Spark 2.0(新特性、含真實項目、純Scala語言開發、CDH5.7)分享網盤下載——https://pan.baidu.com/s/1c2F9zO0 密碼: pzx9Spark進入2.0時代,引入了很多優秀特性,性能上有較大提升,API更易用。在“編程統一”方面非常驚艷,實現了離線計算和

Android8.0特性開發指南(轉載)

背景介紹谷歌2017 I/O開發者大會今年將於5月17-19日在美國加州舉辦。大會將跟往年一樣釋出最新的 Android 系統,今年為 Android 8.0。谷歌在今年3 月21日釋出 Android 新系統開發者預覽版時已給新系統取名為 Android O。自2008 年

Android 8.0特性開發指南

一、通知渠道 — Notification Channels 通知渠道是由應用自行定義的通知內容類別,藉助渠道,開發者可以讓使用者對不同種類的通知進行精細控制,使用者可以單獨攔截或更改每個渠道的行為,而不是統一管理應用的所有通知。 開發指南 建立通知渠道的步驟: 1、建立

Android O / Android 8.0 特性開發指南

谷歌2017 I/O開發者大會今年將於5月17-19日在美國加州舉辦。大會將跟往年一樣釋出最新的 Android 系統,今年為 Android 8.0。谷歌在今年3 月21日釋出 Android 新系統開發者預覽版時已給新系統取名為 Android O。自2008 年釋出

開發者必看|Android 8.0 特性開發指南

背景介紹 谷歌2017 I/O開發者大會今年將於5月17-19日在美國加州舉辦。大會將跟往年一樣釋出最新的 Android 系統,今年為 Android 8.0。谷歌在今年3 月21日釋出 Android 新系統開發者預覽版時已給新系統取名為 Android O。自2008

Android 8.0 特性開發指南

背景介紹 谷歌2017I/O開發者大會今年將於5月17-19日在美國加州舉辦。大會將跟往年一樣釋出最新的 Android 系統,今年為 Android 8.0。谷歌在今年3 月21日釋出 Android 新系統開發者預覽版時已給新系統取名為 Android O。自200

紅帽RedHat 8.0特性(網路、yum源、Web介面管理等)

1、Red Hat8 配置靜態IP 注意:Red Hat8網路管理預設使用NetworkManager,而不是之前版本的network。 按照之前版本我們一般通過配置檔案設定靜態IP地址資訊,如下: [root@localhost ~]# cd /etc/sysconfig/network-scripts

(六)Unity5.0特性------動畫功能

節點 拖動 eve 定義 -a ret del trees nts ??unity 5.0 中的新動畫功能這裏是你能夠期待的新動畫功能高速概述 !State Machine Behaviours狀態機行為在Unity 5 中,你會能夠將StateMachineBehavi

C#7.0特性

reat href code 轉載 支持 als 有用 sharp object類 轉載自:http://www.cnblogs.com/GuZhenYin/p/6526041.html 微軟昨天發布了新的VS 2017 ..隨之而來的還有很多很多東西... .NET新版

使用bottle進行web開發(1):hello world

matches 動態 bsp allow 模塊 開發 code spec converter 為什麽使用bottle?因為簡單,就一個py文件,和其他模塊沒有依賴,3000多行代碼。 http://www.bottlepy.org/docs/dev/ 既然開始學習

使用bottle進行web開發(5):Generating Content

方便 () strings 系統 end byte 導致 res 名稱 在純粹的 WSGI中,你的應用能返回的數據類型是十分有限的,你必須返回可叠代的字符串,你能返回字符串是因為字符串是可以叠代的,但是這導致服務器將你的內容按一字符一字符的傳送,這個時候,Unicode 字

使用bottle進行web開發(4):HTTPError

instead bject hat red uil tle ott class not from bottle import error @error(404) def error404(error): return ‘Nothing here, sorry‘

Servlet 2.0 && Servlet 3.0 特性

ack amp 特性 call all callback 如何 nbsp let 概念:透傳。 Callback 在異步線程中是如何使用的。?? Servlet 2.0 && Servlet 3.0 新特性 Servlet 2.0 &a

[Python] 利用Django進行Web開發

ons 條件 turn log har 包含 參數 ^c 檢測 第一步:下載並安裝django 首先,在Django官網上下載適合自己Python的Django版本,在安裝Django前首先確定你已成功安裝了python。 Windows系統下安裝Djang