You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by wu...@apache.org on 2018/06/14 12:23:47 UTC
[incubator-servicecomb-java-chassis] branch master updated:
[SCB-625] ProduceProcessor use SPI to support extends (#741)
This is an automated email from the ASF dual-hosted git repository.
wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new ec3ec37 [SCB-625] ProduceProcessor use SPI to support extends (#741)
ec3ec37 is described below
commit ec3ec37e9fa18d1b2ec310f9d749b617d0938d4e
Author: weichao <30...@users.noreply.github.com>
AuthorDate: Thu Jun 14 20:23:44 2018 +0800
[SCB-625] ProduceProcessor use SPI to support extends (#741)
* [SCB-625] ProduceProcessor use SPI to support extends
* [SCB-625] ProduceProcessor use SPI to support extends
* [SCB-625] ProduceProcessor use SPI to support extends
* [SCB-625] ProduceProcessor use SPI to support extends,use SPIServiceUtils
* [SCB-625] ProduceProcessor use SPI to support extends,use SPIServiceUtils
* [SCB-625] ProduceProcessor use SPI to support extends,use SPIServiceUtils
* [SCB-625] rebase,make getOrder useful and add demo
* [SCB-625] rebase
* [SCB-625] amend last commit
* [SCB-625] amend last commit
---
.../codec/produce/AbstractProduceProcessor.java | 24 ------
.../rest/codec/produce/ProduceJsonProcessor.java | 7 +-
.../rest/codec/produce/ProduceProcessor.java | 2 +
.../codec/produce/ProduceProcessorManager.java | 18 ++++-
.../codec/produce/ProduceTextPlainProcessor.java | 7 +-
...comb.common.rest.codec.produce.ProduceProcessor | 19 +++++
.../demo/jaxrs/server/CodeFirstJaxrs.java | 9 +++
.../servicecomb/demo/CodeFirstRestTemplate.java | 22 +++++-
.../apache/servicecomb/demo/jaxbbean/JAXBJob.java | 45 +++++++++++
.../servicecomb/demo/jaxbbean/JAXBPerson.java | 92 ++++++++++++++++++++++
.../produceprocessor/ProduceAppXmlProcessor.java | 35 ++++++++
.../override/ProduceAppXmlProcessor.java | 35 ++++++++
.../apache/servicecomb/demo/utils/JAXBUtils.java | 75 ++++++++++++++++++
...comb.common.rest.codec.produce.ProduceProcessor | 19 +++++
.../demo/springmvc/server/CodeFirstSpringmvc.java | 6 ++
15 files changed, 386 insertions(+), 29 deletions(-)
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/AbstractProduceProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/AbstractProduceProcessor.java
deleted file mode 100644
index 7704fa2..0000000
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/AbstractProduceProcessor.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.servicecomb.common.rest.codec.produce;
-
-public abstract class AbstractProduceProcessor implements ProduceProcessor {
- public AbstractProduceProcessor() {
- ProduceProcessorManager.INSTANCE.register(getName(), this);
- }
-}
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
index 28e2b29..73cbf62 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
@@ -26,7 +26,7 @@ import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
import com.fasterxml.jackson.databind.JavaType;
-public class ProduceJsonProcessor extends AbstractProduceProcessor {
+public class ProduceJsonProcessor implements ProduceProcessor {
@Override
public String getName() {
@@ -42,4 +42,9 @@ public class ProduceJsonProcessor extends AbstractProduceProcessor {
public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {
return RestObjectMapper.INSTANCE.readValue(input, type);
}
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
}
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessor.java
index 244c901..127250f 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessor.java
@@ -30,6 +30,8 @@ import io.vertx.core.buffer.Buffer;
public interface ProduceProcessor {
String getName();
+ int getOrder();
+
default void encodeResponse(OutputStream output, Object result) throws Exception {
if (result == null) {
return;
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
index d70eac4..255b35d 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
@@ -17,24 +17,38 @@
package org.apache.servicecomb.common.rest.codec.produce;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import javax.ws.rs.core.MediaType;
import org.apache.servicecomb.foundation.common.RegisterManager;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
public final class ProduceProcessorManager extends RegisterManager<String, ProduceProcessor> {
+ private static final List<ProduceProcessor> produceProcessor =
+ SPIServiceUtils.getSortedService(ProduceProcessor.class);
+
private static final String NAME = "produce processor mgr";
public static final String DEFAULT_TYPE = MediaType.APPLICATION_JSON;
public static final ProduceProcessorManager INSTANCE = new ProduceProcessorManager();
- public static final ProduceProcessor JSON_PROCESSOR = new ProduceJsonProcessor();
+ public static final ProduceProcessor JSON_PROCESSOR =
+ SPIServiceUtils.getTargetService(ProduceProcessor.class, ProduceJsonProcessor.class);
- public static final ProduceProcessor PLAIN_PROCESSOR = new ProduceTextPlainProcessor();
+ public static final ProduceProcessor PLAIN_PROCESSOR =
+ SPIServiceUtils.getTargetService(ProduceProcessor.class, ProduceTextPlainProcessor.class);
public static final ProduceProcessor DEFAULT_PROCESSOR = JSON_PROCESSOR;
private ProduceProcessorManager() {
super(NAME);
+ Set<String> set = new HashSet<>();
+ produceProcessor.forEach(processor -> {
+ if (set.add(processor.getName()))
+ register(processor.getName(), processor);
+ });
}
}
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java
index 7157adf..0311182 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java
@@ -27,7 +27,7 @@ import org.apache.commons.io.IOUtils;
import com.fasterxml.jackson.databind.JavaType;
-public class ProduceTextPlainProcessor extends AbstractProduceProcessor {
+public class ProduceTextPlainProcessor implements ProduceProcessor {
@Override
public String getName() {
return MediaType.TEXT_PLAIN;
@@ -59,4 +59,9 @@ public class ProduceTextPlainProcessor extends AbstractProduceProcessor {
// .newInstance((String)result);
// }
}
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
}
diff --git a/common/common-rest/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor b/common/common-rest/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor
new file mode 100644
index 0000000..9353b9d
--- /dev/null
+++ b/common/common-rest/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.common.rest.codec.produce.ProduceJsonProcessor
+org.apache.servicecomb.common.rest.codec.produce.ProduceTextPlainProcessor
\ No newline at end of file
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java
index 35cdd56..11987e3 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java
@@ -42,6 +42,7 @@ import org.apache.servicecomb.core.Const;
import org.apache.servicecomb.demo.compute.Person;
import org.apache.servicecomb.demo.ignore.InputModelForTestIgnore;
import org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore;
+import org.apache.servicecomb.demo.jaxbbean.JAXBPerson;
import org.apache.servicecomb.demo.server.User;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;
@@ -93,6 +94,14 @@ public class CodeFirstJaxrs {
return body;
}
+ @Path("/appXml")
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_XML)
+ public JAXBPerson appXml(JAXBPerson body) {
+ return body;
+ }
+
@Path("/bytes")
@POST
public byte[] bytes(byte[] input) {
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
index d637672..d5a12be 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
@@ -21,11 +21,14 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;
import org.apache.servicecomb.core.Const;
import org.apache.servicecomb.core.CseContext;
import org.apache.servicecomb.demo.compute.Person;
import org.apache.servicecomb.demo.ignore.InputModelForTestIgnore;
import org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore;
+import org.apache.servicecomb.demo.jaxbbean.JAXBJob;
+import org.apache.servicecomb.demo.jaxbbean.JAXBPerson;
import org.apache.servicecomb.demo.server.User;
import org.apache.servicecomb.serviceregistry.RegistryUtils;
import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
@@ -34,6 +37,7 @@ import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
@@ -62,6 +66,7 @@ public class CodeFirstRestTemplate {
protected void testAllTransport(String microserviceName, RestTemplate template, String cseUrlPrefix) {
testCodeFirstUserMap(template, cseUrlPrefix);
testCodeFirstTextPlain(template, cseUrlPrefix);
+ testCodeFirstAppXml(template, cseUrlPrefix);
testCodeFirstBytes(template, cseUrlPrefix);
testCseResponse(microserviceName, template, cseUrlPrefix);
testCodeFirstAddDate(template, cseUrlPrefix);
@@ -123,6 +128,21 @@ public class CodeFirstRestTemplate {
TestMgr.check(body, result);
}
+ private void testCodeFirstAppXml(RestTemplate template, String cseUrlPrefix) {
+ JAXBPerson person = new JAXBPerson("jake", 22, "it", "60kg");
+ person.setJob(new JAXBJob("developer", "coding"));
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("Accept", MediaType.APPLICATION_XML_VALUE);
+ headers.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
+ HttpEntity<JAXBPerson> requestEntity = new HttpEntity<>(person, headers);
+ ResponseEntity<JAXBPerson> resEntity = template.exchange(cseUrlPrefix + "appXml",
+ HttpMethod.POST,
+ requestEntity,
+ JAXBPerson.class);
+ TestMgr.check(-1, ProduceProcessorManager.INSTANCE.ensureFindValue(MediaType.APPLICATION_XML_VALUE).getOrder());
+ TestMgr.check(person, resEntity.getBody());
+ }
+
private void testCodeFirstBytes(RestTemplate template, String cseUrlPrefix) {
byte[] body = new byte[] {0, 1, 2};
byte[] result = template.postForObject(cseUrlPrefix + "bytes",
@@ -240,7 +260,7 @@ public class CodeFirstRestTemplate {
protected void testModelFieldIgnore(RestTemplate template, String cseUrlPrefix) {
InputModelForTestIgnore input = new InputModelForTestIgnore("input_id_rest", "input_id_content",
new Person("inputSomeone"), new JsonObject("{\"InputJsonKey\" : \"InputJsonValue\"}"), () -> {
- });
+ });
OutputModelForTestIgnore output = template
.postForObject(cseUrlPrefix + "ignore", input, OutputModelForTestIgnore.class);
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxbbean/JAXBJob.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxbbean/JAXBJob.java
new file mode 100644
index 0000000..b8da947
--- /dev/null
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxbbean/JAXBJob.java
@@ -0,0 +1,45 @@
+package org.apache.servicecomb.demo.jaxbbean;
+
+import javax.xml.bind.annotation.XmlAccessOrder;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorOrder;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "job")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
+public class JAXBJob {
+ private String name;
+
+ private String content;
+
+ public JAXBJob() {
+ }
+
+ public JAXBJob(String name, String content) {
+ this.name = name;
+ this.content = content;
+ }
+
+ @Override
+ public String toString() {
+ return "Job{" + "name'" + name + '\'' + ", content='" + content + '\'' + '}';
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+}
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxbbean/JAXBPerson.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxbbean/JAXBPerson.java
new file mode 100644
index 0000000..e69376d
--- /dev/null
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxbbean/JAXBPerson.java
@@ -0,0 +1,92 @@
+package org.apache.servicecomb.demo.jaxbbean;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlAccessOrder;
+import javax.xml.bind.annotation.XmlAccessorOrder;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType(propOrder = {"name", "role", "job"})
+@XmlRootElement(name = "person")
+@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
+public class JAXBPerson implements Serializable {
+ private static final long serialVersionUID = -7127275268696924681L;
+
+ private String name;
+
+ private int age;
+
+ private String role;
+
+ private String weight;
+
+ private JAXBJob job;
+
+ public JAXBPerson() {
+ }
+
+ public JAXBPerson(String name, int age, String role, String weight) {
+ this.name = name;
+ this.age = age;
+ this.role = role;
+ this.weight = weight;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @XmlAttribute
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ @XmlElement(nillable = true)
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ @XmlTransient
+ public String getWeight() {
+ return weight;
+ }
+
+ public void setWeight(String weight) {
+ this.weight = weight;
+ }
+
+ @XmlElement
+ public JAXBJob getJob() {
+ return job;
+ }
+
+ public void setJob(JAXBJob job) {
+ this.job = job;
+ }
+
+ @Override
+ public String toString() {
+ return "Person{" +
+ "name='" + name + '\'' +
+ ", age=" + age +
+ ", role='" + role + '\'' +
+ ", job=" + job +
+ '}';
+ }
+}
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/produceprocessor/ProduceAppXmlProcessor.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/produceprocessor/ProduceAppXmlProcessor.java
new file mode 100644
index 0000000..db88297
--- /dev/null
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/produceprocessor/ProduceAppXmlProcessor.java
@@ -0,0 +1,35 @@
+package org.apache.servicecomb.demo.produceprocessor;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
+import org.apache.servicecomb.demo.utils.JAXBUtils;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+public class ProduceAppXmlProcessor implements ProduceProcessor {
+
+ @Override
+ public String getName() {
+ return MediaType.APPLICATION_XML;
+ }
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
+
+ @Override
+ public void doEncodeResponse(OutputStream output, Object result) throws Exception {
+ output.write(JAXBUtils.convertToXml(result).getBytes());
+ }
+
+ @Override
+ public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {
+ return JAXBUtils.convertToJavaBean(input, type);
+ }
+
+}
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/produceprocessor/override/ProduceAppXmlProcessor.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/produceprocessor/override/ProduceAppXmlProcessor.java
new file mode 100644
index 0000000..fc1a01a
--- /dev/null
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/produceprocessor/override/ProduceAppXmlProcessor.java
@@ -0,0 +1,35 @@
+package org.apache.servicecomb.demo.produceprocessor.override;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
+import org.apache.servicecomb.demo.utils.JAXBUtils;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+public class ProduceAppXmlProcessor implements ProduceProcessor {
+
+ @Override
+ public String getName() {
+ return MediaType.APPLICATION_XML;
+ }
+
+ @Override
+ public int getOrder() {
+ return -1;
+ }
+
+ @Override
+ public void doEncodeResponse(OutputStream output, Object result) throws Exception {
+ output.write(JAXBUtils.convertToXml(result).getBytes());
+ }
+
+ @Override
+ public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {
+ return JAXBUtils.convertToJavaBean(input, type);
+ }
+
+}
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/utils/JAXBUtils.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/utils/JAXBUtils.java
new file mode 100644
index 0000000..511a18c
--- /dev/null
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/utils/JAXBUtils.java
@@ -0,0 +1,75 @@
+package org.apache.servicecomb.demo.utils;
+
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.sax.SAXSource;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+public class JAXBUtils {
+ private static final Logger LOGGER = LoggerFactory.getLogger(JAXBUtils.class);
+
+ public static String convertToXml(Object obj) {
+ return convertToXml(obj, StandardCharsets.UTF_8.toString());
+ }
+
+ public static String convertToXml(Object obj, String encoding) {
+ String result = null;
+ try {
+ JAXBContext context = JAXBContext.newInstance(obj.getClass());
+ Marshaller marshaller = context.createMarshaller();
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+ marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
+
+ StringWriter writer = new StringWriter();
+ marshaller.marshal(obj, writer);
+ result = writer.toString();
+ } catch (Exception e) {
+ LOGGER.error("Bean convert to xml failed, error message: {}", e.getMessage());
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T convertToJavaBean(InputStream xml, JavaType type) {
+ return (T) convertToJavaBean(xml, type.getRawClass());
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T convertToJavaBean(InputStream xml, Class<T> c) {
+ T t = null;
+ try {
+ JAXBContext context = JAXBContext.newInstance(c);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ t = (T) unmarshaller.unmarshal(XXEPrevention(xml));
+ } catch (Exception e) {
+ LOGGER.error("Xml convert to Bean failed, error message: {}", e.getMessage());
+ }
+ return t;
+ }
+
+ private static Source XXEPrevention(InputStream xml) {
+ Source xmlSource = null;
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ try {
+ spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
+ spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+ spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), new InputSource(xml));
+ } catch (Exception e) {
+ LOGGER.error("Xml External Entity (XXE) Processing report error, error message: {}", e.getMessage());
+ }
+ return xmlSource;
+ }
+}
diff --git a/demo/demo-schema/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor b/demo/demo-schema/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor
new file mode 100644
index 0000000..ff9a6cb
--- /dev/null
+++ b/demo/demo-schema/src/main/resources/META-INF/services/org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.demo.produceprocessor.ProduceAppXmlProcessor
+org.apache.servicecomb.demo.produceprocessor.override.ProduceAppXmlProcessor
\ No newline at end of file
diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
index 8d96d9c..4e3ae8b 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
@@ -37,6 +37,7 @@ import org.apache.servicecomb.demo.Generic;
import org.apache.servicecomb.demo.compute.Person;
import org.apache.servicecomb.demo.ignore.InputModelForTestIgnore;
import org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore;
+import org.apache.servicecomb.demo.jaxbbean.JAXBPerson;
import org.apache.servicecomb.demo.server.User;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.apache.servicecomb.swagger.extend.annotations.RawJsonRequestBody;
@@ -155,6 +156,11 @@ public class CodeFirstSpringmvc {
return body;
}
+ @RequestMapping(path = "/appXml", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_XML_VALUE)
+ public JAXBPerson appXml(@RequestBody JAXBPerson person) {
+ return person;
+ }
+
@RequestMapping(path = "/bytes", method = RequestMethod.POST)
public byte[] bytes(@RequestBody byte[] input) {
input[0] = (byte) (input[0] + 1);
--
To stop receiving notification emails like this one, please contact
wujimin@apache.org.