Java微服務框架之Undertow
一、Undertow簡介:
Undertow 是紅帽公司(RedHat)的開源產品,是 WildFly8(JBoos) 默認的 Web 服務器。
官網API給出一句話概述Undertow:
Undertow is a flexible performant web server written in java, providing both blocking and non-blocking API’s based on NIO.
譯文: Undertow是一個用java編寫的靈活的高性能Web服務器,提供基於NIO的阻塞和非阻塞API。
官網API總結特點:
Lightweight(輕量級)
Undertow非常輕量級,Undertow核心jar包在1Mb以下。 它在運行時也是輕量級的,有一個簡單的嵌入式服務器使用少於4Mb的堆空間
HTTP Upgrade Support(支持http升級)
支持HTTP升級,允許多個協議通過HTTP端口進行多路復用
Web Socket Support(支持WebScoket)
Undertow提供對Web Socket的全面支持,包括JSR-356支持
Servlet 3.1
Undertow提供對Servlet 3.1的支持,包括對嵌入式servlet的支持。 還可以在同一部署中混合Servlet和本機Undertow非阻塞處理程序
Embeddable(可嵌入的)
Undertow可以嵌入在應用程序中或獨立運行,只需幾行代碼
6. Flexible(靈活性)
Undertow框架jar包: undertow-core.jar undertow-servlet.jar
二、Undertow示例:
1.官網給出一個Undertow Web 服務器使用異步IO的方式向界面輸出字符串
1 import io.undertow.Undertow; 2 import io.undertow.server.HttpHandler; 3 import io.undertow.server.HttpServerExchange; 4 import io.undertow.util.Headers; 5 6 public class HelloWorldServer { 7 public static void main(String[] args) { 8 Undertow server=Undertow.builder() 9 .addHttpListener(8080, "localhost").setHandler(new HttpHandler(){//設置HttpHandler的回調方法 10 @Override 11 public void handleRequest(HttpServerExchange exchange) 12 throws Exception { 13 exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "text/plain"); 14 exchange.getResponseSender().send("This is my first insert server!"); 15 } 16 }).build(); 17 server.start(); 18 } 19 }
運行后打開瀏覽器輸入 http://localhost:8080 ,則頁面輸出“Hello World”字符串
2.Undertow來部署Servlet
1 import io.undertow.Handlers; 2 import io.undertow.Undertow; 3 import io.undertow.server.HttpHandler; 4 import io.undertow.server.handlers.PathHandler; 5 import io.undertow.servlet.Servlets; 6 import io.undertow.servlet.api.DeploymentInfo; 7 import io.undertow.servlet.api.DeploymentManager; 8 import io.undertow.servlet.api.ServletContainer; 9 import io.undertow.servlet.api.ServletInfo; 10 11 import javax.servlet.ServletException; 12 13 import org.wildfly.undertow.quickstart.servlet.MyServlet; 14 15 public class ServletServer { 16 17 public static void main(String[] args) { 18 19 /* 20 * 創建ServletInfo,Servelt的最小單位。是對javax.servlet.Servlet具體實現的再次封裝。 21 * 注意:ServletInfo的name必須是唯一的 22 */ 23 ServletInfo servletInfo1 = Servlets.servlet("MyServlet", 24 MyServlet.class); 25 // 創建servletInfo的初始化參數 26 servletInfo1.addInitParam("message", "This is my first MyServlet!"); 27 // 綁定映射為/myServlet 28 servletInfo1.addMapping("/myServlet"); 29 /** 30 * 創建包部署對象,包含多個servletInfo。可以認為是servletInfo的集合 31 */ 32 DeploymentInfo deploymentInfo1 = Servlets.deployment(); 33 // 指定ClassLoader 34 deploymentInfo1.setClassLoader(ServletServer.class.getClassLoader()); 35 // 應用上下文(必須與映射路徑一致,否則sessionId會出現問題,每次都會新建) 36 deploymentInfo1.setContextPath("/myapp"); 37 // 設置部署包名 38 deploymentInfo1.setDeploymentName("myServlet.war"); 39 // 添加servletInfo到部署對象中 40 deploymentInfo1.addServlets(servletInfo1); 41 /** 42 * 使用默認的servlet容器,並將部署添加至容器 43 * 容器,用來管理DeploymentInfo,一個容器可以添加多個DeploymentInfo 44 */ 45 ServletContainer container = Servlets.defaultContainer(); 46 /** 47 * 將部署添加至容器並生成對應的容器管理對象 48 * 包部署管理。是對添加到ServletContaint中DeploymentInfo的一個引用,用於運行發布和啟動容器 49 */ 50 DeploymentManager manager = container.addDeployment(deploymentInfo1); 51 // 實施部署 52 manager.deploy(); 53 /** 54 * 分發器:將用戶請求分發給對應的HttpHandler 55 */ 56 PathHandler pathHandler = Handlers.path(); 57 /** 58 * servlet path處理器,DeploymentManager啟動后返回的Servlet處理器。 59 */ 60 HttpHandler myApp=null; 61 try { 62 //啟動容器,生成請求處理器 63 myApp=manager.start(); 64 } catch (ServletException e) { 65 throw new RuntimeException("容器啟動失敗!"); 66 } 67 //綁定映射關系 68 pathHandler.addPrefixPath("/myapp", myApp); 69 70 Undertow server=Undertow.builder(). 71 //綁定端口號和主機 72 addHttpListener(8081, "localhost") 73 //設置分發處理器 74 .setHandler(pathHandler).build(); 75 //啟動server 76 server.start(); 77 } 78 }
自定義MyServlet
1 import java.io.IOException; 2 import java.io.PrintWriter; 3 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class MyServlet extends HttpServlet { 10 11 private static final long serialVersionUID = 2378494112650465478L; 12 13 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 14 doPost(req, resp); 15 } 16 17 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 18 PrintWriter writer = resp.getWriter(); 19 writer.write("<p style='color:red;text-align:center;'>"+this.getInitParameter("message")+"</p>"); 20 writer.close(); 21 } 22 23 }
如下圖,是本人抽象出Undertow生成應用的架構:
示例運行:
在瀏覽器地址欄里輸入:http://localhost:8081/myapp/myServlet,界面上會顯示ServletInfo的初始化參數message數據
Undertow jar包:點擊下載
Undertow 官網API地址:http://undertow.io/index.html