diff --git a/src/main/java/META-INF/application-template.xml b/src/main/java/META-INF/application-template.xml index 86dc40f19..bc5166bc5 100644 --- a/src/main/java/META-INF/application-template.xml +++ b/src/main/java/META-INF/application-template.xml @@ -273,10 +273,12 @@ 当Server为HTTP协议时, request节点才有效。 remoteaddr 节点: 替换请求方节点的IP地址, 通常请求方是由nginx等web静态服务器转发过的则需要配置该节点。 且value值只能是以request.headers.开头,表示从request.headers中获取对应的header值。 + locale value值必须是request.headers.或request.parameters.开头。 例如下面例子获取request.getRemoteAddr()值,如果header存在X-RemoteAddress值则返回X-RemoteAddress值,不存在返回getRemoteAddress()。 --> + @@ -286,8 +288,8 @@ contenttype: plain值为调用finish时的ContentType; 默认值: text/plain; charset=utf-8 json值为调用finishJson时的ContentType; 默认值: application/json; charset=utf-8 defcookie 节点: 当response里输出的cookie没有指定domain 和path时,使用该节点的默认值。 - 如果addheader、setheader 的value值以request.parameters.开头则表示从request.parameters中获取对应的parameter值 - 如果addheader、setheader 的value值以request.headers.开头则表示从request.headers中获取对应的header值 + addheader、setheader 的value值以request.parameters.开头则表示从request.parameters中获取对应的parameter值 + addheader、setheader 的value值以request.headers.开头则表示从request.headers中获取对应的header值 例如下面例子是在Response输出header时添加两个header(一个addHeader, 一个setHeader)。 options 节点: 设置了该节点且auto=true,当request的method=OPTIONS自动设置addheader、setheader并返回200状态码 date 节点: 设置了该节点且period有值(单位:毫秒);返回response会包含Date头信息,默认为period=0 diff --git a/src/main/java/org/redkale/net/http/HttpContext.java b/src/main/java/org/redkale/net/http/HttpContext.java index 1900594a8..f7622eb7d 100644 --- a/src/main/java/org/redkale/net/http/HttpContext.java +++ b/src/main/java/org/redkale/net/http/HttpContext.java @@ -30,6 +30,10 @@ public class HttpContext extends Context { protected final String remoteAddrHeader; + protected final String localHeader; + + protected final String localParameter; + protected final HttpRpcAuthenticator rpcAuthenticator; protected final AnyValue rpcAuthenticatorConfig; @@ -40,6 +44,8 @@ public class HttpContext extends Context { public HttpContext(HttpContextConfig config) { super(config); this.remoteAddrHeader = config.remoteAddrHeader; + this.localHeader = config.localHeader; + this.localParameter = config.localParameter; this.rpcAuthenticator = config.rpcAuthenticator; this.rpcAuthenticatorConfig = config.rpcAuthenticatorConfig; random.setSeed(Math.abs(System.nanoTime())); @@ -190,6 +196,10 @@ public class HttpContext extends Context { public String remoteAddrHeader; + public String localHeader; + + public String localParameter; + public HttpRpcAuthenticator rpcAuthenticator; public AnyValue rpcAuthenticatorConfig; diff --git a/src/main/java/org/redkale/net/http/HttpParam.java b/src/main/java/org/redkale/net/http/HttpParam.java index 23f8ae068..67301a2fe 100644 --- a/src/main/java/org/redkale/net/http/HttpParam.java +++ b/src/main/java/org/redkale/net/http/HttpParam.java @@ -12,7 +12,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 配合 @HttpMapping 使用。 * 用于对@HttpMapping方法中参数描述
- * 从RestService生成过来的HttpMapping,标记为@RestUserid、@RestAddress的参数不会生成HttpParam + * 从RestService生成过来的HttpMapping,标记为@RestUserid、@RestAddress、@RestLocale的参数不会生成HttpParam * *

* 详情见: https://redkale.org diff --git a/src/main/java/org/redkale/net/http/HttpRequest.java b/src/main/java/org/redkale/net/http/HttpRequest.java index 824aafbd2..398888d7b 100644 --- a/src/main/java/org/redkale/net/http/HttpRequest.java +++ b/src/main/java/org/redkale/net/http/HttpRequest.java @@ -132,6 +132,8 @@ public class HttpRequest extends Request { protected String remoteAddr; + protected String locale; + private String lastRequestURIString; private byte[] lastRequestURIBytes; @@ -146,6 +148,10 @@ public class HttpRequest extends Request { private final String remoteAddrHeader; + private final String localHeader; + + private final String localParameter; + final HttpRpcAuthenticator rpcAuthenticator; HttpServlet.ActionEntry actionEntry; //仅供HttpServlet传递Entry使用 @@ -158,6 +164,8 @@ public class HttpRequest extends Request { super(context); this.array = array; this.remoteAddrHeader = context.remoteAddrHeader; + this.localHeader = context.localHeader; + this.localParameter = context.localParameter; this.rpcAuthenticator = context.rpcAuthenticator; } @@ -166,6 +174,8 @@ public class HttpRequest extends Request { super(context); this.array = new ByteArray(); this.remoteAddrHeader = null; + this.localHeader = null; + this.localParameter = null; this.rpcAuthenticator = null; if (req != null) initSimpleRequest(req, true); } @@ -185,6 +195,7 @@ public class HttpRequest extends Request { if (req.getCurrentUserid() != null) this.currentUserid = req.getCurrentUserid(); this.contentType = req.getContentType(); this.remoteAddr = req.getRemoteAddr(); + this.locale = req.getLocale(); if (needPath) { this.requestURI = (req.getPath() == null || req.getPath().isEmpty()) ? req.getRequestURI() : (req.getPath() + req.getRequestURI()); } else { @@ -214,6 +225,7 @@ public class HttpRequest extends Request { parseBody(); req.setParams(params.isEmpty() ? null : params); req.setRemoteAddr(getRemoteAddr()); + req.setLocale(getLocale()); req.setContentType(getContentType()); req.setPath(prefix); String uri = this.requestURI; @@ -1140,6 +1152,30 @@ public class HttpRequest extends Request { return this.remoteAddr; } + /** + * 获取国际化Locale,值可以取之于header或parameter + * + * @return 国际化Locale + */ + public String getLocale() { + if (this.locale != null) return this.locale; + if (localHeader != null) { + String val = getHeader(localHeader); + if (val != null) { + this.locale = val; + return val; + } + } + if (localParameter != null) { + String val = getParameter(localParameter); + if (val != null) { + this.locale = val; + return val; + } + } + return this.locale; + } + /** * 获取请求内容指定的编码字符串 * diff --git a/src/main/java/org/redkale/net/http/HttpServer.java b/src/main/java/org/redkale/net/http/HttpServer.java index ae13de7ae..1eae8b6c4 100644 --- a/src/main/java/org/redkale/net/http/HttpServer.java +++ b/src/main/java/org/redkale/net/http/HttpServer.java @@ -334,6 +334,8 @@ public class HttpServer extends Server headers; - @ConvertColumn(index = 13) + @ConvertColumn(index = 14) @Comment("参数信息") protected Map params; - @ConvertColumn(index = 14) + @ConvertColumn(index = 15) @Comment("http body信息") protected byte[] body; //对应HttpRequest.array @@ -152,6 +156,11 @@ public class HttpSimpleRequest implements java.io.Serializable { return this; } + public HttpSimpleRequest locale(String locale) { + this.locale = locale; + return this; + } + public HttpSimpleRequest sessionid(String sessionid) { this.sessionid = sessionid; return this; @@ -266,6 +275,11 @@ public class HttpSimpleRequest implements java.io.Serializable { return this; } + public HttpSimpleRequest clearLocale() { + this.locale = null; + return this; + } + public HttpSimpleRequest clearSessionid() { this.sessionid = null; return this; @@ -316,6 +330,14 @@ public class HttpSimpleRequest implements java.io.Serializable { this.remoteAddr = remoteAddr; } + public String getLocale() { + return locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + public int getHashid() { return hashid; } diff --git a/src/main/java/org/redkale/net/http/Rest.java b/src/main/java/org/redkale/net/http/Rest.java index 8cf868e8b..392b80b56 100644 --- a/src/main/java/org/redkale/net/http/Rest.java +++ b/src/main/java/org/redkale/net/http/Rest.java @@ -1022,6 +1022,7 @@ public final class Rest { Collections.sort(entrys); } { //restConverts、typeRefs、mappingurlToMethod、restAttributes、bodyTypes赋值 + final int headIndex = 10; for (final MappingEntry entry : entrys) { mappingurlToMethod.put(entry.mappingurl, entry.mappingMethod); final Method method = entry.mappingMethod; @@ -1059,6 +1060,10 @@ public final class Rest { if (annaddr != null) { comment = annaddr.comment(); } + RestLocale annlocale = param.getAnnotation(RestLocale.class); + if (annlocale != null) { + comment = annlocale.comment(); + } RestBody annbody = param.getAnnotation(RestBody.class); if (annbody != null) { comment = annbody.comment(); @@ -1099,10 +1104,10 @@ public final class Rest { } //n maybe is null java.lang.reflect.Type paramtype = TypeToken.getGenericType(param.getParameterizedType(), serviceType); - paramlist.add(new Object[]{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie, annbody, annfile, annuri, userid, annheaders, annparams, paramtype}); + paramlist.add(new Object[]{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annlocale, annhead, anncookie, annbody, annfile, annuri, userid, annheaders, annparams, paramtype}); } - for (Object[] ps : paramlist) { //{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie, annbody, annfile, annuri, annuserid, annheaders, annparams, paramtype} - final boolean isuserid = ((RestUserid) ps[14]) != null; //是否取userid + for (Object[] ps : paramlist) { //{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annlocale, annhead, anncookie, annbody, annfile, annuri, annuserid, annheaders, annparams, paramtype} + final boolean isuserid = ((RestUserid) ps[headIndex + 5]) != null; //是否取userid if ((ps[1] != null && ps[1].toString().indexOf('&') >= 0) || isuserid) continue; //@RestUserid 不需要生成 @HttpParam if (((RestAddress) ps[8]) != null) continue; //@RestAddress 不需要生成 @HttpParam java.lang.reflect.Type pgtype = TypeToken.getGenericType(((Parameter) ps[0]).getParameterizedType(), serviceType); @@ -1123,18 +1128,20 @@ public final class Rest { RestParam annpara = (RestParam) ps[6]; RestSessionid annsid = (RestSessionid) ps[7]; RestAddress annaddr = (RestAddress) ps[8]; - RestHeader annhead = (RestHeader) ps[9]; - RestCookie anncookie = (RestCookie) ps[10]; - RestBody annbody = (RestBody) ps[11]; - RestUploadFile annfile = (RestUploadFile) ps[12]; - RestURI annuri = (RestURI) ps[13]; - RestUserid annuserid = (RestUserid) ps[14]; - RestHeaders annheaders = (RestHeaders) ps[15]; - RestParams annparams = (RestParams) ps[16]; + RestLocale annlocale = (RestLocale) ps[9]; + RestHeader annhead = (RestHeader) ps[headIndex]; + RestCookie anncookie = (RestCookie) ps[headIndex + 1]; + RestBody annbody = (RestBody) ps[headIndex + 2]; + RestUploadFile annfile = (RestUploadFile) ps[headIndex + 3]; + RestURI annuri = (RestURI) ps[headIndex + 4]; + RestUserid annuserid = (RestUserid) ps[headIndex + 5]; + RestHeaders annheaders = (RestHeaders) ps[headIndex + 6]; + RestParams annparams = (RestParams) ps[headIndex + 7]; if (CompletionHandler.class.isAssignableFrom(ptype)) { //HttpResponse.createAsyncHandler() or HttpResponse.createAsyncHandler(Class) } else if (annsid != null) { //HttpRequest.getSessionid(true|false) } else if (annaddr != null) { //HttpRequest.getRemoteAddr + } else if (annlocale != null) { //HttpRequest.getLocale } else if (annheaders != null) { //HttpRequest.getHeaders } else if (annparams != null) { //HttpRequest.getParameters } else if (annbody != null) { //HttpRequest.getBodyUTF8 / HttpRequest.getBody @@ -1163,10 +1170,11 @@ public final class Rest { RestCookie rc = field.getAnnotation(RestCookie.class); RestSessionid rs = field.getAnnotation(RestSessionid.class); RestAddress ra = field.getAnnotation(RestAddress.class); + RestLocale rl = field.getAnnotation(RestLocale.class); RestBody rb = field.getAnnotation(RestBody.class); RestUploadFile ru = field.getAnnotation(RestUploadFile.class); RestURI ri = field.getAnnotation(RestURI.class); - if (rh == null && rc == null && ra == null && rb == null && rs == null && ru == null && ri == null) continue; + if (rh == null && rc == null && ra == null && rl == null && rb == null && rs == null && ru == null && ri == null) continue; org.redkale.util.Attribute attr = org.redkale.util.Attribute.create(loop, field); String attrFieldName; @@ -1183,6 +1191,9 @@ public final class Rest { } else if (ra != null) { attrFieldName = "_redkale_attr_address_" + restAttributes.size(); //restname = ""; + } else if (rl != null) { + attrFieldName = "_redkale_attr_locale_" + restAttributes.size(); + //restname = ""; } else if (rb != null && field.getType() == String.class) { attrFieldName = "_redkale_attr_bodystring_" + restAttributes.size(); //restname = ""; @@ -1228,6 +1239,7 @@ public final class Rest { } else if (en.getKey().contains("_cookie_")) { } else if (en.getKey().contains("_sessionid_")) { } else if (en.getKey().contains("_address_")) { + } else if (en.getKey().contains("_locale_")) { } else if (en.getKey().contains("_uri_")) { } else if (en.getKey().contains("_bodystring_")) { } else if (en.getKey().contains("_bodybytes_")) { @@ -1614,12 +1626,23 @@ public final class Rest { comment = annaddr.comment(); required = false; } + RestLocale annlocale = param.getAnnotation(RestLocale.class); + if (annlocale != null) { + if (annhead != null) throw new RuntimeException("@RestLocale and @RestHeader cannot on the same Parameter in " + method); + if (anncookie != null) throw new RuntimeException("@RestLocale and @RestCookie cannot on the same Parameter in " + method); + if (annsid != null) throw new RuntimeException("@RestLocale and @RestSessionid cannot on the same Parameter in " + method); + if (annaddr != null) throw new RuntimeException("@RestLocale and @RestAddress cannot on the same Parameter in " + method); + if (ptype != String.class) throw new RuntimeException("@RestAddress must on String Parameter in " + method); + comment = annlocale.comment(); + required = false; + } RestBody annbody = param.getAnnotation(RestBody.class); if (annbody != null) { if (annhead != null) throw new RuntimeException("@RestBody and @RestHeader cannot on the same Parameter in " + method); if (anncookie != null) throw new RuntimeException("@RestBody and @RestCookie cannot on the same Parameter in " + method); if (annsid != null) throw new RuntimeException("@RestBody and @RestSessionid cannot on the same Parameter in " + method); if (annaddr != null) throw new RuntimeException("@RestBody and @RestAddress cannot on the same Parameter in " + method); + if (annlocale != null) throw new RuntimeException("@RestBody and @RestLocale cannot on the same Parameter in " + method); if (ptype.isPrimitive()) throw new RuntimeException("@RestBody cannot on primitive type Parameter in " + method); comment = annbody.comment(); } @@ -1632,6 +1655,7 @@ public final class Rest { if (anncookie != null) throw new RuntimeException("@RestUploadFile and @RestCookie cannot on the same Parameter in " + method); if (annsid != null) throw new RuntimeException("@RestUploadFile and @RestSessionid cannot on the same Parameter in " + method); if (annaddr != null) throw new RuntimeException("@RestUploadFile and @RestAddress cannot on the same Parameter in " + method); + if (annlocale != null) throw new RuntimeException("@RestUploadFile and @RestLocale cannot on the same Parameter in " + method); if (annbody != null) throw new RuntimeException("@RestUploadFile and @RestBody cannot on the same Parameter in " + method); if (ptype != byte[].class && ptype != File.class && ptype != File[].class) throw new RuntimeException("@RestUploadFile must on byte[] or File or File[] Parameter in " + method); comment = annfile.comment(); @@ -1643,6 +1667,7 @@ public final class Rest { if (anncookie != null) throw new RuntimeException("@RestURI and @RestCookie cannot on the same Parameter in " + method); if (annsid != null) throw new RuntimeException("@RestURI and @RestSessionid cannot on the same Parameter in " + method); if (annaddr != null) throw new RuntimeException("@RestURI and @RestAddress cannot on the same Parameter in " + method); + if (annlocale != null) throw new RuntimeException("@RestURI and @RestLocale cannot on the same Parameter in " + method); if (annbody != null) throw new RuntimeException("@RestURI and @RestBody cannot on the same Parameter in " + method); if (annfile != null) throw new RuntimeException("@RestURI and @RestUploadFile cannot on the same Parameter in " + method); if (ptype != String.class) throw new RuntimeException("@RestURI must on String Parameter in " + method); @@ -1655,6 +1680,7 @@ public final class Rest { if (anncookie != null) throw new RuntimeException("@RestUserid and @RestCookie cannot on the same Parameter in " + method); if (annsid != null) throw new RuntimeException("@RestUserid and @RestSessionid cannot on the same Parameter in " + method); if (annaddr != null) throw new RuntimeException("@RestUserid and @RestAddress cannot on the same Parameter in " + method); + if (annlocale != null) throw new RuntimeException("@RestUserid and @RestLocale cannot on the same Parameter in " + method); if (annbody != null) throw new RuntimeException("@RestUserid and @RestBody cannot on the same Parameter in " + method); if (annfile != null) throw new RuntimeException("@RestUserid and @RestUploadFile cannot on the same Parameter in " + method); if (!ptype.isPrimitive() && !java.io.Serializable.class.isAssignableFrom(ptype)) throw new RuntimeException("@RestUserid must on java.io.Serializable Parameter in " + method); @@ -1668,6 +1694,7 @@ public final class Rest { if (anncookie != null) throw new RuntimeException("@RestHeaders and @RestCookie cannot on the same Parameter in " + method); if (annsid != null) throw new RuntimeException("@RestHeaders and @RestSessionid cannot on the same Parameter in " + method); if (annaddr != null) throw new RuntimeException("@RestHeaders and @RestAddress cannot on the same Parameter in " + method); + if (annlocale != null) throw new RuntimeException("@RestHeaders and @RestLocale cannot on the same Parameter in " + method); if (annbody != null) throw new RuntimeException("@RestHeaders and @RestBody cannot on the same Parameter in " + method); if (annfile != null) throw new RuntimeException("@RestHeaders and @RestUploadFile cannot on the same Parameter in " + method); if (userid != null) throw new RuntimeException("@RestHeaders and @RestUserid cannot on the same Parameter in " + method); @@ -1681,6 +1708,7 @@ public final class Rest { if (anncookie != null) throw new RuntimeException("@RestParams and @RestCookie cannot on the same Parameter in " + method); if (annsid != null) throw new RuntimeException("@RestParams and @RestSessionid cannot on the same Parameter in " + method); if (annaddr != null) throw new RuntimeException("@RestParams and @RestAddress cannot on the same Parameter in " + method); + if (annlocale != null) throw new RuntimeException("@RestParams and @RestLocale cannot on the same Parameter in " + method); if (annbody != null) throw new RuntimeException("@RestParams and @RestBody cannot on the same Parameter in " + method); if (annfile != null) throw new RuntimeException("@RestParams and @RestUploadFile cannot on the same Parameter in " + method); if (userid != null) throw new RuntimeException("@RestParams and @RestUserid cannot on the same Parameter in " + method); @@ -1705,7 +1733,7 @@ public final class Rest { throw new RuntimeException("Parameter " + param.getName() + " not found name by @RestParam in " + method); } } - if (annhead == null && anncookie == null && annsid == null && annaddr == null && annbody == null && annfile == null + if (annhead == null && anncookie == null && annsid == null && annaddr == null && annlocale == null && annbody == null && annfile == null && !ptype.isPrimitive() && ptype != String.class && ptype != Flipper.class && !CompletionHandler.class.isAssignableFrom(ptype) && !ptype.getName().startsWith("java") && n.charAt(0) != '#' && !"&".equals(n)) { //判断Json对象是否包含@RestUploadFile Class loop = ptype; @@ -1723,7 +1751,7 @@ public final class Rest { } while ((loop = loop.getSuperclass()) != Object.class); } java.lang.reflect.Type paramtype = TypeToken.getGenericType(param.getParameterizedType(), serviceType); - paramlist.add(new Object[]{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie, annbody, annfile, annuri, userid, annheaders, annparams, paramtype}); + paramlist.add(new Object[]{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annlocale, annhead, anncookie, annbody, annfile, annuri, userid, annheaders, annparams, paramtype}); } Map mappingMap = new LinkedHashMap<>(); @@ -1833,18 +1861,20 @@ public final class Rest { av1.visitEnd(); av0.visitEnd(); } + final int headIndex = 10; { // 设置 Annotation av0 = mv.visitAnnotation(httpParamsDesc, true); AnnotationVisitor av1 = av0.visitArray("value"); //设置 HttpParam - for (Object[] ps : paramlist) { //{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie, annbody, annfile, annuri, annuserid, annheaders, annparams, paramtype} + for (Object[] ps : paramlist) { //{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annlocale, annhead, anncookie, annbody, annfile, annuri, annuserid, annheaders, annparams, paramtype} String n = ps[1].toString(); - final boolean isuserid = ((RestUserid) ps[14]) != null; //是否取userid + final boolean isuserid = ((RestUserid) ps[headIndex + 5]) != null; //是否取userid if (n.indexOf('&') >= 0 || isuserid) continue; //@RestUserid 不需要生成 @HttpParam if (((RestAddress) ps[8]) != null) continue; //@RestAddress 不需要生成 @HttpParam - final boolean ishead = ((RestHeader) ps[9]) != null; //是否取getHeader 而不是 getParameter - final boolean iscookie = ((RestCookie) ps[10]) != null; //是否取getCookie - final boolean isbody = ((RestBody) ps[11]) != null; //是否取getBody + if (((RestLocale) ps[9]) != null) continue; //@RestLocale 不需要生成 @HttpParam + final boolean ishead = ((RestHeader) ps[headIndex]) != null; //是否取getHeader 而不是 getParameter + final boolean iscookie = ((RestCookie) ps[headIndex + 1]) != null; //是否取getCookie + final boolean isbody = ((RestBody) ps[headIndex + 2]) != null; //是否取getBody AnnotationVisitor av2 = av1.visitAnnotation(null, httpParamDesc); av2.visit("name", (String) ps[1]); if (((Parameter) ps[0]).getAnnotation(Deprecated.class) != null) { @@ -1863,13 +1893,13 @@ public final class Rest { av2.visit("radix", (Integer) ps[3]); if (ishead) { av2.visitEnum("style", sourcetypeDesc, HttpParam.HttpParameterStyle.HEADER.name()); - av2.visit("example", ((RestHeader) ps[9]).example()); + av2.visit("example", ((RestHeader) ps[headIndex]).example()); } else if (iscookie) { av2.visitEnum("style", sourcetypeDesc, HttpParam.HttpParameterStyle.COOKIE.name()); - av2.visit("example", ((RestCookie) ps[10]).example()); + av2.visit("example", ((RestCookie) ps[headIndex + 1]).example()); } else if (isbody) { av2.visitEnum("style", sourcetypeDesc, HttpParam.HttpParameterStyle.BODY.name()); - av2.visit("example", ((RestBody) ps[11]).example()); + av2.visit("example", ((RestBody) ps[headIndex + 2]).example()); } else if (ps[6] != null) { av2.visitEnum("style", sourcetypeDesc, HttpParam.HttpParameterStyle.QUERY.name()); av2.visit("example", ((RestParam) ps[6]).example()); @@ -1932,16 +1962,17 @@ public final class Rest { RestParam annpara = (RestParam) ps[6]; RestSessionid annsid = (RestSessionid) ps[7]; RestAddress annaddr = (RestAddress) ps[8]; - RestHeader annhead = (RestHeader) ps[9]; - RestCookie anncookie = (RestCookie) ps[10]; - RestBody annbody = (RestBody) ps[11]; - RestUploadFile annfile = (RestUploadFile) ps[12]; - RestURI annuri = (RestURI) ps[13]; - RestUserid userid = (RestUserid) ps[14]; - RestHeaders annheaders = (RestHeaders) ps[15]; - RestParams annparams = (RestParams) ps[16]; - java.lang.reflect.Type pgentype = (java.lang.reflect.Type) ps[17]; - if (dynsimple && (annsid != null || annaddr != null || annhead != null || anncookie != null || annfile != null || annheaders != null)) dynsimple = false; + RestLocale annlocale = (RestLocale) ps[9]; + RestHeader annhead = (RestHeader) ps[headIndex]; + RestCookie anncookie = (RestCookie) ps[headIndex + 1]; + RestBody annbody = (RestBody) ps[headIndex + 2]; + RestUploadFile annfile = (RestUploadFile) ps[headIndex + 3]; + RestURI annuri = (RestURI) ps[headIndex + 4]; + RestUserid userid = (RestUserid) ps[headIndex + 5]; + RestHeaders annheaders = (RestHeaders) ps[headIndex + 6]; + RestParams annparams = (RestParams) ps[headIndex + 7]; + java.lang.reflect.Type pgentype = (java.lang.reflect.Type) ps[headIndex + 8]; + if (dynsimple && (annsid != null || annaddr != null || annlocale != null || annhead != null || anncookie != null || annfile != null || annheaders != null)) dynsimple = false; final boolean ishead = annhead != null; //是否取getHeader 而不是 getParameter final boolean iscookie = anncookie != null; //是否取getCookie @@ -1975,6 +2006,11 @@ public final class Rest { mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getRemoteAddr", "()Ljava/lang/String;", false); mv.visitVarInsn(ASTORE, maxLocals); varInsns.add(new int[]{ALOAD, maxLocals}); + } else if (annlocale != null) { //HttpRequest.getLocale + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getLocale", "()Ljava/lang/String;", false); + mv.visitVarInsn(ASTORE, maxLocals); + varInsns.add(new int[]{ALOAD, maxLocals}); } else if (annheaders != null) { //HttpRequest.getHeaders mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getHeaders", "()Ljava/util/Map;", false); @@ -2326,14 +2362,16 @@ public final class Rest { RestCookie rc = field.getAnnotation(RestCookie.class); RestSessionid rs = field.getAnnotation(RestSessionid.class); RestAddress ra = field.getAnnotation(RestAddress.class); + RestLocale rl = field.getAnnotation(RestLocale.class); RestBody rb = field.getAnnotation(RestBody.class); RestUploadFile ru = field.getAnnotation(RestUploadFile.class); RestURI ri = field.getAnnotation(RestURI.class); - if (rh == null && rc == null && ra == null && rb == null && rs == null && ru == null && ri == null) continue; + if (rh == null && rc == null && ra == null && rl == null && rb == null && rs == null && ru == null && ri == null) continue; if (rh != null && field.getType() != String.class && field.getType() != InetSocketAddress.class) throw new RuntimeException("@RestHeader must on String Field in " + field); if (rc != null && field.getType() != String.class) throw new RuntimeException("@RestCookie must on String Field in " + field); if (rs != null && field.getType() != String.class) throw new RuntimeException("@RestSessionid must on String Field in " + field); if (ra != null && field.getType() != String.class) throw new RuntimeException("@RestAddress must on String Field in " + field); + if (rl != null && field.getType() != String.class) throw new RuntimeException("@RestLocale must on String Field in " + field); if (rb != null && field.getType().isPrimitive()) throw new RuntimeException("@RestBody must on cannot on primitive type Field in " + field); if (ru != null && field.getType() != byte[].class && field.getType() != File.class && field.getType() != File[].class) { throw new RuntimeException("@RestUploadFile must on byte[] or File or File[] Field in " + field); @@ -2355,6 +2393,9 @@ public final class Rest { } else if (ra != null) { attrFieldName = "_redkale_attr_address_" + restAttributes.size(); //restname = ""; + } else if (rl != null) { + attrFieldName = "_redkale_attr_locale_" + restAttributes.size(); + //restname = ""; } else if (rb != null && field.getType() == String.class) { attrFieldName = "_redkale_attr_bodystring_" + restAttributes.size(); //restname = ""; @@ -2385,7 +2426,7 @@ public final class Rest { } } while ((loop = loop.getSuperclass()) != Object.class); - if (!attrParaNames.isEmpty()) { //参数存在 RestHeader、RestCookie、RestSessionid、RestAddress、RestBody字段 + if (!attrParaNames.isEmpty()) { //参数存在 RestHeader、RestCookie、RestSessionid、RestAddress、RestLocale、RestBody字段 mv.visitVarInsn(ALOAD, maxLocals); //加载JsonBean Label lif = new Label(); mv.visitJumpInsn(IFNULL, lif); //if(bean != null) { @@ -2428,6 +2469,8 @@ public final class Rest { mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getSessionid", "(Z)Ljava/lang/String;", false); } else if (en.getKey().contains("_address_")) { mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getRemoteAddr", "()Ljava/lang/String;", false); + } else if (en.getKey().contains("_locale_")) { + mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getLocale", "()Ljava/lang/String;", false); } else if (en.getKey().contains("_uri_")) { mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getRequestURI", "()Ljava/lang/String;", false); } else if (en.getKey().contains("_bodystring_")) { diff --git a/src/main/java/org/redkale/net/http/RestLocale.java b/src/main/java/org/redkale/net/http/RestLocale.java new file mode 100644 index 000000000..d9b581a39 --- /dev/null +++ b/src/main/java/org/redkale/net/http/RestLocale.java @@ -0,0 +1,32 @@ +/* + */ +package org.redkale.net.http; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 只能注解于Service类的方法的String参数或参数内的String字段 + *

+ * 用于获取HTTP请求端的IP地址 HttpRequest.getLocale + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + * @since 2.7.0 + */ +@Inherited +@Documented +@Target({PARAMETER, FIELD}) +@Retention(RUNTIME) +public @interface RestLocale { + + /** + * 备注描述, 对应@HttpParam.comment + * + * @return String + */ + String comment() default ""; +}