一:pom依赖
<dependency> <groupId>org.mortbay.jettygroupId> <artifactId>jettyartifactId> <version>6.1.26version> 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 serviceNameList = new HashSet<>();
public static Set getServiceNameList(){
return serviceNameList;
}
public static void getRegistryInterface(Server grpcServer){
try {
/*if(null != grpcServer){
List services = grpcServer.getServices();
if(null != services && services.size()>0){
for(ServerServiceDefinition service:services){
serviceNameList.add(service.getServiceDescriptor().getName());
}
}
}*/
/*ImmutableMap> map = getStaticField(grpcServer);*/
Map map = getStaticField(grpcServer);
if(map!=null){
Set 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>*/ getStaticField(Server grpcServer) {
try {
/*ImmutableMap> 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>)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);
}
}