一个SpringBoot框架搭建起来的项目发布接口服务是这样的
SpringBoot搭建教程点击这里
@Controller @RequestMapping("/v1/product") public class DocController { @RequestMapping(value = "/{id}", method = RequestMethod.GET) @ResponseBody public WebResult search(@PathVariable("id") Integer id) { logger.debug("获取指定产品接收产品id=>%d", id); if (id == null || "".equals(id)) { logger.debug("产品id不能为空"); return WebResult.error(ERRORDetail.RC_0101001); } return WebResult.success(products.get(id)); } }
我希望我使用Netty构建的Web服务器也能使用这样便捷的注解方式去发布我的接口服务
public class HttpPipelineInitializer extends ChannelInitializer<Channel> { //编解码处理器名称 public final static String CODEC = "codec"; //HTTP消息聚合处理器名称 public final static String AGGEGATOR = "aggegator"; //HTTP消息压缩处理器名称 public final static String COMPRESSOR = "compressor"; @Override protected void initChannel(Channel channel) throws Exception { ChannelPipeline pipeline = channel.pipeline(); pipeline.addLast(CODEC, new HttpServerCodec()); pipeline.addLast(AGGEGATOR, new HttpObjectAggregator(512 * 1024)); pipeline.addLast(COMPRESSOR,new HttpContentCompressor()); pipeline.addLast(new AllocHandler()); } }
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Controller { } @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMapping { String[] value() default {}; }
/** * 包扫描工具 * @param iPackage 根级包名 * @param iWhat 处理回调 */ public static void scanPackage(String iPackage, IWhat iWhat) { String path = iPackage.replace(".", "/"); URL url = Thread.currentThread().getContextClassLoader().getResource(path); try { if (url != null && url.toString().startsWith("file")) { String filePath = URLDecoder.decode(url.getFile(), "utf-8"); File dir = new File(filePath); List<File> fileList = new ArrayList<File>(); fetchFileList(dir, fileList); for (File f : fileList) { String fileName = f.getAbsolutePath(); if (fileName.endsWith(".class")) { String nosuffixFileName = fileName.substring(8 + fileName.lastIndexOf("classes"), fileName.indexOf(".class")); String filePackage = nosuffixFileName.replaceAll("////", "."); Class<?> clazz = Class.forName(filePackage); iWhat.execute(f, clazz); } else { iWhat.execute(f, null); } } } } catch (Exception e) { e.printStackTrace(); } }
/** * @author calebman * @Date 2018-4-28 * 处理器执行类 */ public class HttpHandler { private Object clazzFromInstance; private Method method; public HttpHandler(Object clazzFromInstance, Method method) { this.clazzFromInstance = clazzFromInstance; this.method = method; } public Object execute(FullHttpRequest fullHttpRequest) throws InvocationTargetException, IllegalAccessException { method.setAccessible(true); return method.invoke(this.clazzFromInstance, (Object) fullHttpRequest); } }
public static void loadHandlers(String packageName) { AnnotationUtil.scanPackage(packageName, new AnnotationUtil.IWhat() { @Override public void execute(File file, Class<?> clazz) throws Exception { if (clazz != null && clazz.isAnnotationPresent(Controller.class)) { System.out.println("load contorller " + clazz.getSimpleName()); Object clazzFromInstance = clazz.newInstance(); Method[] method = clazz.getDeclaredMethods(); for (Method m : method) { if (m.isAnnotationPresent(RequestMapping.class)) { RequestMapping requestMapping = m.getAnnotation(RequestMapping.class); for (String url : requestMapping.value()) { HttpHandler httpHandler = httpHandlerMap.get(url); if (httpHandler == null) { System.out.println("load url " + url + " handler " + m.getName()); httpHandlerMap.put(url, new HttpHandler(clazzFromInstance, m)); } else { System.err.println("url " + url + " has same handler"); } } } } } } }); }
public class AllocHandler extends SimpleChannelInboundHandler<FullHttpRequest> { @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest) throws Exception { HttpHandler httpHandler = HttpController.getHandler(fullHttpRequest.uri()); if (httpHandler != null) { Object obj = httpHandler.execute(fullHttpRequest); if (obj instanceof String) { sendMessage(ctx, obj.toString()); } else { sendMessage(ctx, JSONObject.toJSONString(obj)); } } else { sendError(ctx, HttpResponseStatus.NOT_FOUND); } } private void sendMessage(ChannelHandlerContext ctx, String msg) { FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8)); response.headers().set("Content-Type", "text/plain"); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }
@Controller public class TestController { @RequestMapping("/test") public String testHandler(FullHttpRequest fullHttpRequest) { return "1234"; } @RequestMapping("/zx") public String zx(FullHttpRequest fullHttpRequest) { return "zhuxiong"; } @RequestMapping("/obj") public Object obj(FullHttpRequest fullHttpRequest) { System.out.println("/n/n----------"); HttpHeaders httpHeaders = fullHttpRequest.headers(); Set<String> names = httpHeaders.names(); for (String name : names) { System.out.println(name + " : " + httpHeaders.get(name)); } System.out.println(""); ByteBuf byteBuf = fullHttpRequest.content(); byte[] byteArray = new byte[byteBuf.capacity()]; byteBuf.readBytes(byteArray); System.out.println(new String(byteArray)); System.out.println("----------/n/n"); JSONObject json = new JSONObject(); json.put("errCode", "00"); json.put("errMsg", "0000000(成功)"); json.put("data", null); return json; } }
public class HttpServerTest { public static void main(String[] args) throws Exception { HttpServer httpServer = new HttpServer(8080); httpServer.start(); } }