From 6676c3fd37519005bde7234d632e427a15653906 Mon Sep 17 00:00:00 2001 From: Redkale <22250530@qq.com> Date: Wed, 10 May 2017 23:35:47 +0800 Subject: [PATCH] =?UTF-8?q?REST=20=E5=A2=9E=E5=8A=A0=20@RestBody=20?= =?UTF-8?q?=E7=89=B9=E6=80=A7=EF=BC=8C=20=E8=8E=B7=E5=8F=96=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=86=85=E5=AE=B9,=20=E5=8F=82=E6=95=B0=E5=8F=AF?= =?UTF-8?q?=E4=BB=A5=E6=98=AFString=20=E6=88=96=20byte[]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/org/redkale/net/http/HttpRequest.java | 9 ++++ src/org/redkale/net/http/Rest.java | 41 +++++++++++++++++-- src/org/redkale/net/http/RestBody.java | 28 +++++++++++++ .../redkale/test/http/HttpRequestDesc.java | 3 ++ test/org/redkale/test/rest/HelloEntity.java | 22 ++++++++++ .../test/rest/_DynHelloRestServlet2.java | 4 ++ 6 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 src/org/redkale/net/http/RestBody.java diff --git a/src/org/redkale/net/http/HttpRequest.java b/src/org/redkale/net/http/HttpRequest.java index dfa71ff6a..e71ff0ed6 100644 --- a/src/org/redkale/net/http/HttpRequest.java +++ b/src/org/redkale/net/http/HttpRequest.java @@ -282,6 +282,15 @@ public class HttpRequest extends Request { return array.toString(UTF8); } + /** + * 获取请求内容的byte[] + * + * @return 内容 + */ + public byte[] getBody() { + return array.getBytes(); + } + /** * 直接获取body对象 * diff --git a/src/org/redkale/net/http/Rest.java b/src/org/redkale/net/http/Rest.java index fb779843c..9c44399c1 100644 --- a/src/org/redkale/net/http/Rest.java +++ b/src/org/redkale/net/http/Rest.java @@ -346,6 +346,14 @@ public final class Rest { if (annsid != null) throw new RuntimeException("@RestAddress and @RestSessionid cannot on the same Parameter in " + method); if (ptype != String.class) throw new RuntimeException("@RestAddress must on String Parameter in " + method); } + 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 (ptype != String.class && ptype != byte[].class) throw new RuntimeException("@RestBody must on String or byte[] Parameter in " + method); + } RestParam annpara = param.getAnnotation(RestParam.class); if (annpara != null) radix = annpara.radix(); @@ -363,11 +371,11 @@ public final class Rest { n = ("bean" + i); } } - if (annhead == null && anncookie == null && annaddr == null + if (annhead == null && anncookie == null && annaddr == null && annbody == null && (entry.name.startsWith("find") || entry.name.startsWith("delete")) && params.length == 1) { if (ptype.isPrimitive() || ptype == String.class) n = "#"; } - paramlist.add(new Object[]{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie}); + paramlist.add(new Object[]{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie, annbody}); } Map mappingMap = new LinkedHashMap<>(); @@ -409,7 +417,7 @@ public final class Rest { av0 = mv.visitAnnotation(webparamsDesc, true); AnnotationVisitor av1 = av0.visitArray("value"); //设置 WebParam - for (Object[] ps : paramlist) { //{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie} + for (Object[] ps : paramlist) { //{param, n, ptype, radix, comment, required, annpara, annsid, annaddr, annhead, anncookie, annbody} final boolean ishead = ((RestHeader) ps[9]) != null; //是否取getHeader 而不是 getParameter final boolean iscookie = ((RestCookie) ps[10]) != null; //是否取getCookie @@ -442,6 +450,7 @@ public final class Rest { RestAddress annaddr = (RestAddress) ps[8]; RestHeader annhead = (RestHeader) ps[9]; RestCookie anncookie = (RestCookie) ps[10]; + RestBody annbody = (RestBody) ps[11]; final boolean ishead = annhead != null; //是否取getHeader 而不是 getParameter final boolean iscookie = anncookie != null; //是否取getCookie @@ -475,6 +484,18 @@ 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 (annbody != null) { //HttpRequest.getBodyUTF8 / HttpRequest.getBody + if (ptype == String.class) { + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getBodyUTF8", "()Ljava/lang/String;", false); + mv.visitVarInsn(ASTORE, maxLocals); + varInsns.add(new int[]{ALOAD, maxLocals}); + } else { + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getBody", "()[B", false); + mv.visitVarInsn(ASTORE, maxLocals); + varInsns.add(new int[]{ALOAD, maxLocals}); + } } else if ("#".equals(pname)) { //从request.getRequstURI 中取参数 if (ptype == boolean.class) { mv.visitVarInsn(ALOAD, 1); @@ -751,11 +772,13 @@ public final class Rest { RestCookie rc = field.getAnnotation(RestCookie.class); RestSessionid rs = field.getAnnotation(RestSessionid.class); RestAddress ra = field.getAnnotation(RestAddress.class); + RestBody rb = field.getAnnotation(RestBody.class); if (rh == null && rc == null && ra == null) continue; if (rh != null && field.getType() != String.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 (rb != null && field.getType() != String.class && field.getType() != byte[].class) throw new RuntimeException("@RestAddress must on String or byte[] Field in " + field); org.redkale.util.Attribute attr = org.redkale.util.Attribute.create(loop, field); String attrFieldName; String restname = ""; @@ -771,6 +794,12 @@ public final class Rest { } else if (ra != null) { attrFieldName = "_redkale_attr_address_" + restAttributes.size(); //restname = ""; + } else if (rb != null && field.getType() == String.class) { + attrFieldName = "_redkale_attr_bodystring_" + restAttributes.size(); + //restname = ""; + } else if (rb != null && field.getType() == byte[].class) { + attrFieldName = "_redkale_attr_bodybytes_" + restAttributes.size(); + //restname = ""; } else { continue; } @@ -780,7 +809,7 @@ public final class Rest { } } while ((loop = loop.getSuperclass()) != Object.class); - if (!attrParaNames.isEmpty()) { //参数存在 RestHeader、RestCookie、RestSessionid、RestAddress字段 + if (!attrParaNames.isEmpty()) { //参数存在 RestHeader、RestCookie、RestSessionid、RestAddress、RestBody字段 mv.visitVarInsn(ALOAD, maxLocals); Label lif = new Label(); mv.visitJumpInsn(IFNULL, lif); //if(bean != null) { @@ -802,6 +831,10 @@ 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("_bodystring_")) { + mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getBodyUTF8", "()Ljava/lang/String;", false); + } else if (en.getKey().contains("_bodybytes_")) { + mv.visitMethodInsn(INVOKEVIRTUAL, reqInternalName, "getBody", "()[B", false); } mv.visitMethodInsn(INVOKEINTERFACE, attrInternalName, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V", true); } diff --git a/src/org/redkale/net/http/RestBody.java b/src/org/redkale/net/http/RestBody.java new file mode 100644 index 000000000..44e22c1b5 --- /dev/null +++ b/src/org/redkale/net/http/RestBody.java @@ -0,0 +1,28 @@ +/* + * 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.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 只能注解于Service类的方法的String/byte[]参数或参数内的String/byte[]字段 + *

+ * 用于获取HTTP请求端的请求内容UTF-8编码字符串或者 byte[] + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + */ +@Inherited +@Documented +@Target({PARAMETER, FIELD}) +@Retention(RUNTIME) +public @interface RestBody { + +} diff --git a/test/org/redkale/test/http/HttpRequestDesc.java b/test/org/redkale/test/http/HttpRequestDesc.java index 3564457dd..01eec373d 100644 --- a/test/org/redkale/test/http/HttpRequestDesc.java +++ b/test/org/redkale/test/http/HttpRequestDesc.java @@ -32,6 +32,9 @@ public interface HttpRequestDesc { //获取请求内容的UTF-8编码字符串 public String getBodyUTF8(); + //获取请求内容的byte[] + public byte[] getBody(); + //获取文件上传对象 public MultiContext getMultiContext(); diff --git a/test/org/redkale/test/rest/HelloEntity.java b/test/org/redkale/test/rest/HelloEntity.java index 8efb9cf22..1f0b738fd 100644 --- a/test/org/redkale/test/rest/HelloEntity.java +++ b/test/org/redkale/test/rest/HelloEntity.java @@ -22,6 +22,12 @@ public class HelloEntity { @RestHeader(name = "hello-res") private String resname; + @RestBody + private String bodystr; + + @RestBody + private byte[] bodys; + @RestAddress private String clientaddr; @@ -82,6 +88,22 @@ public class HelloEntity { this.resname = resname; } + public String getBodystr() { + return bodystr; + } + + public void setBodystr(String bodystr) { + this.bodystr = bodystr; + } + + public byte[] getBodys() { + return bodys; + } + + public void setBodys(byte[] bodys) { + this.bodys = bodys; + } + @Override public String toString() { return JsonFactory.root().getConvert().convertTo(this); diff --git a/test/org/redkale/test/rest/_DynHelloRestServlet2.java b/test/org/redkale/test/rest/_DynHelloRestServlet2.java index 23db0f9f0..4e97eed6c 100644 --- a/test/org/redkale/test/rest/_DynHelloRestServlet2.java +++ b/test/org/redkale/test/rest/_DynHelloRestServlet2.java @@ -34,6 +34,8 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet { HelloEntity bean = req.getJsonParameter(HelloEntity.class, "bean"); bean.setClientaddr(req.getRemoteAddr()); bean.setResname(req.getHeader("hello-res")); + bean.setBodys(req.getBody()); + bean.setBodystr(req.getBodyUTF8()); UserInfo user = currentUser(req); RetResult result = service.createHello(user, bean); resp.finishJson(result); @@ -57,6 +59,8 @@ public class _DynHelloRestServlet2 extends SimpleRestServlet { HelloEntity bean = req.getJsonParameter(HelloEntity.class, "bean"); bean.setClientaddr(req.getRemoteAddr()); bean.setResname(req.getHeader("hello-res")); + bean.setBodys(req.getBody()); + bean.setBodystr(req.getBodyUTF8()); service.updateHello(bean); resp.finishJson(RetResult.success()); }