web服务支持静态资源映射.
This commit is contained in:
@@ -76,4 +76,8 @@ public interface MetaDataConstant {
|
||||
* 默认的http页面路径
|
||||
*/
|
||||
String DEFAULT_HTTP_PAGE_PATH = CLASSPATH_RESOURCE_IDENTIFIER.concat("/webapp/");
|
||||
/**
|
||||
* 服务版本
|
||||
*/
|
||||
String SERVER_VS = "Neutrino-1.0";
|
||||
}
|
||||
|
||||
@@ -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<String, String> h = new HashMap<String, String>();
|
||||
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 "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
@@ -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<HttpRouteIdentity, HttpRouteInfo> 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<BeanWrapper> 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<HttpMethod> httpMethods, Set<String> paths) {
|
||||
Set<Method> 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
function hello() {
|
||||
alert("hello");
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>测试页面</title>
|
||||
<script type="application/javascript" src="js/test.js"></script>
|
||||
<script type="application/javascript">
|
||||
hello();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h2>hello,欢迎来到<span stype="color:red;">中微子代理</span></h2>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user