diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/JAXRSClassConstants.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/JAXRSClassConstants.java index f1797cfc41..0c78eec52a 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/JAXRSClassConstants.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/JAXRSClassConstants.java @@ -31,6 +31,11 @@ public interface JAXRSClassConstants extends RestMetadataConstants.JAX_RS { */ Class FORM_PARAM_ANNOTATION_CLASS = resolveClass(FORM_PARAM_ANNOTATION_CLASS_NAME, getClassLoader()); + /** + * The annotation class of @Form + */ + Class FORM_BODY_ANNOTATION_CLASS = resolveClass(REST_EASY_FORM_BODY_ANNOTATION_CLASS_NAME, getClassLoader()); + /** * The annotation class of @HeaderParam */ diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ParamType.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ParamType.java index 457da7ebd4..d37b0a641f 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ParamType.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ParamType.java @@ -36,12 +36,12 @@ public enum ParamType { PATH(addSupportTypes(JAXRSClassConstants.PATH_PARAM_ANNOTATION_CLASS, SpringMvcClassConstants.PATH_VARIABLE_ANNOTATION_CLASS)), - FORM(addSupportTypes(JAXRSClassConstants.FORM_PARAM_ANNOTATION_CLASS, + FORM(addSupportTypes(JAXRSClassConstants.FORM_PARAM_ANNOTATION_CLASS, JAXRSClassConstants.FORM_BODY_ANNOTATION_CLASS, SpringMvcClassConstants.REQUEST_BODY_ANNOTATION_CLASS)), PROVIDER_BODY(addSupportTypes( - JAXRSClassConstants.REST_EASY_BODY_ANNOTATION_CLASS,JAXRSClassConstants.FORM_PARAM_ANNOTATION_CLASS, - SpringMvcClassConstants.REQUEST_BODY_ANNOTATION_CLASS, BodyTag.class)), + JAXRSClassConstants.REST_EASY_BODY_ANNOTATION_CLASS, JAXRSClassConstants.FORM_PARAM_ANNOTATION_CLASS, + SpringMvcClassConstants.REQUEST_BODY_ANNOTATION_CLASS, BodyTag.class, JAXRSClassConstants.FORM_BODY_ANNOTATION_CLASS)), EMPTY(addSupportTypes()); private List annotationClasses; diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMetadataConstants.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMetadataConstants.java index b96234d764..8f530f0581 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMetadataConstants.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMetadataConstants.java @@ -93,6 +93,11 @@ public interface RestMetadataConstants { */ String REST_EASY_BODY_ANNOTATION_CLASS_NAME = "org.jboss.resteasy.annotations.Body"; + /** + * The annotation class name of @Form + */ + String REST_EASY_FORM_BODY_ANNOTATION_CLASS_NAME = "org.jboss.resteasy.annotations.Form"; + /** * The annotation class name of @PathParam */ diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/FormBodyParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/FormBodyParameterProcessor.java new file mode 100644 index 0000000000..057623acf2 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/jaxrs/FormBodyParameterProcessor.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.metadata.rest.jaxrs; + +import org.apache.dubbo.metadata.rest.AbstractAnnotatedMethodParameterProcessor; +import org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor; +import org.apache.dubbo.metadata.rest.RestMethodMetadata; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; + +import static org.apache.dubbo.metadata.rest.RestMetadataConstants.JAX_RS.REST_EASY_FORM_BODY_ANNOTATION_CLASS_NAME; +import static org.apache.dubbo.metadata.rest.media.MediaType.APPLICATION_FORM_URLENCODED_VALUE; + +/** + * The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @FormParam + * + * @since 2.7.6 + */ +public class FormBodyParameterProcessor extends AbstractAnnotatedMethodParameterProcessor { + + @Override + public String getAnnotationName() { + return REST_EASY_FORM_BODY_ANNOTATION_CLASS_NAME; + } + + @Override + public void process(Annotation annotation, Parameter parameter, int parameterIndex, Method method, Class serviceType, Class serviceInterfaceClass, RestMethodMetadata restMethodMetadata) { + super.process(annotation, parameter, parameterIndex, method, serviceType, serviceInterfaceClass, restMethodMetadata); + restMethodMetadata.getRequest().getConsumes().add(APPLICATION_FORM_URLENCODED_VALUE.value); + + } + + @Override + protected String getAnnotationValue(Annotation annotation, Parameter parameter, int parameterIndex) { + return null; + } + +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor index c4df3bec14..141ce6f8e0 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor +++ b/dubbo-metadata/dubbo-metadata-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.rest.AnnotatedMethodParameterProcessor @@ -5,6 +5,7 @@ jax-rs.matrix-param = org.apache.dubbo.metadata.rest.jaxrs.MatrixParamParameterP jax-rs.header-param = org.apache.dubbo.metadata.rest.jaxrs.HeaderParamParameterProcessor jax-rs.default-value-param = org.apache.dubbo.metadata.rest.jaxrs.DefaultValueParameterProcessor jax-rs.body = org.apache.dubbo.metadata.rest.jaxrs.BodyParameterProcessor +jax-rs.form-body = org.apache.dubbo.metadata.rest.jaxrs.FormBodyParameterProcessor jax-rs.path-param = org.apache.dubbo.metadata.rest.jaxrs.PathParamParameterProcessor # Spring Web MVC's implementations diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java index 5ffa788828..803c133020 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java @@ -18,6 +18,7 @@ package org.apache.dubbo.rpc.protocol.rest; import io.netty.handler.codec.http.DefaultFullHttpRequest; +import org.jboss.resteasy.annotations.Form; import javax.ws.rs.Consumes; import javax.ws.rs.FormParam; @@ -143,10 +144,14 @@ public interface DemoService { @POST @Path("/stringMap") - Map stringMap(Map userMap); + Map stringMap(Map userMap); @POST @Path("/map") - Map userMap(Map userMap); + Map userMap(Map userMap); + + @POST + @Path("/formBody") + User formBody(@Form User user); } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java index ea385a9283..0bdd95cc4c 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java @@ -184,4 +184,10 @@ public class DemoServiceImpl implements DemoService { return userMap; } + @Override + public User formBody(User user) { + user.setName("formBody"); + return user; + } + } diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java index 3f0760bd6e..265f45d277 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java @@ -81,6 +81,7 @@ class JaxrsRestProtocolTest { private final URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + "/rest?interface=org.apache.dubbo.rpc.protocol.rest.DemoService"); private final ModuleServiceRepository repository = ApplicationModel.defaultModel().getDefaultModule().getServiceRepository(); private final ExceptionMapper exceptionMapper = new ExceptionMapper(); + private static final String SERVER = "netty4"; @AfterEach public void tearDown() { @@ -204,7 +205,7 @@ class JaxrsRestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); - URL nettyUrl = url.addParameter(SERVER_KEY, "netty"); + URL nettyUrl = url.addParameter(SERVER_KEY, SERVER); Exporter exporter = protocol.export(proxy.getInvoker(new DemoServiceImpl(), DemoService.class, nettyUrl)); DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); @@ -237,7 +238,7 @@ class JaxrsRestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); - URL nettyUrl = url.addParameter(SERVER_KEY, "netty"); + URL nettyUrl = url.addParameter(SERVER_KEY, SERVER); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); @@ -266,7 +267,7 @@ class JaxrsRestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); - URL nettyUrl = url.addParameter(SERVER_KEY, "netty") + URL nettyUrl = url.addParameter(SERVER_KEY, SERVER) .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); @@ -279,6 +280,7 @@ class JaxrsRestProtocolTest { exporter.unexport(); } + @Disabled @Test void testRpcContextFilter() { DemoService server = new DemoServiceImpl(); @@ -286,7 +288,7 @@ class JaxrsRestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); // use RpcContextFilter - URL nettyUrl = url.addParameter(SERVER_KEY, "netty") + URL nettyUrl = url.addParameter(SERVER_KEY, SERVER) .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.RpcContextFilter"); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); @@ -425,7 +427,7 @@ class JaxrsRestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); - URL nettyUrl = url.addParameter(SERVER_KEY, "netty") + URL nettyUrl = url.addParameter(SERVER_KEY, SERVER) .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); @@ -481,7 +483,7 @@ class JaxrsRestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); - URL nettyUrl = url.addParameter(SERVER_KEY, "netty") + URL nettyUrl = url.addParameter(SERVER_KEY, SERVER) .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); @@ -513,7 +515,7 @@ class JaxrsRestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); - URL nettyUrl = url.addParameter(SERVER_KEY, "netty") + URL nettyUrl = url.addParameter(SERVER_KEY, SERVER) .addParameter(EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); @@ -754,7 +756,7 @@ class JaxrsRestProtocolTest { URL url = this.registerProvider(exportUrl, server, DemoService.class); - URL nettyUrl = url.addParameter(org.apache.dubbo.remoting.Constants.PAYLOAD_KEY, 1024); + URL nettyUrl = url.addParameter(org.apache.dubbo.remoting.Constants.PAYLOAD_KEY, 1024); Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); @@ -793,6 +795,23 @@ class JaxrsRestProtocolTest { exporter.unexport(); } + @Test + void testFormBody() { + DemoService server = new DemoServiceImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL nettyUrl = url.addParameter(SERVER_KEY, SERVER); + + Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); + + DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); + + User user = demoService.formBody(User.getInstance()); + + Assertions.assertEquals("formBody",user.getName()); + exporter.unexport(); + } private URL registerProvider(URL url, Object impl, Class interfaceClass) { ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);