diff --git a/README.md b/README.md
index af317602f..5afd9e48f 100644
--- a/README.md
+++ b/README.md
@@ -64,14 +64,14 @@ Run with `Maven`:
com.bladejava
blade-mvc
- 2.0.12.BETA
+ 2.0.12.RELEASE
```
or `Gradle`:
```sh
-compile 'com.bladejava:blade-mvc:2.0.12.BETA'
+compile 'com.bladejava:blade-mvc:2.0.12.RELEASE'
```
Write the `main` method and the `Hello World`:
diff --git a/README_CN.md b/README_CN.md
index a4a3997bc..1389fa758 100644
--- a/README_CN.md
+++ b/README_CN.md
@@ -61,7 +61,7 @@
com.bladejava
blade-mvc
- 2.0.12.BETA
+ 2.0.12.RELEASE
```
@@ -70,7 +70,7 @@
或者 `Gradle`:
```sh
-compile 'com.bladejava:blade-mvc:2.0.12.BETA'
+compile 'com.bladejava:blade-mvc:2.0.12.RELEASE'
```
编写 `main` 函数写一个 `Hello World`:
diff --git a/pom.xml b/pom.xml
index d528325f9..e211fd3fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.bladejava
blade-mvc
- 2.0.12.BETA
+ 2.0.12.RELEASE
jar
blade
diff --git a/src/main/java/com/blade/Blade.java b/src/main/java/com/blade/Blade.java
index a26afd402..3bba34ca0 100644
--- a/src/main/java/com/blade/Blade.java
+++ b/src/main/java/com/blade/Blade.java
@@ -153,6 +153,8 @@ public class Blade {
*/
private ExceptionHandler exceptionHandler = new DefaultExceptionHandler();
+ private CorsMiddleware corsMiddleware;
+
/**
* Used to identify whether the web server has started
*/
@@ -548,11 +550,15 @@ public Blade enableCors(boolean enableCors) {
public Blade enableCors(boolean enableCors, CorsConfiger corsConfig) {
this.environment.set(ENV_KEY_CORS_ENABLE, enableCors);
if (enableCors) {
- this.use(new CorsMiddleware(corsConfig));
+ this.corsMiddleware = new CorsMiddleware(corsConfig);
}
return this;
}
+ public CorsMiddleware corsMiddleware() {
+ return corsMiddleware;
+ }
+
/**
* Get blade statics list.
* e.g: "/favicon.ico", "/robots.txt", "/static/", "/upload/", "/webjars/"
@@ -1103,4 +1109,5 @@ private void loadConfig(String[] args) {
}
}
+
}
\ No newline at end of file
diff --git a/src/main/java/com/blade/ioc/annotation/Bean.java b/src/main/java/com/blade/ioc/annotation/Bean.java
index 267d4a8cc..6342e5602 100644
--- a/src/main/java/com/blade/ioc/annotation/Bean.java
+++ b/src/main/java/com/blade/ioc/annotation/Bean.java
@@ -15,6 +15,7 @@
String value() default "";
+ @Deprecated
boolean singleton() default true;
}
\ No newline at end of file
diff --git a/src/main/java/com/blade/ioc/annotation/Inject.java b/src/main/java/com/blade/ioc/annotation/Inject.java
index a23c2ae90..ac9b5f8cd 100644
--- a/src/main/java/com/blade/ioc/annotation/Inject.java
+++ b/src/main/java/com/blade/ioc/annotation/Inject.java
@@ -17,6 +17,4 @@
String value() default "";
- boolean singleton() default true;
-
}
\ No newline at end of file
diff --git a/src/main/java/com/blade/kit/IocKit.java b/src/main/java/com/blade/kit/IocKit.java
index c3f546a27..b90bd46b9 100644
--- a/src/main/java/com/blade/kit/IocKit.java
+++ b/src/main/java/com/blade/kit/IocKit.java
@@ -17,7 +17,6 @@
import com.blade.Environment;
import com.blade.ioc.Ioc;
-import com.blade.ioc.annotation.Bean;
import com.blade.ioc.annotation.Inject;
import com.blade.ioc.annotation.InjectWith;
import com.blade.ioc.annotation.Value;
@@ -25,8 +24,6 @@
import com.blade.ioc.bean.ClassDefine;
import com.blade.ioc.bean.FieldInjector;
import com.blade.ioc.bean.ValueInjector;
-import com.blade.mvc.WebContext;
-import com.blade.mvc.annotation.Path;
import lombok.experimental.UtilityClass;
import java.lang.reflect.Field;
@@ -132,18 +129,6 @@ public static void injectionValue(Environment environment, BeanDefine beanDefine
}
public static boolean isSingleton(Class> type) {
- Bean bean = type.getAnnotation(Bean.class);
- if (null != bean) {
- return bean.singleton();
- }
- Path path = type.getAnnotation(Path.class);
- if (null != path) {
- return path.singleton();
- }
- Inject inject = type.getAnnotation(Inject.class);
- if (null != inject) {
- return inject.singleton();
- }
return true;
}
diff --git a/src/main/java/com/blade/mvc/Const.java b/src/main/java/com/blade/mvc/Const.java
index 27bb935f9..949992f11 100644
--- a/src/main/java/com/blade/mvc/Const.java
+++ b/src/main/java/com/blade/mvc/Const.java
@@ -31,7 +31,7 @@ public interface Const {
int DEFAULT_SERVER_PORT = 9000;
String DEFAULT_SERVER_ADDRESS = "0.0.0.0";
String LOCAL_IP_ADDRESS = "127.0.0.1";
- String VERSION = "2.0.12.BETA";
+ String VERSION = "2.0.12.RELEASE";
String WEB_JARS = "/webjars/";
String CLASSPATH = BladeKit.getCurrentClassPath();
String CONTENT_TYPE_HTML = "text/html; charset=UTF-8";
diff --git a/src/main/java/com/blade/mvc/RouteContext.java b/src/main/java/com/blade/mvc/RouteContext.java
index 857bea275..b7e24937a 100644
--- a/src/main/java/com/blade/mvc/RouteContext.java
+++ b/src/main/java/com/blade/mvc/RouteContext.java
@@ -17,6 +17,7 @@
import com.blade.ioc.bean.BeanDefine;
import com.blade.kit.IocKit;
+import com.blade.mvc.handler.RouteHandler;
import com.blade.mvc.http.Body;
import com.blade.mvc.http.Request;
import com.blade.mvc.http.Response;
@@ -46,6 +47,7 @@ public class RouteContext {
private Request request;
private Response response;
private Object[] routeActionParameters;
+ private boolean abort;
private static final String LAMBDA_IDENTIFY = "$$Lambda$";
@@ -521,25 +523,35 @@ public Object[] routeParameters() {
return this.routeActionParameters;
}
+ public void abort() {
+ this.abort = true;
+ }
+
+ public boolean isAbort() {
+ return this.abort;
+ }
+
public void initRoute(Route route) {
this.request.initPathParams(route);
this.route = route;
-
- boolean singleton = IocKit.isSingleton(route.getTargetType());
-
- if (singleton) {
- BeanDefine beanDefine = WebContext.blade().ioc().getBeanDefine(route.getTargetType());
- if(beanDefine.isFieldHasPrototype()){
- // reset initialize
- IocKit.injection(WebContext.blade().ioc(), beanDefine);
- } else {
- Object target = WebContext.blade().ioc().getBean(route.getTargetType());
- this.route.setTarget(target);
- }
- } else {
- Object target = WebContext.blade().ioc().createBean(route.getTargetType());
- this.route.setTarget(target);
- }
+// if (null != route.getTarget() && route.getTargetType().equals(RouteHandler.class)) {
+// return;
+// }
+// boolean singleton = IocKit.isSingleton(route.getTargetType());
+//
+// if (singleton) {
+// BeanDefine beanDefine = WebContext.blade().ioc().getBeanDefine(route.getTargetType());
+// if (beanDefine.isFieldHasPrototype()) {
+// // reset initialize
+// IocKit.injection(WebContext.blade().ioc(), beanDefine);
+// } else {
+// Object target = WebContext.blade().ioc().getBean(route.getTargetType());
+// this.route.setTarget(target);
+// }
+// } else {
+// Object target = WebContext.blade().ioc().createBean(route.getTargetType());
+// this.route.setTarget(target);
+// }
}
public void injectParameters() {
diff --git a/src/main/java/com/blade/mvc/annotation/Path.java b/src/main/java/com/blade/mvc/annotation/Path.java
index c0cf6559b..d0f7572ac 100644
--- a/src/main/java/com/blade/mvc/annotation/Path.java
+++ b/src/main/java/com/blade/mvc/annotation/Path.java
@@ -31,12 +31,6 @@
*/
boolean restful() default false;
- /**
- * @return Whether to create a controller as a singleton, the default is.
- * When false, a new controller instance is created for each request.
- */
- boolean singleton() default true;
-
/**
* @return path description
*/
diff --git a/src/main/java/com/blade/security/web/cors/CorsMiddleware.java b/src/main/java/com/blade/security/web/cors/CorsMiddleware.java
index aea32749b..fd9078e47 100644
--- a/src/main/java/com/blade/security/web/cors/CorsMiddleware.java
+++ b/src/main/java/com/blade/security/web/cors/CorsMiddleware.java
@@ -1,19 +1,24 @@
package com.blade.security.web.cors;
import com.blade.mvc.RouteContext;
-import com.blade.mvc.hook.WebHook;
+import com.blade.mvc.handler.RouteHandler;
+import com.blade.mvc.http.Response;
+import lombok.extern.slf4j.Slf4j;
+
import java.util.StringJoiner;
import java.util.stream.Collector;
-import lombok.extern.slf4j.Slf4j;
/**
* CorsMiddleware
+ *
+ * This is a simple CORS policy,
+ * you can also implement the {@link CorsMiddleware#handle} method of the class to perform custom filtering.
*
* @author biezhi
* @date 2018/7/11
*/
@Slf4j
-public class CorsMiddleware implements WebHook {
+public class CorsMiddleware implements RouteHandler {
private CorsConfiger corsConfig;
@@ -25,79 +30,76 @@ public CorsMiddleware(CorsConfiger corsConfiger) {
}
@Override
- public boolean before(RouteContext context) {
- this.allowCredentials(context)
- .allowMethods(context)
- .allowHeads(context)
- .setMaxAge(context)
- .allowCredentials(context);
- if ("OPTIONS".equals(context.method())) {
- context.status(202);
- }
- return true;
+ public void handle(RouteContext context) {
+ context.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
+ context.header("Access-Control-Allow-Origin", "*");
+ context.header("Access-Control-Allow-Headers", CorsConfiger.ALL);
+ context.status(204);
}
- private CorsMiddleware allowHeads(RouteContext context) {
+ private CorsMiddleware allowHeads(Response response) {
boolean isDefaultAllowHeads = corsConfig == null || corsConfig.getAllowedHeaders() == null
- || corsConfig.getAllowedHeaders().size() == 0;
+ || corsConfig.getAllowedHeaders().size() == 0;
if (isDefaultAllowHeads) {
- context.response().header("Access-Control-Allow-Headers", CorsConfiger.ALL);
+ response.header("Access-Control-Allow-Headers", CorsConfiger.ALL);
return this;
}
- String heads = corsConfig.getAllowedHeaders().stream().collect(Collector.of(
- () -> new StringJoiner(","),
- (j, head) -> j.add(head),
- StringJoiner::merge,
- StringJoiner::toString
- ));
- context.response().header("Access-Control-Allow-Headers", heads);
+ String heads = corsConfig.getAllowedHeaders().stream()
+ .collect(Collector.of(
+ () -> new StringJoiner(","),
+ StringJoiner::add,
+ StringJoiner::merge,
+ StringJoiner::toString
+ ));
+
+ response.header("Access-Control-Allow-Headers", heads);
return this;
}
- private CorsMiddleware allowMethods(RouteContext context) {
+ private CorsMiddleware allowMethods(Response response) {
boolean isDefaultAllowMethods = corsConfig == null || corsConfig.getAllowedMethods() == null
- || corsConfig.getAllowedMethods().size() == 0;
+ || corsConfig.getAllowedMethods().size() == 0;
if (isDefaultAllowMethods) {
- context.header("Access-Control-Allow-Methods",
- CorsConfiger.DEFAULT_ALLOWED_METHODS);
+ response.header("Access-Control-Allow-Methods",
+ CorsConfiger.DEFAULT_ALLOWED_METHODS);
return this;
}
String methods = corsConfig.getAllowedMethods().stream().collect(Collector.of(
- () -> new StringJoiner(", "),
- (j, method) -> j.add(method.toUpperCase()),
- StringJoiner::merge,
- StringJoiner::toString
+ () -> new StringJoiner(", "),
+ (j, method) -> j.add(method.toUpperCase()),
+ StringJoiner::merge,
+ StringJoiner::toString
));
- context.response().header("Access-Control-Allow-Methods", methods);
+ response.header("Access-Control-Allow-Methods", methods);
return this;
}
- private CorsMiddleware allowCredentials(RouteContext context) {
+ private CorsMiddleware allowCredentials(Response response) {
boolean isDefaultAllowCredentials = corsConfig == null || corsConfig.getAllowCredentials() == null;
if (isDefaultAllowCredentials) {
- context.header("Access-Control-Allow-Credentials",
- CorsConfiger.DEFAULT_ALLOW_CREDENTIALS);
+ response.header("Access-Control-Allow-Credentials",
+ CorsConfiger.DEFAULT_ALLOW_CREDENTIALS);
return this;
}
- context.response().header("Access-Control-Allow-Credentials",
- corsConfig.getAllowCredentials().toString());
+ response.header("Access-Control-Allow-Credentials",
+ corsConfig.getAllowCredentials().toString());
return this;
}
- private CorsMiddleware setMaxAge(RouteContext context) {
+ private CorsMiddleware setMaxAge(Response response) {
boolean isDefaultMaxAge = corsConfig == null || corsConfig.getMaxAge() == null;
if (isDefaultMaxAge) {
- context.response().header("Access-Control-Max-Age",
- CorsConfiger.DEFAULT_MAX_AGE.toString());
+ response.header("Access-Control-Max-Age",
+ CorsConfiger.DEFAULT_MAX_AGE.toString());
return this;
}
- context.header("Access-Control-Max-Age", corsConfig.getMaxAge().toString());
+ response.header("Access-Control-Max-Age", corsConfig.getMaxAge().toString());
return this;
}
diff --git a/src/main/java/com/blade/server/netty/HttpServerHandler.java b/src/main/java/com/blade/server/netty/HttpServerHandler.java
index 543100d9b..dc63246a8 100644
--- a/src/main/java/com/blade/server/netty/HttpServerHandler.java
+++ b/src/main/java/com/blade/server/netty/HttpServerHandler.java
@@ -18,12 +18,10 @@
import com.blade.exception.BladeException;
import com.blade.exception.NotFoundException;
import com.blade.kit.BladeCache;
+import com.blade.mvc.RouteContext;
import com.blade.mvc.WebContext;
import com.blade.mvc.handler.ExceptionHandler;
-import com.blade.mvc.http.HttpRequest;
-import com.blade.mvc.http.HttpResponse;
-import com.blade.mvc.http.Request;
-import com.blade.mvc.http.Response;
+import com.blade.mvc.http.*;
import com.blade.mvc.route.Route;
import com.blade.mvc.route.RouteMatcher;
import io.netty.channel.ChannelFutureListener;
@@ -67,10 +65,10 @@ public class HttpServerHandler extends SimpleChannelInboundHandler
WebContext.blade().environment()
.getBoolean(ENV_KEY_PERFORMANCE, false);
- private final StaticFileHandler staticFileHandler = new StaticFileHandler(WebContext.blade());
- private final RouteMethodHandler routeHandler = new RouteMethodHandler();
- private final Set notStaticUri = new HashSet<>(32);
- private final RouteMatcher routeMatcher = WebContext.blade().routeMatcher();
+ private final StaticFileHandler staticFileHandler = new StaticFileHandler(WebContext.blade());
+ private final RouteMethodHandler routeHandler = new RouteMethodHandler();
+ private final Set notStaticUri = new HashSet<>(32);
+ private final RouteMatcher routeMatcher = WebContext.blade().routeMatcher();
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
@@ -104,10 +102,10 @@ private void writeResponse(ChannelHandlerContext ctx, CompletableFuture {
private final HttpServerHandler httpServerHandler;
private final SslContext sslCtx;
- private final Blade blade;
- private final boolean enableCors;
- private final boolean isWebSocket;
- private final boolean useGZIP;
+ private final Blade blade;
+ private final boolean isWebSocket;
+ private final boolean useGZIP;
public static volatile String date = DateKit.gmtDate(LocalDateTime.now());
@@ -41,7 +40,6 @@ public class HttpServerInitializer extends ChannelInitializer {
public HttpServerInitializer(SslContext sslCtx, Blade blade, ScheduledExecutorService service) {
this.sslCtx = sslCtx;
this.blade = blade;
- this.enableCors = blade.environment().getBoolean(Const.ENV_KEY_CORS_ENABLE, false);
this.useGZIP = blade.environment().getBoolean(Const.ENV_KEY_GZIP_ENABLE, false);
this.isWebSocket = StringKit.isNotEmpty(blade.webSocketPath());
@@ -69,10 +67,6 @@ protected void initChannel(SocketChannel ch) {
pipeline.addLast(new HttpContentCompressor());
}
- if (enableCors) {
- pipeline.addLast(new CorsHandler(CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build()));
- }
-
if (isWebSocket) {
pipeline.addLast(new WebSocketServerProtocolHandler(blade.webSocketPath(), null, true));
pipeline.addLast(WEB_SOCKET_HANDLER);
diff --git a/src/main/java/com/blade/server/netty/NettyServer.java b/src/main/java/com/blade/server/netty/NettyServer.java
index 02cd77110..29fb01d4c 100644
--- a/src/main/java/com/blade/server/netty/NettyServer.java
+++ b/src/main/java/com/blade/server/netty/NettyServer.java
@@ -291,8 +291,7 @@ private void parseAndCreate(Class> clazz) {
blade.register(clazz);
}
if (null != clazz.getAnnotation(Path.class)) {
- Path path = clazz.getAnnotation(Path.class);
- if (path.singleton() && null == blade.ioc().getBean(clazz)) {
+ if (null == blade.ioc().getBean(clazz)) {
blade.register(clazz);
}
Object controller = blade.ioc().getBean(clazz);
diff --git a/src/main/java/com/blade/server/netty/RouteMethodHandler.java b/src/main/java/com/blade/server/netty/RouteMethodHandler.java
index 6ae914871..30338c3e1 100644
--- a/src/main/java/com/blade/server/netty/RouteMethodHandler.java
+++ b/src/main/java/com/blade/server/netty/RouteMethodHandler.java
@@ -224,7 +224,6 @@ private void routeHandle(RouteContext context) {
if (null == target) {
Class> clazz = context.routeAction().getDeclaringClass();
target = WebContext.blade().getBean(clazz);
-// context.route().setTarget(target);
}
if (context.targetType() == RouteHandler.class) {
RouteHandler routeHandler = (RouteHandler) target;
@@ -239,10 +238,7 @@ private void routeHandle(RouteContext context) {
Path path = target.getClass().getAnnotation(Path.class);
JSON JSON = actionMethod.getAnnotation(JSON.class);
- boolean isRestful = (null != JSON) || (null != path && path.restful());
- boolean isSingleton = path.singleton();
-
- target = isSingleton ? target : WebContext.blade().ioc().createBean(target.getClass());
+ boolean isRestful = (null != JSON) || (null != path && path.restful());
// if request is restful and not InternetExplorer userAgent
if (isRestful) {
@@ -330,9 +326,7 @@ private boolean invokeHook(RouteContext context, Route hookRoute) throws Excepti
return true;
}
- private boolean invokeMiddleware(List middleware,
- RouteContext context) throws BladeException {
-
+ private boolean invokeMiddleware(List middleware, RouteContext context) throws BladeException {
if (BladeKit.isEmpty(middleware)) {
return true;
}
@@ -356,6 +350,9 @@ private boolean invokeHook(List hooks, RouteContext context) throws Excep
if (hook.getTargetType() == RouteHandler.class) {
RouteHandler routeHandler = (RouteHandler) hook.getTarget();
routeHandler.handle(context);
+ if (context.isAbort()) {
+ return false;
+ }
} else if (hook.getTargetType() == RouteHandler0.class) {
RouteHandler0 routeHandler = (RouteHandler0) hook.getTarget();
routeHandler.handle(context.request(), context.response());
diff --git a/src/main/java/com/blade/server/netty/StaticFileHandler.java b/src/main/java/com/blade/server/netty/StaticFileHandler.java
index 4874c4755..2c345f946 100644
--- a/src/main/java/com/blade/server/netty/StaticFileHandler.java
+++ b/src/main/java/com/blade/server/netty/StaticFileHandler.java
@@ -135,7 +135,7 @@ public void handle(WebContext webContext) throws Exception {
// gradle resources path
File resourcesDirectory = new File(new File(Const.class.getResource("/").getPath()).getParent() + "/resources");
if (resourcesDirectory.isDirectory()) {
- file = new File(resourcesDirectory.getPath() + "/resources/" + cleanUri.substring(1));
+ file = new File(resourcesDirectory.getPath() + "/" + cleanUri.substring(1));
if (file.isHidden() || !file.exists()) {
log404(log, method, uri);
throw new NotFoundException(uri);
diff --git a/src/test/java/netty_hello/BService.java b/src/test/java/netty_hello/BService.java
index 106d7e676..b0488fc4e 100644
--- a/src/test/java/netty_hello/BService.java
+++ b/src/test/java/netty_hello/BService.java
@@ -6,7 +6,7 @@
* @author biezhi
* @date 2018-11-21
*/
-@Bean(singleton = false)
+@Bean
public class BService {
public void sayHello(){
diff --git a/src/test/java/netty_hello/Hello.java b/src/test/java/netty_hello/Hello.java
index fc4b2b7c9..0ac2ca83a 100644
--- a/src/test/java/netty_hello/Hello.java
+++ b/src/test/java/netty_hello/Hello.java
@@ -16,6 +16,7 @@
* 2017/6/5
*/
public class Hello {
+
private static final StringBody hello = StringBody.of("Hello World.");
public static void main(String[] args) {
@@ -24,6 +25,7 @@ public static void main(String[] args) {
String[] chars = new String[]{"Here a special char \" that not escaped", "And Another \\ char"};
ctx.json(chars);
})
+ .get("/user/aa", ctx -> ctx.render("upload.html"))
.get("/up", ctx -> ctx.render("upload.html"))
.get("/d1", ctx -> {
File file = new File("/Users/biezhi/Pictures/rand/003.jpg");
@@ -78,6 +80,14 @@ public static void main(String[] args) {
}
})
+ .before("/user/*", ctx ->
+ {
+ System.out.println("before: " + ctx.uri());
+ ctx.text("Hello World");
+ ctx.abort();
+ }
+ )
+ .enableCors(true)
.event(EventType.ENVIRONMENT_CHANGED, new ConfigChanged())
.event(EventType.SESSION_DESTROY, e -> {
System.out.println("session 失效了");
diff --git a/src/test/java/netty_hello/UserService.java b/src/test/java/netty_hello/UserService.java
index 7e16ab0d6..15d66fca3 100644
--- a/src/test/java/netty_hello/UserService.java
+++ b/src/test/java/netty_hello/UserService.java
@@ -7,7 +7,7 @@
* @author biezhi
* @date 2018-11-21
*/
-@Bean(singleton = false)
+@Bean
public class UserService {
@Inject