This commit is contained in:
Redkale
2017-05-13 14:16:51 +08:00
parent 02fcb7b089
commit 63fe26f9cb
9 changed files with 85 additions and 116 deletions

View File

@@ -83,7 +83,7 @@ public final class ApiDocsService extends AbstractService {
if (actionurls.contains(action.url())) continue;
mappingmap.put("url", prefix + action.url());
actionurls.add(action.url());
mappingmap.put("auth", method.getAnnotation(AuthIgnore.class) == null);
mappingmap.put("auth", action.auth());
mappingmap.put("actionid", action.actionid());
mappingmap.put("comment", action.comment());
List<Map> paramsList = new ArrayList<>();

View File

@@ -1,35 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.net.http;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 配合 HttpServlet 使用。 <br>
* 当标记为 &#64;HttpCacheable 的方法使用response.finish的参数将被缓存一段时间(默认值 seconds=15秒)。 <br>
* 通常情况下 &#64;HttpCacheable 需要与 &#64;AuthIgnore 一起使用,没有标记&#64;AuthIgnore的方法一般输出的结果与当前用户信息有关。 <br>
* <p>
* 注意: 不能标记在HttpServlet类中已有的方法(如: execute/preExecute/authenticate)
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface HttpCacheable {
/**
* 超时的秒数
*
* @return 超时秒数
*/
int seconds() default 15;
}

View File

@@ -23,17 +23,64 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
public @interface HttpMapping {
/**
* 操作ID值鉴权时用到
*
* @return int
*/
int actionid() default 0;
String url();
String[] methods() default {};//允许方法(不区分大小写),如:GET/POST/PUT,为空表示允许所有方法
/**
* 结果缓存的秒数, 为0表示不缓存 <br>
* * 当值大于0将被缓存一段时间(默认值 seconds=15秒)。 <br>
* 通常情况下需要 auth() == true 才使用没有标记auth==true方法一般输出的结果与当前用户信息有关。 <br>
*
* @return int
*/
int cacheseconds() default 0;
String comment() default ""; //备注描述
/**
* 是否鉴权,默认不鉴权 <br>
* 如&#64;WebServlet.auth = false 该值忽略
*
* @return boolean
*/
boolean auth() default false;
boolean inherited() default true; //是否能被继承, 当 HttpServlet 被继承后该方法是否能被子类继承
/**
* 允许方法(不区分大小写),如:GET/POST/PUT,为空表示允许所有方法
*
* @return String[]
*/
String[] methods() default {};
String result() default "Object"; //输出结果的数据类型
/**
* 是否能被继承, 当 HttpServlet 被继承后该方法是否能被子类继承
*
* @return boolean
*/
boolean inherited() default true;
Class[] results() default {}; //输出结果的数据类型集合,由于结果类型可能是泛型而注解的参数值不支持泛型,因此加入明细数据类型集合
/**
* 输出结果的数据类型
*
* @return String
*/
String result() default "Object";
/**
* 输出结果的数据类型集合,由于结果类型可能是泛型而注解的参数值不支持泛型,因此加入明细数据类型集合
*
* @return Class[]
*/
Class[] results() default {};
/**
* 备注描述
*
* @return String
*/
String comment() default "";
}

View File

@@ -158,9 +158,9 @@ public abstract class HttpServlet extends Servlet<HttpContext, HttpRequest, Http
}
private HashMap<String, Entry> load() {
final boolean typeIgnore = this.getClass().getAnnotation(AuthIgnore.class) != null;
WebServlet module = this.getClass().getAnnotation(WebServlet.class);
final int serviceid = module == null ? 0 : module.moduleid();
final boolean typeIgnore = module == null ? true : !module.auth();
final HashMap<String, Entry> map = new HashMap<>();
HashMap<String, Class> nameset = new HashMap<>();
final Class selfClz = this.getClass();
@@ -286,9 +286,9 @@ public abstract class HttpServlet extends Servlet<HttpContext, HttpRequest, Http
this.methods = methods;
this.method = method;
this.servlet = servlet;
this.ignore = typeIgnore || method.getAnnotation(AuthIgnore.class) != null;
HttpCacheable hc = method.getAnnotation(HttpCacheable.class);
this.cacheseconds = hc == null ? 0 : hc.seconds() * 1000;
HttpMapping mapping = method.getAnnotation(HttpMapping.class);
this.ignore = typeIgnore || (mapping == null || !mapping.auth());
this.cacheseconds = mapping == null ? 0 : mapping.cacheseconds();
this.cache = cacheseconds > 0 ? new ConcurrentHashMap() : null;
this.cacheHandler = cacheseconds > 0 ? (HttpResponse response, ByteBuffer[] buffers) -> {
int status = response.getStatus();

View File

@@ -120,8 +120,6 @@ public final class Rest {
final String flipperDesc = Type.getDescriptor(Flipper.class);
final String httprsDesc = Type.getDescriptor(HttpResult.class);
final String attrDesc = Type.getDescriptor(org.redkale.util.Attribute.class);
final String authDesc = Type.getDescriptor(AuthIgnore.class);
final String cacheDesc = Type.getDescriptor(HttpCacheable.class);
final String mappingDesc = Type.getDescriptor(HttpMapping.class);
final String webparamDesc = Type.getDescriptor(HttpParam.class);
final String webparamsDesc = Type.getDescriptor(HttpParam.HttpParams.class);
@@ -263,15 +261,6 @@ public final class Rest {
mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, entry.name, "(" + reqDesc + respDesc + ")V", null, new String[]{"java/io/IOException"}));
//mv.setDebug(true);
mv.debugLine();
if (!entry.auth) { //设置 AuthIgnore
av0 = mv.visitAnnotation(authDesc, true);
av0.visitEnd();
}
if (entry.cacheseconds > 0) { //设置 HttpCacheable
av0 = mv.visitAnnotation(cacheDesc, true);
av0.visit("seconds", entry.cacheseconds);
av0.visitEnd();
}
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, REST_SERVICEMAP_FIELD_NAME, "Ljava/util/Map;");
@@ -386,6 +375,8 @@ public final class Rest {
av0 = mv.visitAnnotation(mappingDesc, true);
String url = "/" + defmodulename.toLowerCase() + "/" + entry.name + (reqpath ? "/" : "");
av0.visit("url", url);
av0.visit("auth", entry.auth);
av0.visit("cacheseconds", entry.cacheseconds);
av0.visit("actionid", entry.actionid);
av0.visit("comment", entry.comment);
@@ -401,7 +392,7 @@ public final class Rest {
av0.visitEnd();
mappingMap.put("url", url);
mappingMap.put("auth", entry.auth);
mappingMap.put("cachetimeout", entry.cacheseconds);
mappingMap.put("cacheseconds", entry.cacheseconds);
mappingMap.put("actionid", entry.actionid);
mappingMap.put("comment", entry.comment);
mappingMap.put("methods", entry.methods);

View File

@@ -49,6 +49,14 @@ public @interface WebServlet {
*/
int moduleid() default 0;
/**
* 是否鉴权,默认不鉴权 <br>
* 标记为不鉴权的HttpServlet 其内部所有方法都将不进行鉴权
*
* @return boolean
*/
boolean auth() default false;
/**
* 备注描述
*

View File

@@ -1,27 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.util;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 用于标记不要进行鉴权操作。 <br>
* 场景一:配合 HttpServlet 使用,当标记为 &#64;AuthIgnore 的方法在执行execute之前不会调用authenticate 方法。 <br>
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*/
@Inherited
@Documented
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface AuthIgnore {
}

View File

@@ -47,7 +47,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet {
url = "http://127.0.0.1:" + port + "/pipes/hello/create?entity={}";
System.out.println("增加记录: " + Utility.postHttpContent(url, headers, "{'a':2,'b':3}"));
url = "http://127.0.0.1:" + port + "/pipes/hello/asyncfind/111111";
System.out.println("listmap: " + Utility.postHttpContent(url, headers, null));
url = "http://127.0.0.1:" + port + "/pipes/hello/asyncfind2/22222";
@@ -57,20 +57,18 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet {
}
@AuthIgnore
@HttpMapping(url = "/hello/create")
@HttpMapping(url = "/hello/create", auth = false)
public void create(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
HelloEntity bean = req.getJsonParameter(HelloEntity.class, "bean");
bean.setClientaddr(req.getRemoteAddr());
bean.setResname(req.getHeader("hello-res"));
UserInfo user = req.currentUser();
RetResult<HelloEntity> result = service.createHello(user, bean, req.getBodyJson(Map.class));
RetResult<HelloEntity> result = service.createHello(user, bean, req.getBodyJson(Map.class));
resp.finishJson(result);
}
@AuthIgnore
@HttpMapping(url = "/hello/delete/")
@HttpMapping(url = "/hello/delete/", auth = false)
public void delete(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
int id = Integer.parseInt(req.getRequstURILastPath());
@@ -78,8 +76,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet {
resp.finishJson(RetResult.success());
}
@AuthIgnore
@HttpMapping(url = "/hello/update")
@HttpMapping(url = "/hello/update", auth = false)
public void update(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
String clientaddr = req.getRemoteAddr();
@@ -90,8 +87,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet {
resp.finishJson(RetResult.success());
}
@AuthIgnore
@HttpMapping(url = "/hello/partupdate")
@HttpMapping(url = "/hello/partupdate", auth = false)
public void partupdate(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
HelloEntity bean = req.getJsonParameter(HelloEntity.class, "bean");
@@ -102,8 +98,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet {
resp.finishJson(RetResult.success());
}
@AuthIgnore
@HttpMapping(url = "/hello/query")
@HttpMapping(url = "/hello/query", auth = false)
public void query(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
HelloBean bean = req.getJsonParameter(HelloBean.class, "bean");
@@ -116,8 +111,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet {
resp.finishJson(result);
}
@AuthIgnore
@HttpMapping(url = "/hello/list")
@HttpMapping(url = "/hello/list", auth = false)
public void list(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
HelloBean bean = req.getJsonParameter(HelloBean.class, "bean");
@@ -129,8 +123,7 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet {
resp.finishJson(result);
}
@AuthIgnore
@HttpMapping(url = "/hello/find/")
@HttpMapping(url = "/hello/find/", auth = false)
public void find(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
int id = Integer.parseInt(req.getRequstURILastPath());
@@ -138,24 +131,21 @@ public class _DynHelloRestServlet1 extends SimpleRestServlet {
resp.finishJson(bean);
}
@AuthIgnore
@HttpMapping(url = "/hello/asyncfind/")
@HttpMapping(url = "/hello/asyncfind/", auth = false)
public void asyncfind(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
int id = Integer.parseInt(req.getRequstURILastPath());
resp.finishJson(service.asyncFindHello(id));
}
@AuthIgnore
@HttpMapping(url = "/hello/asyncfind2/")
@HttpMapping(url = "/hello/asyncfind2/", auth = false)
public void asyncfind2(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
int id = Integer.parseInt(req.getRequstURILastPath());
service.asyncFindHello(resp.createAsyncHandler(), id);
}
@AuthIgnore
@HttpMapping(url = "/hello/asyncfind3/")
@HttpMapping(url = "/hello/asyncfind3/", auth = false)
public void asyncfind3(HttpRequest req, HttpResponse resp) throws IOException {
HelloService service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
int id = Integer.parseInt(req.getRequstURILastPath());

View File

@@ -26,8 +26,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet {
@Resource
private Map<String, HelloService2> _servicemap;
@AuthIgnore
@HttpMapping(url = "/hello/create", comment = "创建Hello对象")
@HttpMapping(url = "/hello/create", auth = false, comment = "创建Hello对象")
@HttpParam(name = "bean", type = HelloEntity.class, comment = "Hello对象")
public void create(HttpRequest req, HttpResponse resp) throws IOException {
HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
@@ -41,8 +40,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet {
resp.finishJson(result);
}
@AuthIgnore
@HttpMapping(url = "/hello/delete/", comment = "根据id删除Hello对象")
@HttpMapping(url = "/hello/delete/", auth = false, comment = "根据id删除Hello对象")
@HttpParam(name = "#", type = int.class, comment = "Hello对象id")
public void delete(HttpRequest req, HttpResponse resp) throws IOException {
HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
@@ -51,8 +49,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet {
resp.finishJson(RetResult.success());
}
@AuthIgnore
@HttpMapping(url = "/hello/update", comment = "修改Hello对象")
@HttpMapping(url = "/hello/update", auth = false, comment = "修改Hello对象")
@HttpParam(name = "bean", type = HelloEntity.class, comment = "Hello对象")
public void update(HttpRequest req, HttpResponse resp) throws IOException {
HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
@@ -65,8 +62,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet {
resp.finishJson(RetResult.success());
}
@AuthIgnore
@HttpMapping(url = "/hello/query", comment = "查询Hello对象列表")
@HttpMapping(url = "/hello/query", auth = false, comment = "查询Hello对象列表")
@HttpParam(name = "bean", type = HelloBean.class, comment = "过滤条件")
public void query(HttpRequest req, HttpResponse resp) throws IOException {
HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));
@@ -80,8 +76,7 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet {
resp.finishJson(result);
}
@AuthIgnore
@HttpMapping(url = "/hello/find/", comment = "根据id删除Hello对象")
@HttpMapping(url = "/hello/find/", auth = false, comment = "根据id删除Hello对象")
@HttpParam(name = "#", type = int.class, comment = "Hello对象id")
public void find(HttpRequest req, HttpResponse resp) throws IOException {
HelloService2 service = _servicemap == null ? _service : _servicemap.get(req.getHeader(Rest.REST_HEADER_RESOURCE_NAME, ""));