From 6c95264ead16b32cd93138f76c98b9bf428148c1 Mon Sep 17 00:00:00 2001 From: aoshiguchen <1052045476@qq.com> Date: Thu, 21 Jul 2022 20:33:54 +0800 Subject: [PATCH] =?UTF-8?q?web=E6=9C=8D=E5=8A=A1=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=9D=99=E6=80=81=E8=B5=84=E6=BA=90=E6=98=A0=E5=B0=84.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/constant/MetaDataConstant.java | 4 + .../fun/asgc/neutrino/core/util/MimeType.java | 255 ++++++++++++++++++ .../neutrino/core/web/HttpRequestHandler.java | 16 ++ .../core/web/router/DefaultHttpRouter.java | 59 ++++ .../src/main/resources/static/js/test.js | 3 + .../src/main/resources/template/index.html | 12 + 6 files changed, 349 insertions(+) create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/util/MimeType.java create mode 100644 neutrino-proxy-server/src/main/resources/static/js/test.js create mode 100644 neutrino-proxy-server/src/main/resources/template/index.html diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/constant/MetaDataConstant.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/constant/MetaDataConstant.java index 883cc2c8..948bab82 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/constant/MetaDataConstant.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/constant/MetaDataConstant.java @@ -76,4 +76,8 @@ public interface MetaDataConstant { * 默认的http页面路径 */ String DEFAULT_HTTP_PAGE_PATH = CLASSPATH_RESOURCE_IDENTIFIER.concat("/webapp/"); + /** + * 服务版本 + */ + String SERVER_VS = "Neutrino-1.0"; } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/MimeType.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/MimeType.java new file mode 100644 index 00000000..145f2426 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/util/MimeType.java @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2022 aoshiguchen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package fun.asgc.neutrino.core.util; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @author: aoshiguchen + * @date: 2022/7/21 + */ +public class MimeType { + + final static Pattern pattern = Pattern.compile("\\S*[?]\\S*"); + + private static Map h = new HashMap(); + static { + h.put("", "application/octet-stream"); + h.put("323", "text/h323"); + h.put("acx", "application/internet-property-stream"); + h.put("ai", "application/postscript"); + h.put("aif", "audio/x-aiff"); + h.put("aifc", "audio/x-aiff"); + h.put("aiff", "audio/x-aiff"); + h.put("asf", "video/x-ms-asf"); + h.put("asr", "video/x-ms-asf"); + h.put("asx", "video/x-ms-asf"); + h.put("au", "audio/basic"); + h.put("avi", "video/x-msvideo"); + h.put("axs", "application/olescript"); + h.put("bas", "text/plain"); + h.put("bcpio", "application/x-bcpio"); + h.put("bin", "application/octet-stream"); + h.put("bmp", "image/bmp"); + h.put("c", "text/plain"); + h.put("cat", "application/vnd.ms-pkiseccat"); + h.put("cdf", "application/x-cdf"); + h.put("cer", "application/x-x509-ca-cert"); + h.put("class", "application/octet-stream"); + h.put("clp", "application/x-msclip"); + h.put("cmx", "image/x-cmx"); + h.put("cod", "image/cis-cod"); + h.put("cpio", "application/x-cpio"); + h.put("crd", "application/x-mscardfile"); + h.put("crl", "application/pkix-crl"); + h.put("crt", "application/x-x509-ca-cert"); + h.put("csh", "application/x-csh"); + h.put("css", "text/css"); + h.put("dcr", "application/x-director"); + h.put("der", "application/x-x509-ca-cert"); + h.put("dir", "application/x-director"); + h.put("dll", "application/x-msdownload"); + h.put("dms", "application/octet-stream"); + h.put("doc", "application/msword"); + h.put("dot", "application/msword"); + h.put("dvi", "application/x-dvi"); + h.put("dxr", "application/x-director"); + h.put("eps", "application/postscript"); + h.put("etx", "text/x-setext"); + h.put("evy", "application/envoy"); + h.put("exe", "application/octet-stream"); + h.put("fif", "application/fractals"); + h.put("flr", "x-world/x-vrml"); + h.put("gif", "image/gif"); + h.put("gtar", "application/x-gtar"); + h.put("gz", "application/x-gzip"); + h.put("h", "text/plain"); + h.put("hdf", "applicatin/x-hdf"); + h.put("hlp", "application/winhlp"); + h.put("hqx", "application/mac-binhex40"); + h.put("hta", "application/hta"); + h.put("htc", "text/x-component"); + h.put("htm", "text/html"); + h.put("html", "text/html"); + h.put("htt", "text/webviewhtml"); + h.put("ico", "image/x-icon"); + h.put("ief", "image/ief"); + h.put("iii", "application/x-iphone"); + h.put("ins", "application/x-internet-signup"); + h.put("isp", "application/x-internet-signup"); + h.put("jfif", "image/pipeg"); + h.put("jpe", "image/jpeg"); + h.put("jpeg", "image/jpeg"); + h.put("jpg", "image/jpeg"); + h.put("js", "application/x-javascript"); + h.put("latex", "application/x-latex"); + h.put("lha", "application/octet-stream"); + h.put("lsf", "video/x-la-asf"); + h.put("lsx", "video/x-la-asf"); + h.put("lzh", "application/octet-stream"); + h.put("m13", "application/x-msmediaview"); + h.put("m14", "application/x-msmediaview"); + h.put("m3u", "audio/x-mpegurl"); + h.put("man", "application/x-troff-man"); + h.put("mdb", "application/x-msaccess"); + h.put("me", "application/x-troff-me"); + h.put("mht", "message/rfc822"); + h.put("mhtml", "message/rfc822"); + h.put("mid", "audio/mid"); + h.put("mny", "application/x-msmoney"); + h.put("mov", "video/quicktime"); + h.put("movie", "video/x-sgi-movie"); + h.put("mp2", "video/mpeg"); + h.put("mp3", "audio/mpeg"); + h.put("mpa", "video/mpeg"); + h.put("mpe", "video/mpeg"); + h.put("mpeg", "video/mpeg"); + h.put("mpg", "video/mpeg"); + h.put("mpp", "application/vnd.ms-project"); + h.put("mpv2", "video/mpeg"); + h.put("ms", "application/x-troff-ms"); + h.put("mvb", "application/x-msmediaview"); + h.put("nws", "message/rfc822"); + h.put("oda", "application/oda"); + h.put("p10", "application/pkcs10"); + h.put("p12", "application/x-pkcs12"); + h.put("p7b", "application/x-pkcs7-certificates"); + h.put("p7c", "application/x-pkcs7-mime"); + h.put("p7m", "application/x-pkcs7-mime"); + h.put("p7r", "application/x-pkcs7-certreqresp"); + h.put("p7s", "application/x-pkcs7-signature"); + h.put("pbm", "image/x-portable-bitmap"); + h.put("pdf", "application/pdf"); + h.put("pfx", "application/x-pkcs12"); + h.put("pgm", "image/x-portable-graymap"); + h.put("pko", "application/ynd.ms-pkipko"); + h.put("pma", "application/x-perfmon"); + h.put("pmc", "application/x-perfmon"); + h.put("pml", "application/x-perfmon"); + h.put("pmr", "application/x-perfmon"); + h.put("pmw", "application/x-perfmon"); + h.put("pnm", "image/x-portable-anymap"); + h.put("pot,", "application/vnd.ms-powerpoint"); + h.put("ppm", "image/x-portable-pixmap"); + h.put("pps", "application/vnd.ms-powerpoint"); + h.put("ppt", "application/vnd.ms-powerpoint"); + h.put("prf", "application/pics-rules"); + h.put("ps", "application/postscript"); + h.put("pub", "application/x-mspublisher"); + h.put("qt", "video/quicktime"); + h.put("ra", "audio/x-pn-realaudio"); + h.put("ram", "audio/x-pn-realaudio"); + h.put("ras", "image/x-cmu-raster"); + h.put("rgb", "image/x-rgb"); + h.put("rmi", "audio/mid"); + h.put("roff", "application/x-troff"); + h.put("rtf", "application/rtf"); + h.put("rtx", "text/richtext"); + h.put("scd", "application/x-msschedule"); + h.put("sct", "text/scriptlet"); + h.put("setpay", "application/set-payment-initiation"); + h.put("setreg", "application/set-registration-initiation"); + h.put("sh", "application/x-sh"); + h.put("shar", "application/x-shar"); + h.put("sit", "application/x-stuffit"); + h.put("snd", "audio/basic"); + h.put("spc", "application/x-pkcs7-certificates"); + h.put("spl", "application/futuresplash"); + h.put("src", "application/x-wais-source"); + h.put("sst", "application/vnd.ms-pkicertstore"); + h.put("stl", "application/vnd.ms-pkistl"); + h.put("stm", "text/html"); + h.put("svg", "image/svg+xml"); + h.put("sv4cpio", "application/x-sv4cpio"); + h.put("sv4crc", "application/x-sv4crc"); + h.put("swf", "application/x-shockwave-flash"); + h.put("t", "application/x-troff"); + h.put("tar", "application/x-tar"); + h.put("tcl", "application/x-tcl"); + h.put("tex", "application/x-tex"); + h.put("texi", "application/x-texinfo"); + h.put("texinfo", "application/x-texinfo"); + h.put("tgz", "application/x-compressed"); + h.put("tif", "image/tiff"); + h.put("tiff", "image/tiff"); + h.put("tr", "application/x-troff"); + h.put("trm", "application/x-msterminal"); + h.put("tsv", "text/tab-separated-values"); + h.put("txt", "text/plain"); + h.put("uls", "text/iuls"); + h.put("ustar", "application/x-ustar"); + h.put("vcf", "text/x-vcard"); + h.put("vrml", "x-world/x-vrml"); + h.put("wav", "audio/x-wav"); + h.put("wcm", "application/vnd.ms-works"); + h.put("wdb", "application/vnd.ms-works"); + h.put("wks", "application/vnd.ms-works"); + h.put("wmf", "application/x-msmetafile"); + h.put("wps", "application/vnd.ms-works"); + h.put("wri", "application/x-mswrite"); + h.put("wrl", "x-world/x-vrml"); + h.put("wrz", "x-world/x-vrml"); + h.put("xaf", "x-world/x-vrml"); + h.put("xbm", "image/x-xbitmap"); + h.put("xla", "application/vnd.ms-excel"); + h.put("xlc", "application/vnd.ms-excel"); + h.put("xlm", "application/vnd.ms-excel"); + h.put("xls", "application/vnd.ms-excel"); + h.put("xlt", "application/vnd.ms-excel"); + h.put("xlw", "application/vnd.ms-excel"); + h.put("xof", "x-world/x-vrml"); + h.put("xpm", "image/x-xpixmap"); + h.put("xwd", "image/x-xwindowdump"); + h.put("z", "application/x-compress"); + h.put("zip", "application/zip"); + } + + public static String getMimeType(String docType) { + String mime = h.get(docType); + if (mime == null) { + mime = "application/octet-stream"; + } + return mime; + } + + public static String parseSuffix(String url) { + try { + Matcher matcher = pattern.matcher(url); + String[] spUrl = url.toString().split("/"); + int len = spUrl.length; + String endUrl = spUrl[len - 1]; + if (matcher.find()) { + String[] spEndUrl = endUrl.split("\\?"); + endUrl = spEndUrl[0]; + } + String[] endUrlArr = endUrl.split("\\."); + return endUrlArr[endUrlArr.length - 1]; + } catch (Exception e) { + return ""; + } + } +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/web/HttpRequestHandler.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/web/HttpRequestHandler.java index 6f9cab0c..cce72e2c 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/web/HttpRequestHandler.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/web/HttpRequestHandler.java @@ -25,6 +25,7 @@ import com.alibaba.fastjson.JSONObject; import fun.asgc.neutrino.core.annotation.Autowired; import fun.asgc.neutrino.core.annotation.Component; import fun.asgc.neutrino.core.annotation.NonIntercept; +import fun.asgc.neutrino.core.constant.MetaDataConstant; import fun.asgc.neutrino.core.context.ApplicationConfig; import fun.asgc.neutrino.core.util.*; import fun.asgc.neutrino.core.web.router.DefaultHttpRouter; @@ -37,6 +38,8 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.*; import lombok.extern.slf4j.Slf4j; +import java.util.Date; + /** * * @author: aoshiguchen @@ -74,6 +77,19 @@ public class HttpRequestHandler { } catch (Exception e) { // TODO } + } else if(HttpRouterType.PAGE == httpRouteResult.getType()) { + // 前端页面 + String mimeType = MimeType.getMimeType(MimeType.parseSuffix(httpRouteResult.getPageLocation())); + if (mimeType.startsWith("text/")) { + mimeType += ";charset=utf-8"; + } + FullHttpResponse fullHttpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(FileUtil.readBytes(httpRouteResult.getPageLocation()))); + fullHttpResponse.headers().add(HttpHeaderNames.CONTENT_TYPE, mimeType); + fullHttpResponse.headers().add(HttpHeaderNames.CONTENT_LANGUAGE, "zh-CN"); + fullHttpResponse.headers().add(HttpHeaderNames.SERVER, MetaDataConstant.SERVER_VS); + fullHttpResponse.headers().add(HttpHeaderNames.DATE, new Date()); + context.writeAndFlush(fullHttpResponse).addListener(ChannelFutureListener.CLOSE); + return; } else { // TODO HttpServerUtil.send404Response(context, request.uri()); diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/web/router/DefaultHttpRouter.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/web/router/DefaultHttpRouter.java index 135774a7..fb532b54 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/web/router/DefaultHttpRouter.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/web/router/DefaultHttpRouter.java @@ -25,8 +25,10 @@ import com.google.common.collect.Sets; import fun.asgc.neutrino.core.annotation.*; import fun.asgc.neutrino.core.bean.BeanWrapper; import fun.asgc.neutrino.core.bean.SimpleBeanFactory; +import fun.asgc.neutrino.core.context.ApplicationConfig; import fun.asgc.neutrino.core.util.ArrayUtil; import fun.asgc.neutrino.core.util.CollectionUtil; +import fun.asgc.neutrino.core.util.FileUtil; import fun.asgc.neutrino.core.util.ReflectUtil; import fun.asgc.neutrino.core.web.HttpMethod; import fun.asgc.neutrino.core.web.annotation.GetMapping; @@ -35,6 +37,7 @@ import fun.asgc.neutrino.core.web.annotation.RequestMapping; import fun.asgc.neutrino.core.web.annotation.RestController; import lombok.extern.slf4j.Slf4j; +import java.io.InputStream; import java.lang.reflect.Method; import java.util.List; import java.util.Map; @@ -58,9 +61,21 @@ public class DefaultHttpRouter implements HttpRouter { private Map routeCache = new ConcurrentHashMap<>(256); @Autowired private SimpleBeanFactory webApplicationBeanFactory; + @Autowired + private ApplicationConfig applicationConfig; @Init public void init() { + // 初始化方法路由 + initMethodRoute(); + // 初始化页面路由 + initPageRoute(); + } + + /** + * 初始化方法路由 + */ + private void initMethodRoute() { log.debug("Http路由器初始化..."); List beanWrapperList = webApplicationBeanFactory.beanWrapperList(); beanWrapperList.forEach(beanWrapper -> { @@ -108,6 +123,20 @@ public class DefaultHttpRouter implements HttpRouter { }); } + /** + * 初始化页面路由 + */ + private void initPageRoute() { + ApplicationConfig.StaticResource staticResource = applicationConfig.getHttp().getStaticResource(); + if (null == staticResource || CollectionUtil.isEmpty(staticResource.getLocations())) { + return; + } + log.info("Page路由初始化..."); + staticResource.getLocations().forEach(location -> { + // TODO + }); + } + private void methodScan(BeanWrapper beanWrapper, Set httpMethods, Set paths) { Set methods = ReflectUtil.getDeclaredMethods(beanWrapper.getType()); methods.forEach(method -> { @@ -184,10 +213,40 @@ public class DefaultHttpRouter implements HttpRouter { ); } + private synchronized void addRoute(String path, String pageLocation) { + log.info("addRoute path:{} file:{}", path, pageLocation); + HttpRouteIdentity identity = new HttpRouteIdentity(HttpMethod.GET, path); + if (routeCache.containsKey(identity)) { + return; + } + routeCache.put(identity, new HttpRouteInfo() + .setType(HttpRouterType.PAGE) + .setPageLocation(pageLocation) + ); + } + @Override public HttpRouteResult route(HttpRouteParam httpRouteParam) { HttpRouteIdentity identity = new HttpRouteIdentity(httpRouteParam.getMethod(), httpRouteParam.getUrl()); HttpRouteInfo httpRouteInfo = routeCache.get(identity); + if (null == httpRouteInfo) { + if (HttpMethod.GET == httpRouteParam.getMethod()) { + ApplicationConfig.StaticResource staticResource = applicationConfig.getHttp().getStaticResource(); + if (null != staticResource && CollectionUtil.notEmpty(staticResource.getLocations())) { + for (String location : staticResource.getLocations()) { + try (InputStream in = FileUtil.getInputStream(location + httpRouteParam.getUrl())){ + if (null != in) { + addRoute(httpRouteParam.getUrl(), location + httpRouteParam.getUrl()); + httpRouteInfo = routeCache.get(identity); + break; + } + } catch (Exception e) { + // ignore + } + } + } + } + } if (null == httpRouteInfo) { return null; } diff --git a/neutrino-proxy-server/src/main/resources/static/js/test.js b/neutrino-proxy-server/src/main/resources/static/js/test.js new file mode 100644 index 00000000..37b5d1e4 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/static/js/test.js @@ -0,0 +1,3 @@ +function hello() { + alert("hello"); +} diff --git a/neutrino-proxy-server/src/main/resources/template/index.html b/neutrino-proxy-server/src/main/resources/template/index.html new file mode 100644 index 00000000..0450a6c8 --- /dev/null +++ b/neutrino-proxy-server/src/main/resources/template/index.html @@ -0,0 +1,12 @@ + + + 测试页面 + + + + +

hello,欢迎来到中微子代理

+ +