一:pom依赖
<!-- jetty --> <dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty</artifactId> <version>6.1.26</version> </dependency>
二:JettyContainer实现
public class JettyContainer { private static int port = 8080; private static final Logger logger = Logger.getLogger(JettyContainer.class); public static SelectChannelConnector connector; public static void start(int serverPort) { try { if(serverPort==0){ serverPort = port; } connector = new SelectChannelConnector(); connector.setPort(serverPort); ServletHandler handler = new ServletHandler(); ServletHolder pageHolder = handler.addServletWithMapping(GrpcServiceServlet.class, "/servicelist"); ServletHolder healthHolder = handler.addServletWithMapping(HealthServlet.class, "/health"); healthHolder.setInitOrder(3); pageHolder.setInitOrder(2); Server server = new Server(); server.addConnector(connector); server.addHandler(handler); server.start(); }catch (Exception e){ logger.error("Failed to start jetty server, cause:"+ e.getMessage(),e); } } public static class HealthServlet extends HttpServlet { public HealthServlet() {} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); response.setStatus(HttpServletResponse.SC_OK); response.getWriter().println(JSONObject.toJSONString(new Msg())); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } } @Getter @Setter public static class Msg { private String status = "UP"; } public static void stop() { try { if (connector != null) { connector.close(); connector = null; } } catch (Throwable e) { logger.error(e.getMessage(), e); } } }
三:Servlet
public class GrpcServiceServlet extends HttpServlet { private static GrpcServiceServlet INSTANCE; public static GrpcServiceServlet getInstance() { return INSTANCE; } @Override public void init() throws ServletException { super.init(); INSTANCE = this; } @Override protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (! response.isCommitted()) { String uri = request.getRequestURI(); if (uri == null || uri.length() == 0 || "/".equals(uri) || !"/servicelist".equals(uri)) response.sendError(HttpServletResponse.SC_NOT_FOUND); PrintWriter out=response.getWriter(); out.print(JSON.toJSON(GrpcServiceServletHandler.getServiceNameList())); } } }
四:ServletHandler
public class GrpcServiceServletHandler { private static final Logger logger = Logger.getLogger(GrpcServiceServletHandler.class); private static final Set<String> serviceNameList = new HashSet<>(); public static Set<String> getServiceNameList(){ return serviceNameList; } public static void getRegistryInterface(Server grpcServer){ try { /*if(null != grpcServer){ List<ServerServiceDefinition> services = grpcServer.getServices(); if(null != services && services.size()>0){ for(ServerServiceDefinition service:services){ serviceNameList.add(service.getServiceDescriptor().getName()); } } }*/ /*ImmutableMap<String, ServerMethodDefinition<?, ?>> map = getStaticField(grpcServer);*/ Map map = getStaticField(grpcServer); if(map!=null){ Set<String> keys = map.keySet(); if(keys != null && keys.size()>0){ for (String key:keys){ if(org.apache.commons.lang.StringUtils.isNotBlank(key) && key.indexOf("/")!=-1){ serviceNameList.add(key.split("/")[0]); } } } } }catch (Exception e){ logger.error("GrpcServiceServletHandler.getRegistryInterface error",e); } } /** * 获得类的静态属性值,不管是public或者private的都可以。 * @return 该类的静态属性值 */ private static Map/*ImmutableMap<String, ServerMethodDefinition<?, ?>>*/ getStaticField(Server grpcServer) { try { /*ImmutableMap<String, ServerMethodDefinition<?, ?>> map = null;*/ Map map = null; //现在是一个未知类型的对象(模拟一下) Object obj = grpcServer; //获取对象类型,可以看到输出是TestClass类型 Class c = obj.getClass(); //创建此类型的空对象 Field fu = Unsafe.class.getDeclaredField("theUnsafe"); fu.setAccessible(true); Unsafe us = (Unsafe) fu.get(null); Object newObj = us.allocateInstance(c); //获取所有成员(包括private)的值,并拷贝到新对象中 Field[] fields = c.getDeclaredFields(); for (Field f : fields) { //不拷贝static成员和final成员 if("registry".equals(f.getName())){ f.setAccessible(true); Object fieldValue = f.get(obj); f.set(newObj, fieldValue); Class innerClass = fieldValue.getClass(); Field[] innerFields = innerClass.getDeclaredFields(); for(Field inf : innerFields){ if("methods".equals(inf.getName())){ inf.setAccessible(true); /*map = (ImmutableMap<String, ServerMethodDefinition<?, ?>>)inf.get(fieldValue);*/ map = (Map)inf.get(fieldValue); } } break; } } //再看一下新对象里的内容,private成员也被复制过来了 return map; }catch (Exception e){ logger.error("GrpcServiceServletHandler.getStaticField error",e); } return null; } }
五:调用
public void jettyStart() { try { int port = 8080; JettyContainer.start(port); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { System.err.println("*** shutting down jettyContainer since JVM is shutting down"); JettyContainer.stop(); System.err.println("*** jettyContainer shut down"); } }); } catch (Exception e) { logger.error("Start jettyContainer error", e); } }