# RichServlet **Repository Path**: xiaohanfeidao/RichServlet ## Basic Information - **Project Name**: RichServlet - **Description**: RichServlet 是一款轻量级、性能高 httpServlet容器,实现了标准servlet协议 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 18 - **Created**: 2022-04-08 - **Last Updated**: 2022-04-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # RichServlet **借助于Netty强大的NIO高性能服务框架,RichServlet 来打造一款轻量级、性能高的HTTP与HTTP2 restful 服务器,同时实现了servlet标准协议,可以标准Servlet容器;做到插件可配制化,类似Jetty对开发者非常容易上手** ### RichServlet 功能特点 **1. 可以作为单独的HTTP与HTTP2 容器,实现了标准的http restful,实现了类似spring mvc 注解的功能特点** **2. 实现了servlet标准协议,可以标准Servlet容器,类似web项目中web.xml可配制化,简单而且性能高效,容易上手** **3. 使用了java classcloader加载隔离机制** ### RichServlet http-server代码例子 1. restful 例子 ``` @Controller public class Controller1 { @RequestMapping(value = "/contract/new", method = RequestMethodEnums.POST) public @ResponseBody HttpResult createNewContract( @RequestParam("tenantId") Long tenantId, @RequestParam("baseId") String baseId, @RequestParam("resourceType") Integer resourceType, @RequestParam("specs") String specs ) { return new HttpResult(); } @RequestMapping(value = "/contract/upgrade", method = RequestMethodEnums.POST) public @ResponseBody HttpResult createUpgradeContract( @RequestParam("tenantId") Long tenantId, @RequestParam("baseId") String baseId, @RequestParam("resourceId") Long resourceId, @RequestParam("specs") String specs) { return new HttpResult(); } @RequestMapping(value = "/contract/renew", method = RequestMethodEnums.POST) public @ResponseBody HttpResult createRenewContract( @RequestParam("tenantId") Long tenantId, @RequestParam("baseId") String baseId, @RequestParam("resourceId") Long resourceId, @RequestParam("specs") String specs) { return new HttpResult(); } @RequestMapping(value = "/contract/{tenantId}/{contractId}", method = RequestMethodEnums.DELETE) public @ResponseBody HttpResult cancelContract( @PathVariable(value = "contractId") Long contractId, @PathVariable(value = "tenantId") Long tenantId, @RequestParam(value = "baseId") String baseId ) { return new HttpResult(); } @RequestMapping(value = "/contract/{tenantId}/{contractId}", method = RequestMethodEnums.GET) public @ResponseBody HttpResult getContract( @PathVariable(value = "contractId") Long contractId, @PathVariable(value = "tenantId") Long tenantId ) { return new HttpResult(); } @RequestMapping(value = "/contract/{tenantId}", method = RequestMethodEnums.GET) public @ResponseBody HttpResult listContract( @PathVariable(value = "tenantId") Long tenantId, @RequestParam(value = "offset") Long offset, @RequestParam(value = "pageSize") Integer pageSize, @RequestParam(value = "orderStatus", required = false) Integer orderStatus ) { return new HttpResult(); } @RequestMapping(value = "/contractUnpay/{tenantId}", method = RequestMethodEnums.GET) public @ResponseBody HttpResult> listUnpayContract( @PathVariable(value = "tenantId") Long tenantId ) { return new HttpResult>(); } @RequestMapping(value = "/contractCount/{tenantId}", method = RequestMethodEnums.GET) public @ResponseBody HttpResult> getContractCount( @PathVariable(value = "tenantId") Long tenantId ) { return new HttpResult>(); } } ``` 2. http-server启动 ``` /** * */ package com.apache.rich.servlet.http.server; import com.apache.rich.servlet.http.server.RichServletHttpServer; import com.apache.rich.servlet.http.server.RichServletHttpServerProvider; import com.apache.rich.servlet.core.server.helper.RichServletServerOptions; import com.apache.rich.servlet.core.server.monitor.RichServletServerMonitor; /** * @author wanghailing * */ public class SimpleRichServletHttpServer { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { RichServletHttpServer richServletHttpServer=RichServletHttpServerProvider.getInstance().service(); // disable internal root path stats controller //richServletHttpServer.disableInternalController(); // disable stats monitor RichServletServerMonitor.disable(); // 2. choose http params. this is unnecessary richServletHttpServer.option(RichServletServerOptions.IO_THREADS, Runtime.getRuntime().availableProcessors()) .option(RichServletServerOptions.WORKER_THREADS, 128) .option(RichServletServerOptions.TCP_BACKLOG, 1024) .option(RichServletServerOptions.TCP_NODELAY, true) .option(RichServletServerOptions.TCP_TIMEOUT, 10000L) //.option(RichServletServerOptions.TCP_HOST,"127.0.0.1") .option(RichServletServerOptions.TCP_PORT,8080) .option(RichServletServerOptions.MAX_CONNETIONS, 4096); richServletHttpServer.scanHttpController("test.apache.rich.servlet.http.server.rest"); // 3. start http server if (!richServletHttpServer.start()){ System.err.println("HttpServer run failed"); } try { // join and wait here richServletHttpServer.join(); richServletHttpServer.shutdown(); } catch (InterruptedException ignored) { } } } ``` ### RichServlet httpservlet-server代码例子 1. servlet 代码 ``` import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet{ /** * */ private static final long serialVersionUID = 9177182925005765109L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("okdoGet:"+req.getParameterNames()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost"); super.doPost(req, resp); } } ``` 2. web.xml 配置 ``` testServlet com.apache.rich.servlet.server.servlet.TestServlet testServlet /testServlet ``` 3. server.properties 配置 ``` WORKER_THREADS=10 TCP_BACKLOG=1024 TCP_PORT=8080 MAX_CONNETIONS=1024 SUPPORT_TYPE=httpservlet WEBAPP_NAME=/ ``` 4. 脚本启动httpservlet-server ``` ./RichServletServer.sh ``` 5. httpservlet-server 代码 ``` /** * */ package com.apache.rich.servlet.server; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; import javax.servlet.Filter; import javax.servlet.http.HttpServlet; import com.alibaba.fastjson.JSONObject; import com.apache.rich.servlet.server.servlet.TestServlet; import com.apache.rich.servlet.server.classloader.RichServletClassloader; import com.apache.rich.servlet.http.servlet.server.RichServletHttpServletServerProvider; import com.apache.rich.servlet.http.servlet.realize.RichServletHttpServlet; import com.apache.rich.servlet.http.servlet.realize.configuration.RichServletHttpFilterConfiguration; import com.apache.rich.servlet.http.servlet.realize.configuration.RichServletHttpServletConfiguration; import com.apache.rich.servlet.http.servlet.realize.configuration.RichServletHttpWebappConfiguration; import com.apache.rich.servlet.http2.server.RichServletHttp2Server; import com.apache.rich.servlet.http2.server.RichServletHttp2ServerProvider; import com.apache.rich.servlet.core.server.helper.RichServletServerOptions; import com.apache.rich.servlet.core.server.monitor.RichServletServerMonitor; import com.apache.rich.servlet.http.server.RichServletHttpServer; import com.apache.rich.servlet.http.server.RichServletHttpServerProvider; import com.apache.rich.servlet.server.enums.RichServletServerEnums; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.apache.rich.servlet.common.enums.ErrorCodeEnums; import com.apache.rich.servlet.common.exception.HServerException; /** * @author wanghailing * */ public class NBRichServletServer { private static final Logger log = LoggerFactory.getLogger(NBRichServletServer.class); private RichServletServerBean richServletServerBean; public NBRichServletServer(){ try { richServletServerBean=loadClassFromXml(); } catch (Exception e) { log.error("loadClassFromXml error ",e); } } /** * 初始化 */ public void init() { try{ log.info("----NBRichServletServer init start-----"); doInit(); log.info("----NBRichServletServer init end-----"); }catch(HServerException e){ log.error("----NBRichServletServer init error-----",e); } } /** * 系统参数初始化 */ private void doInit() throws HServerException{ if(richServletServerBean!=null){ validateParameters(richServletServerBean); if(RichServletServerEnums.http.toString().equals(richServletServerBean.getSupportType())){ //纯 httpserver服务器 startHttpServer(); }else if(RichServletServerEnums.http2.toString().equals(richServletServerBean.getSupportType())){ // 纯 http2 server服务器 startHttp2Server(); }else if(RichServletServerEnums.httpservlet.toString().equals(richServletServerBean.getSupportType())){ // 纯 httpservlet server服务器 startHttpServletServer(); } }else{ throw new HServerException(ErrorCodeEnums.PARAMETER_ERROR.getErrorCode(),"richServletServerBean is null, parameters can not be null "); } } //启动 httpserver服务器 private void startHttpServer() throws HServerException{ RichServletHttpServer richServletHttpServer=RichServletHttpServerProvider.getInstance().service(); // disable internal root path stats controller richServletHttpServer.disableInternalController(); // disable stats monitor RichServletServerMonitor.disable(); // 2. choose http params. this is unnecessary richServletHttpServer.option(RichServletServerOptions.IO_THREADS, Runtime.getRuntime().availableProcessors()) .option(RichServletServerOptions.WORKER_THREADS, richServletServerBean.getWorkThreads()) .option(RichServletServerOptions.TCP_BACKLOG, richServletServerBean.getTcpBacklogs()) //.option(RichServletServerOptions.TCP_HOST,richServletServerBean.getServerHost()) .option(RichServletServerOptions.TCP_PORT,richServletServerBean.getServerPort()) .option(RichServletServerOptions.MAX_CONNETIONS, richServletServerBean.getMaxConnections()); richServletHttpServer.scanHttpController(richServletServerBean.getScanControllerPatch()); // 3. start http server if (!richServletHttpServer.start()){ //System.err.println("HttpServer run failed"); log.error("startHttpServer error"); } try { // join and wait here richServletHttpServer.join(); richServletHttpServer.shutdown(); } catch (InterruptedException ignored) { log.error("startHttpServer error",ignored); } } /** * 启动 http2server服务器 * @throws HServerException */ private void startHttp2Server() throws HServerException{ RichServletHttp2Server richServletHttp2Server=RichServletHttp2ServerProvider.getInstance().service(); // disable internal root path stats controller richServletHttp2Server.disableInternalController(); // disable stats monitor RichServletServerMonitor.disable(); richServletHttp2Server.option(RichServletServerOptions.IO_THREADS, Runtime.getRuntime().availableProcessors()) .option(RichServletServerOptions.WORKER_THREADS, richServletServerBean.getWorkThreads()) .option(RichServletServerOptions.TCP_BACKLOG, richServletServerBean.getTcpBacklogs()) //.option(RichServletServerOptions.TCP_HOST,richServletServerBean.getServerHost()) .option(RichServletServerOptions.TCP_PORT,richServletServerBean.getServerPort()) .option(RichServletServerOptions.MAX_CONNETIONS, richServletServerBean.getMaxConnections()); richServletHttp2Server.scanHttpController(richServletServerBean.getScanControllerPatch()); // 3. start http server if (!richServletHttp2Server.start()){ //System.err.println("HttpServer run failed"); log.error("startHttp2Server error"); } try { // join and wait here richServletHttp2Server.join(); richServletHttp2Server.shutdown(); } catch (InterruptedException ignored) { log.error("startHttp2Server error",ignored); } } /** * 启动 HttpServlet服务器 * @throws HServerException */ private void startHttpServletServer() throws HServerException{ RichServletHttpWebappConfiguration configuration=new RichServletHttpWebappConfiguration(); configuration.addServletConfigurations(new RichServletHttpServletConfiguration(TestServlet.class,"/testServlet")); if(richServletServerBean.getHttpServletBeans()!=null&&richServletServerBean.getHttpServletBeans().size()>0){ for(HttpServletBean httpServletBean:richServletServerBean.getHttpServletBeans()){ if(httpServletBean.getHttpServlet()!=null&&httpServletBean.getServletpath()!=null){ configuration.addServletConfigurations(new RichServletHttpServletConfiguration(httpServletBean.getHttpServlet(),httpServletBean.getServletpath())); } } } if(richServletServerBean.getHttpFilterBeans()!=null&&richServletServerBean.getHttpFilterBeans().size()>0){ for(HttpFilterBean httpFilterBean:richServletServerBean.getHttpFilterBeans() ){ if(httpFilterBean.getFilter()!=null&&httpFilterBean.getFilterpath()!=null){ configuration.addFilterConfigurations(new RichServletHttpFilterConfiguration(httpFilterBean.getFilter(),httpFilterBean.getFilterpath())); } } } RichServletHttpServlet servletHttpServlet=new RichServletHttpServlet(configuration,richServletServerBean.getWebpatch()); com.apache.rich.servlet.http.servlet.server.RichServletHttpServletServer httpServletServer=RichServletHttpServletServerProvider.getInstance().service(servletHttpServlet); //httpServletServer.disableInternalController(); // disable stats monitor RichServletServerMonitor.disable(); // 2. choose http params. this is unnecessary httpServletServer.option(RichServletServerOptions.IO_THREADS, Runtime.getRuntime().availableProcessors()) .option(RichServletServerOptions.WORKER_THREADS, richServletServerBean.getWorkThreads()) .option(RichServletServerOptions.TCP_BACKLOG, richServletServerBean.getTcpBacklogs()) //.option(RichServletServerOptions.TCP_HOST,richServletServerBean.getServerHost()) .option(RichServletServerOptions.TCP_PORT,richServletServerBean.getServerPort()) .option(RichServletServerOptions.MAX_CONNETIONS, richServletServerBean.getMaxConnections()); // 3. start http server if (!httpServletServer.start()){ log.error("startHttpServletServer error"); } try { // join and wait here httpServletServer.join(); httpServletServer.shutdown(); } catch (InterruptedException ignored) { ignored.printStackTrace(); log.error("startHttpServletServer error",ignored); } } /** * 参数验证 * @throws HServerException */ private void validateParameters(RichServletServerBean richServletServerBean) throws HServerException{ if(richServletServerBean.getSupportType()==null){ throw new HServerException(ErrorCodeEnums.PARAMETER_ERROR.getErrorCode(),"richServletServerBean.supportType is null, supportType can not be null "); } } /** * @return the richServletServerBean */ public RichServletServerBean getRichServletServerBean() { return richServletServerBean; } /** * @param richServletServerBean the richServletServerBean to set */ public void setRichServletServerBean(RichServletServerBean richServletServerBean) { this.richServletServerBean = richServletServerBean; } public RichServletServerBean loadClassFromXml() throws Exception{ RichServletClassloader richServletClassloader=new RichServletClassloader(NBRichServletServer.class); RichServletServerBean richServletServerBean=new RichServletServerBean(); Map mappings=richServletClassloader.getXmlParse().getServletmappings(); if(mappings!=null){ List httpServletBeans=new ArrayList(); for(String key:mappings.keySet()){ HttpServletBean httpServletBean=new HttpServletBean(); httpServletBean.setServletpath(key); String servletClass=richServletClassloader.getXmlParse().getServletClassByUrl(key); httpServletBean.setHttpServlet((Class)richServletClassloader.findClass(servletClass)); httpServletBeans.add(httpServletBean); } if(httpServletBeans!=null&&httpServletBeans.size()>0){ richServletServerBean.setHttpServletBeans(httpServletBeans); } } Map filterMappings=richServletClassloader.getXmlParse().getFiltermappings(); if(filterMappings!=null){ List httpFilterBeans=new ArrayList(); for(String key:filterMappings.keySet()){ HttpFilterBean httpFilterBean=new HttpFilterBean(); httpFilterBean.setFilterpath(key); String servletClass=richServletClassloader.getXmlParse().getServletClassByUrl(key); httpFilterBean.setFilter((Class)richServletClassloader.findClass(servletClass)); httpFilterBeans.add(httpFilterBean); } if(httpFilterBeans!=null&&httpFilterBeans.size()>0){ richServletServerBean.setHttpFilterBeans(httpFilterBeans); } } loadClassFromProperties(richServletServerBean); return richServletServerBean; } public void loadClassFromProperties(RichServletServerBean richServletServerBean)throws Exception{ Properties pps = new Properties(); String filePath=Thread.currentThread().getClass().getResource("/server.properties").getPath(); InputStream in = new BufferedInputStream(new FileInputStream(filePath)); pps.load(in); richServletServerBean.setWorkThreads(Integer.parseInt(pps.getProperty("WORKER_THREADS"))); richServletServerBean.setMaxConnections(Integer.parseInt(pps.getProperty("MAX_CONNETIONS"))); richServletServerBean.setIoThreads(richServletServerBean.getWorkThreads()); richServletServerBean.setServerPort(Integer.parseInt(pps.getProperty("TCP_PORT"))); richServletServerBean.setTcpBacklogs(Integer.parseInt(pps.getProperty("TCP_BACKLOG"))); richServletServerBean.setSupportType(pps.getProperty("SUPPORT_TYPE")); richServletServerBean.setWebpatch(pps.getProperty("WEBAPP_NAME")); } public static void main(String[] args) throws Exception { NBRichServletServer nbRichServletServer=new NBRichServletServer(); nbRichServletServer.doInit(); } } ```