You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/08/29 02:56:28 UTC
[incubator-servicecomb-java-chassis] 02/03: [SCB-206] allow users
to specify request Content-Type
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit cabebee4552cb8d170b993ca7a317cd1a4f1052f
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Fri Aug 24 00:28:17 2018 +0800
[SCB-206] allow users to specify request Content-Type
---
.../common/rest/codec/RestClientRequest.java | 3 ++
.../rest/codec/param/BodyProcessorCreator.java | 43 +++++++++++++++++--
.../rest/codec/param/RestClientRequestImpl.java | 6 +++
.../common/rest/codec/param/TestBodyProcessor.java | 50 ++++++++++++++++++++--
4 files changed, 94 insertions(+), 8 deletions(-)
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestClientRequest.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestClientRequest.java
index f70c7c7..a300273 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestClientRequest.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestClientRequest.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.common.rest.codec;
import javax.servlet.http.Part;
+import io.vertx.core.MultiMap;
import io.vertx.core.buffer.Buffer;
/**
@@ -34,6 +35,8 @@ public interface RestClientRequest {
void putHeader(String name, String value);
+ MultiMap getHeaders();
+
void addForm(String name, Object value);
Buffer getBodyBuffer() throws Exception;
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
index ff5f587..e3016a0 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
@@ -17,6 +17,7 @@
package org.apache.servicecomb.common.rest.codec.param;
+import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.Locale;
@@ -33,6 +34,7 @@ import org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream;
import org.apache.servicecomb.swagger.generator.core.utils.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
@@ -40,6 +42,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
import io.swagger.models.parameters.Parameter;
import io.vertx.core.buffer.Buffer;
+import io.vertx.core.buffer.impl.BufferImpl;
public class BodyProcessorCreator implements ParamValueProcessorCreator {
private static final Logger LOGGER = LoggerFactory.getLogger(BodyProcessorCreator.class);
@@ -99,12 +102,44 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator {
@Override
public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {
+ ensureContentType(clientRequest);
+ if (arg != null) {
+ Buffer buffer = createBodyBuffer(
+ clientRequest.getHeaders().get(HttpHeaders.CONTENT_TYPE),
+ arg);
+ clientRequest.write(buffer);
+ }
+ }
+
+ /**
+ * Deserialize body object into body buffer, according to the Content-Type.
+ *
+ * @param contentType the Content-Type of request
+ * @param arg body param object
+ * @return the deserialized body buffer
+ * @throws IOException
+ */
+ private Buffer createBodyBuffer(String contentType, Object arg) throws IOException {
+ if (MediaType.TEXT_PLAIN.equals(contentType)) {
+ if (!String.class.isInstance(arg)) {
+ throw new IllegalArgumentException("Content-Type is text/plain while arg type is not String");
+ }
+ return new BufferImpl().appendBytes(((String) arg).getBytes());
+ }
+
try (BufferOutputStream output = new BufferOutputStream()) {
- clientRequest.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output, arg);
- if (arg != null) {
- clientRequest.write(output.getBuffer());
- }
+ return output.getBuffer();
+ }
+ }
+
+ /**
+ * If the Content-Type has not been set yet, set application/json as default value.
+ */
+ private void ensureContentType(RestClientRequest clientRequest) {
+ if (null == clientRequest.getHeaders()
+ || StringUtils.isEmpty(clientRequest.getHeaders().get(HttpHeaders.CONTENT_TYPE))) {
+ clientRequest.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
}
}
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
index 9116d3f..8b124ec 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
@@ -40,6 +40,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.vertx.core.Context;
+import io.vertx.core.MultiMap;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpClientRequest;
import io.vertx.core.http.HttpHeaders;
@@ -272,4 +273,9 @@ public class RestClientRequestImpl implements RestClientRequest {
public void putHeader(String name, String value) {
request.putHeader(name, value);
}
+
+ @Override
+ public MultiMap getHeaders() {
+ return request.headers();
+ }
}
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java
index 0b9fb1f..a7afaa5 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/param/TestBodyProcessor.java
@@ -17,8 +17,11 @@
package org.apache.servicecomb.common.rest.codec.param;
+import static org.junit.Assert.fail;
+
import java.io.IOException;
import java.nio.charset.StandardCharsets;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -32,13 +35,16 @@ import org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator.BodyP
import org.apache.servicecomb.common.rest.codec.param.BodyProcessorCreator.RawJsonBodyProcessor;
import org.apache.servicecomb.foundation.vertx.stream.BufferInputStream;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.databind.type.TypeFactory;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
+import io.vertx.core.MultiMap;
import io.vertx.core.buffer.Buffer;
+import io.vertx.core.http.impl.headers.VertxHttpHeaders;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
@@ -48,7 +54,7 @@ public class TestBodyProcessor {
@Mocked
HttpServletRequest request;
- Map<String, String> headers = new HashMap<>();
+ MultiMap headers;
RestClientRequest clientRequest;
@@ -72,13 +78,18 @@ public class TestBodyProcessor {
clientRequest = new MockUp<RestClientRequest>() {
@Mock
void putHeader(String name, String value) {
- headers.put(name, value);
+ headers.add(name, value);
}
@Mock
void write(Buffer bodyBuffer) {
outputBodyBuffer = bodyBuffer;
}
+
+ @Mock
+ MultiMap getHeaders() {
+ return headers;
+ }
}.getMockInstance();
}
@@ -96,6 +107,11 @@ public class TestBodyProcessor {
initInputStream();
}
+ @Before
+ public void before() {
+ headers = new VertxHttpHeaders();
+ }
+
@Test
public void testGetValueHaveAttr() throws Exception {
int body = 10;
@@ -122,7 +138,7 @@ public class TestBodyProcessor {
};
Object result = processor.getValue(request);
- Assert.assertEquals(null, result);
+ Assert.assertNull(result);
}
@Test
@@ -174,6 +190,32 @@ public class TestBodyProcessor {
}
@Test
+ public void testSetValueTextPlain() throws Exception {
+ createClientRequest();
+ createProcessor(String.class);
+ headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
+
+ processor.setValue(clientRequest, "value");
+ Assert.assertEquals(MediaType.TEXT_PLAIN, headers.get(HttpHeaders.CONTENT_TYPE));
+ Assert.assertEquals("value", outputBodyBuffer.toString());
+ }
+
+ @Test
+ public void testSetValueTextPlainTypeMismatch() {
+ createClientRequest();
+ createProcessor(String.class);
+ headers.add(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
+
+ try {
+ processor.setValue(clientRequest, new Date());
+ fail("an exception is expected!");
+ } catch (Exception e) {
+ Assert.assertEquals(IllegalArgumentException.class, e.getClass());
+ Assert.assertEquals("Content-Type is text/plain while arg type is not String", e.getMessage());
+ }
+ }
+
+ @Test
public void testGetParameterPath() {
createProcessor(String.class);
Assert.assertEquals("", processor.getParameterPath());
@@ -220,7 +262,7 @@ public class TestBodyProcessor {
};
Object result = processor.getValue(request);
- Assert.assertEquals(null, result);
+ Assert.assertNull(result);
}
@Test