This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 554d9f94e1111f793cafb1018c5926d2c7ca99a4 Author: Andrea Cosentino <anco...@gmail.com> AuthorDate: Tue Nov 7 13:10:45 2017 +0100 CAMEL-11982 - camel-jackson - Allow to configure timezone --- .../camel/model/dataformat/JsonDataFormat.java | 114 ++++++++++++++------- .../src/main/docs/json-jackson-dataformat.adoc | 3 +- .../camel/component/jackson/JacksonDataFormat.java | 104 ++++++++++++------- .../jackson/JacksonMarshalDateTimezoneTest.java | 60 +++++++++++ .../component/jacksonxml/JacksonXMLDataFormat.java | 100 ++++++++++++------ .../jacksonxml/JacksonMarshalDateTimezoneTest.java | 60 +++++++++++ .../springboot/JacksonDataFormatConfiguration.java | 14 +++ 7 files changed, 346 insertions(+), 109 deletions(-) diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java index 5fe3e66..cc92c90 100644 --- a/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java +++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java @@ -16,6 +16,9 @@ */ package org.apache.camel.model.dataformat; +import java.text.DateFormat; +import java.util.TimeZone; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; @@ -31,9 +34,10 @@ import org.apache.camel.util.CollectionStringBuffer; import org.apache.camel.util.ObjectHelper; /** - * JSon data format is used for unmarshal a JSon payload to POJO or to marshal POJO back to JSon payload. + * JSon data format is used for unmarshal a JSon payload to POJO or to marshal + * POJO back to JSon payload. * - * @version + * @version */ @Metadata(label = "dataformat,transformation,json", title = "JSon") @XmlRootElement(name = "json") @@ -43,7 +47,8 @@ public class JsonDataFormat extends DataFormatDefinition { private String objectMapper; @XmlAttribute private Boolean prettyPrint; - @XmlAttribute @Metadata(defaultValue = "XStream") + @XmlAttribute + @Metadata(defaultValue = "XStream") private JsonLibrary library = JsonLibrary.XStream; @XmlAttribute private String unmarshalTypeName; @@ -75,7 +80,9 @@ public class JsonDataFormat extends DataFormatDefinition { private String permissions; @XmlAttribute private Boolean allowUnmarshallType; - + @XmlAttribute + private String timezone; + public JsonDataFormat() { super("json"); } @@ -89,7 +96,8 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * Lookup and use the existing ObjectMapper with the given id when using Jackson. + * Lookup and use the existing ObjectMapper with the given id when using + * Jackson. */ public void setObjectMapper(String objectMapper) { this.objectMapper = objectMapper; @@ -146,9 +154,10 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * When marshalling a POJO to JSON you might want to exclude certain fields from the JSON output. - * With Jackson you can use JSON views to accomplish this. This option is to refer to the class - * which has @JsonView annotations + * When marshalling a POJO to JSON you might want to exclude certain fields + * from the JSON output. With Jackson you can use JSON views to accomplish + * this. This option is to refer to the class which has @JsonView + * annotations */ public void setJsonView(Class<?> jsonView) { this.jsonView = jsonView; @@ -159,8 +168,9 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * If you want to marshal a pojo to JSON, and the pojo has some fields with null values. - * And you want to skip these null values, you can set this option to <tt>NOT_NULL</tt> + * If you want to marshal a pojo to JSON, and the pojo has some fields with + * null values. And you want to skip these null values, you can set this + * option to <tt>NOT_NULL</tt> */ public void setInclude(String include) { this.include = include; @@ -171,8 +181,8 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * Used for JMS users to allow the JMSType header from the JMS spec to specify a FQN classname - * to use to unmarshal to. + * Used for JMS users to allow the JMSType header from the JMS spec to + * specify a FQN classname to use to unmarshal to. */ public void setAllowJmsType(Boolean allowJmsType) { this.allowJmsType = allowJmsType; @@ -183,8 +193,9 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * Refers to a custom collection type to lookup in the registry to use. This option should rarely be used, but allows - * to use different collection types than java.util.Collection based as default. + * Refers to a custom collection type to lookup in the registry to use. This + * option should rarely be used, but allows to use different collection + * types than java.util.Collection based as default. */ public void setCollectionTypeName(String collectionTypeName) { this.collectionTypeName = collectionTypeName; @@ -206,8 +217,8 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * Whether to enable the JAXB annotations module when using jackson. When enabled then JAXB annotations - * can be used by Jackson. + * Whether to enable the JAXB annotations module when using jackson. When + * enabled then JAXB annotations can be used by Jackson. */ public void setEnableJaxbAnnotationModule(Boolean enableJaxbAnnotationModule) { this.enableJaxbAnnotationModule = enableJaxbAnnotationModule; @@ -218,8 +229,9 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * To use custom Jackson modules com.fasterxml.jackson.databind.Module specified as a String with FQN class names. - * Multiple classes can be separated by comma. + * To use custom Jackson modules com.fasterxml.jackson.databind.Module + * specified as a String with FQN class names. Multiple classes can be + * separated by comma. */ public void setModuleClassNames(String moduleClassNames) { this.moduleClassNames = moduleClassNames; @@ -230,8 +242,8 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * To use custom Jackson modules referred from the Camel registry. - * Multiple modules can be separated by comma. + * To use custom Jackson modules referred from the Camel registry. Multiple + * modules can be separated by comma. */ public void setModuleRefs(String moduleRefs) { this.moduleRefs = moduleRefs; @@ -242,10 +254,13 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * Set of features to enable on the Jackson <tt>com.fasterxml.jackson.databind.ObjectMapper</tt>. + * Set of features to enable on the Jackson + * <tt>com.fasterxml.jackson.databind.ObjectMapper</tt>. * <p/> - * The features should be a name that matches a enum from <tt>com.fasterxml.jackson.databind.SerializationFeature</tt>, - * <tt>com.fasterxml.jackson.databind.DeserializationFeature</tt>, or <tt>com.fasterxml.jackson.databind.MapperFeature</tt> + * The features should be a name that matches a enum from + * <tt>com.fasterxml.jackson.databind.SerializationFeature</tt>, + * <tt>com.fasterxml.jackson.databind.DeserializationFeature</tt>, or + * <tt>com.fasterxml.jackson.databind.MapperFeature</tt> * <p/> * Multiple features can be separated by comma */ @@ -258,10 +273,13 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * Set of features to disable on the Jackson <tt>com.fasterxml.jackson.databind.ObjectMapper</tt>. + * Set of features to disable on the Jackson + * <tt>com.fasterxml.jackson.databind.ObjectMapper</tt>. * <p/> - * The features should be a name that matches a enum from <tt>com.fasterxml.jackson.databind.SerializationFeature</tt>, - * <tt>com.fasterxml.jackson.databind.DeserializationFeature</tt>, or <tt>com.fasterxml.jackson.databind.MapperFeature</tt> + * The features should be a name that matches a enum from + * <tt>com.fasterxml.jackson.databind.SerializationFeature</tt>, + * <tt>com.fasterxml.jackson.databind.DeserializationFeature</tt>, or + * <tt>com.fasterxml.jackson.databind.MapperFeature</tt> * <p/> * Multiple features can be separated by comma */ @@ -274,18 +292,20 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * Adds permissions that controls which Java packages and classes XStream is allowed to use during - * unmarshal from xml/json to Java beans. + * Adds permissions that controls which Java packages and classes XStream is + * allowed to use during unmarshal from xml/json to Java beans. * <p/> - * A permission must be configured either here or globally using a JVM system property. The permission - * can be specified in a syntax where a plus sign is allow, and minus sign is deny. - * <br/> - * Wildcards is supported by using <tt>.*</tt> as prefix. For example to allow <tt>com.foo</tt> and all subpackages - * then specfy <tt>+com.foo.*</tt>. Multiple permissions can be configured separated by comma, such as - * <tt>+com.foo.*,-com.foo.bar.MySecretBean</tt>. - * <br/> - * The following default permission is always included: <tt>"-*,java.lang.*,java.util.*"</tt> unless - * its overridden by specifying a JVM system property with they key <tt>org.apache.camel.xstream.permissions</tt>. + * A permission must be configured either here or globally using a JVM + * system property. The permission can be specified in a syntax where a plus + * sign is allow, and minus sign is deny. <br/> + * Wildcards is supported by using <tt>.*</tt> as prefix. For example to + * allow <tt>com.foo</tt> and all subpackages then specfy + * <tt>+com.foo.*</tt>. Multiple permissions can be configured separated by + * comma, such as <tt>+com.foo.*,-com.foo.bar.MySecretBean</tt>. <br/> + * The following default permission is always included: + * <tt>"-*,java.lang.*,java.util.*"</tt> unless its overridden by specifying + * a JVM system property with they key + * <tt>org.apache.camel.xstream.permissions</tt>. */ public void setPermissions(String permissions) { this.permissions = permissions; @@ -293,6 +313,7 @@ public class JsonDataFormat extends DataFormatDefinition { /** * To add permission for the given pojo classes. + * * @param type the pojo class(es) xstream should use as allowed permission * @see #setPermissions(String) */ @@ -310,7 +331,8 @@ public class JsonDataFormat extends DataFormatDefinition { } /** - * If enabled then Jackson is allowed to attempt to use the CamelJacksonUnmarshalType header during the unmarshalling. + * If enabled then Jackson is allowed to attempt to use the + * CamelJacksonUnmarshalType header during the unmarshalling. * <p/> * This should only be enabled when desired to be used. */ @@ -318,6 +340,19 @@ public class JsonDataFormat extends DataFormatDefinition { this.allowUnmarshallType = allowUnmarshallType; } + public String getTimezone() { + return timezone; + } + + /** + * If set then Jackson will use the Timezone when marshalling/unmarshalling. + * This option will have no effect on the others Json DataFormat, like gson, + * fastjson and xstream. + */ + public void setTimezone(String timezone) { + this.timezone = timezone; + } + @Override public String getDataFormatName() { // json data format is special as the name can be from different bundles @@ -405,7 +440,8 @@ public class JsonDataFormat extends DataFormatDefinition { if (allowUnmarshallType != null) { setProperty(camelContext, dataFormat, "allowUnmarshallType", allowUnmarshallType); } - // if we have the unmarshal type, but no permission set, then use it to be allowed + // if we have the unmarshal type, but no permission set, then use it to + // be allowed if (permissions == null && unmarshalType != null) { String allow = "+" + unmarshalType.getName(); setProperty(camelContext, dataFormat, "permissions", allow); diff --git a/components/camel-jackson/src/main/docs/json-jackson-dataformat.adoc b/components/camel-jackson/src/main/docs/json-jackson-dataformat.adoc index cf6d114..1233cd8 100644 --- a/components/camel-jackson/src/main/docs/json-jackson-dataformat.adoc +++ b/components/camel-jackson/src/main/docs/json-jackson-dataformat.adoc @@ -17,7 +17,7 @@ from("activemq:My.Queue"). // dataformat options: START -The JSon Jackson dataformat supports 17 options which are listed below. +The JSon Jackson dataformat supports 18 options which are listed below. @@ -40,6 +40,7 @@ The JSon Jackson dataformat supports 17 options which are listed below. | disableFeatures | | String | Set of features to disable on the Jackson com.fasterxml.jackson.databind.ObjectMapper. The features should be a name that matches a enum from com.fasterxml.jackson.databind.SerializationFeature com.fasterxml.jackson.databind.DeserializationFeature or com.fasterxml.jackson.databind.MapperFeature Multiple features can be separated by comma | permissions | | String | Adds permissions that controls which Java packages and classes XStream is allowed to use during unmarshal from xml/json to Java beans. A permission must be configured either here or globally using a JVM system property. The permission can be specified in a syntax where a plus sign is allow and minus sign is deny. Wildcards is supported by using . as prefix. For example to allow com.foo and all subpackages then specfy com.foo.. Multiple permissions can be confi [...] | allowUnmarshallType | false | Boolean | If enabled then Jackson is allowed to attempt to use the CamelJacksonUnmarshalType header during the unmarshalling. This should only be enabled when desired to be used. +| timezone | | String | If set then Jackson will use the Timezone when marshalling/unmarshalling. This option will have no effect on the others Json DataFormat like gson fastjson and xstream. | contentTypeHeader | false | Boolean | Whether the data format should set the Content-Type header with the type from the data format if the data format is capable of doing so. For example application/xml for data formats marshalling to XML or application/json for data formats marshalling to JSon etc. |=== // dataformat options: END diff --git a/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java b/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java index ce981a7..dd86f70 100644 --- a/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java +++ b/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TimeZone; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -34,6 +35,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.CollectionType; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; + import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; import org.apache.camel.Exchange; @@ -46,8 +48,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * A <a href="http://camel.apache.org/data-format.html">data format</a> ({@link DataFormat}) - * using <a href="http://jackson.codehaus.org/">Jackson</a> to marshal to and from JSON. + * A <a href="http://camel.apache.org/data-format.html">data format</a> + * ({@link DataFormat}) using <a href="http://jackson.codehaus.org/">Jackson</a> + * to marshal to and from JSON. */ public class JacksonDataFormat extends ServiceSupport implements DataFormat, DataFormatName, CamelContextAware { @@ -71,6 +74,7 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat private boolean enableJacksonTypeConverter; private boolean allowUnmarshallType; private boolean contentTypeHeader = true; + private TimeZone timezone; /** * Use the default Jackson {@link ObjectMapper} and {@link Object} @@ -80,8 +84,8 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat } /** - * Use the default Jackson {@link ObjectMapper} and with a custom - * unmarshal type + * Use the default Jackson {@link ObjectMapper} and with a custom unmarshal + * type * * @param unmarshalType the custom unmarshal type */ @@ -90,25 +94,28 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat } /** - * Use the default Jackson {@link ObjectMapper} and with a custom - * unmarshal type and JSON view + * Use the default Jackson {@link ObjectMapper} and with a custom unmarshal + * type and JSON view * * @param unmarshalType the custom unmarshal type - * @param jsonView marker class to specify properties to be included during marshalling. - * See also http://wiki.fasterxml.com/JacksonJsonViews + * @param jsonView marker class to specify properties to be included during + * marshalling. See also + * http://wiki.fasterxml.com/JacksonJsonViews */ public JacksonDataFormat(Class<?> unmarshalType, Class<?> jsonView) { this(unmarshalType, jsonView, true); } - + /** - * Use the default Jackson {@link ObjectMapper} and with a custom - * unmarshal type and JSON view + * Use the default Jackson {@link ObjectMapper} and with a custom unmarshal + * type and JSON view * * @param unmarshalType the custom unmarshal type - * @param jsonView marker class to specify properties to be included during marshalling. - * See also http://wiki.fasterxml.com/JacksonJsonViews - * @param enableJaxbAnnotationModule if it is true, will enable the JaxbAnnotationModule. + * @param jsonView marker class to specify properties to be included during + * marshalling. See also + * http://wiki.fasterxml.com/JacksonJsonViews + * @param enableJaxbAnnotationModule if it is true, will enable the + * JaxbAnnotationModule. */ public JacksonDataFormat(Class<?> unmarshalType, Class<?> jsonView, boolean enableJaxbAnnotationModule) { this.unmarshalType = unmarshalType; @@ -119,7 +126,7 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat /** * Use a custom Jackson mapper and and unmarshal type * - * @param mapper the custom mapper + * @param mapper the custom mapper * @param unmarshalType the custom unmarshal type */ public JacksonDataFormat(ObjectMapper mapper, Class<?> unmarshalType) { @@ -129,10 +136,11 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat /** * Use a custom Jackson mapper, unmarshal type and JSON view * - * @param mapper the custom mapper + * @param mapper the custom mapper * @param unmarshalType the custom unmarshal type - * @param jsonView marker class to specify properties to be included during marshalling. - * See also http://wiki.fasterxml.com/JacksonJsonViews + * @param jsonView marker class to specify properties to be included during + * marshalling. See also + * http://wiki.fasterxml.com/JacksonJsonViews */ public JacksonDataFormat(ObjectMapper mapper, Class<?> unmarshalType, Class<?> jsonView) { this.objectMapper = mapper; @@ -284,8 +292,8 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat } /** - * To use custom Jackson {@link Module}s specified as a String with FQN class names. - * Multiple classes can be separated by comma. + * To use custom Jackson {@link Module}s specified as a String with FQN + * class names. Multiple classes can be separated by comma. */ public void setModuleClassNames(String moduleClassNames) { this.moduleClassNames = moduleClassNames; @@ -296,8 +304,8 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat } /** - * To use custom Jackson modules referred from the Camel registry. - * Multiple modules can be separated by comma. + * To use custom Jackson modules referred from the Camel registry. Multiple + * modules can be separated by comma. */ public void setModuleRefs(String moduleRefs) { this.moduleRefs = moduleRefs; @@ -319,7 +327,8 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat } /** - * Allows jackson to use the <tt>JMSType</tt> header as an indicator what the classname is for unmarshaling json content to POJO + * Allows jackson to use the <tt>JMSType</tt> header as an indicator what + * the classname is for unmarshaling json content to POJO * <p/> * By default this option is <tt>false</tt>. */ @@ -332,21 +341,24 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat } /** - * If enabled then Jackson is allowed to attempt to be used during Camels <a href="https://camel.apache.org/type-converter.html">type converter</a> - * as a {@link org.apache.camel.FallbackConverter} that attempts to convert POJOs to/from {@link Map}/{@link List} types. + * If enabled then Jackson is allowed to attempt to be used during Camels + * <a href="https://camel.apache.org/type-converter.html">type converter</a> + * as a {@link org.apache.camel.FallbackConverter} that attempts to convert + * POJOs to/from {@link Map}/{@link List} types. * <p/> * This should only be enabled when desired to be used. */ public void setEnableJacksonTypeConverter(boolean enableJacksonTypeConverter) { this.enableJacksonTypeConverter = enableJacksonTypeConverter; } - + public boolean isAllowUnmarshallType() { return allowUnmarshallType; } /** - * If enabled then Jackson is allowed to attempt to use the CamelJacksonUnmarshalType header during the unmarshalling. + * If enabled then Jackson is allowed to attempt to use the + * CamelJacksonUnmarshalType header during the unmarshalling. * <p/> * This should only be enabled when desired to be used. */ @@ -359,19 +371,33 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat } /** - * If enabled then Jackson will set the Content-Type header to <tt>application/json</tt> when marshalling. + * If enabled then Jackson will set the Content-Type header to + * <tt>application/json</tt> when marshalling. */ public void setContentTypeHeader(boolean contentTypeHeader) { this.contentTypeHeader = contentTypeHeader; } + public TimeZone getTimezone() { + return timezone; + } + + /** + * If set then Jackson will use the Timezone when marshalling/unmarshalling. + */ + public void setTimezone(TimeZone timezone) { + this.timezone = timezone; + } + public String getEnableFeatures() { return enableFeatures; } /** - * Set of features to enable on the Jackson {@link ObjectMapper}. - * The features should be a name that matches a enum from {@link SerializationFeature}, {@link DeserializationFeature}, or {@link MapperFeature}. + * Set of features to enable on the Jackson {@link ObjectMapper}. The + * features should be a name that matches a enum from + * {@link SerializationFeature}, {@link DeserializationFeature}, or + * {@link MapperFeature}. */ public void setEnableFeatures(String enableFeatures) { this.enableFeatures = enableFeatures; @@ -382,8 +408,10 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat } /** - * Set of features to disable on the Jackson {@link ObjectMapper}. - * The features should be a name that matches a enum from {@link SerializationFeature}, {@link DeserializationFeature}, or {@link MapperFeature}. + * Set of features to disable on the Jackson {@link ObjectMapper}. The + * features should be a name that matches a enum from + * {@link SerializationFeature}, {@link DeserializationFeature}, or + * {@link MapperFeature}. */ public void setDisableFeatures(String disableFeatures) { this.disableFeatures = disableFeatures; @@ -455,7 +483,7 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat LOG.debug("Creating new ObjectMapper to use: {}", objectMapper); } } - + if (enableJaxbAnnotationModule) { // Enables JAXB processing JaxbAnnotationModule module = new JaxbAnnotationModule(); @@ -494,7 +522,8 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat objectMapper.enable(mf); continue; } - throw new IllegalArgumentException("Enable feature: " + enable + " cannot be converted to an accepted enum of types [SerializationFeature,DeserializationFeature,MapperFeature]"); + throw new IllegalArgumentException("Enable feature: " + enable + + " cannot be converted to an accepted enum of types [SerializationFeature,DeserializationFeature,MapperFeature]"); } } if (disableFeatures != null) { @@ -517,7 +546,8 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat objectMapper.disable(mf); continue; } - throw new IllegalArgumentException("Disable feature: " + disable + " cannot be converted to an accepted enum of types [SerializationFeature,DeserializationFeature,MapperFeature]"); + throw new IllegalArgumentException("Disable feature: " + disable + + " cannot be converted to an accepted enum of types [SerializationFeature,DeserializationFeature,MapperFeature]"); } } @@ -549,6 +579,10 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat, Dat objectMapper.registerModule(module); } } + if (ObjectHelper.isNotEmpty(timezone)) { + LOG.debug("Setting timezone to Object Mapper: {}", timezone); + objectMapper.setTimeZone(timezone); + } } @Override diff --git a/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/JacksonMarshalDateTimezoneTest.java b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/JacksonMarshalDateTimezoneTest.java new file mode 100644 index 0000000..30457e8 --- /dev/null +++ b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/JacksonMarshalDateTimezoneTest.java @@ -0,0 +1,60 @@ +/** + * 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.camel.component.jackson; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class JacksonMarshalDateTimezoneTest extends CamelTestSupport { + + @Test + public void testMarshalDate() throws Exception { + GregorianCalendar in = new GregorianCalendar(2017, Calendar.APRIL, 25, 17, 0, 10); + + MockEndpoint mock = getMockEndpoint("mock:result"); + + Object marshalled = template.requestBody("direct:in", in.getTime()); + String marshalledAsString = context.getTypeConverter().convertTo(String.class, marshalled); + assertEquals("1493132410000", marshalledAsString); + + mock.expectedMessageCount(1); + + mock.assertIsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + + @Override + public void configure() throws Exception { + JacksonDataFormat format = new JacksonDataFormat(); + TimeZone timeZone = TimeZone.getTimeZone("Africa/Ouagadougou"); + format.setTimezone(timeZone); + + from("direct:in").marshal(format).to("mock:result"); + } + }; + } + +} diff --git a/components/camel-jacksonxml/src/main/java/org/apache/camel/component/jacksonxml/JacksonXMLDataFormat.java b/components/camel-jacksonxml/src/main/java/org/apache/camel/component/jacksonxml/JacksonXMLDataFormat.java index eeaddcc..3c63d20 100644 --- a/components/camel-jacksonxml/src/main/java/org/apache/camel/component/jacksonxml/JacksonXMLDataFormat.java +++ b/components/camel-jacksonxml/src/main/java/org/apache/camel/component/jacksonxml/JacksonXMLDataFormat.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.TimeZone; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -33,6 +34,7 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.CollectionType; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; + import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; import org.apache.camel.Exchange; @@ -45,8 +47,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * A <a href="http://camel.apache.org/data-format.html">data format</a> ({@link DataFormat}) - * using <a href="http://jackson.codehaus.org/">Jackson</a> to marshal to and from XML. + * A <a href="http://camel.apache.org/data-format.html">data format</a> + * ({@link DataFormat}) using <a href="http://jackson.codehaus.org/">Jackson</a> + * to marshal to and from XML. */ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, DataFormatName, CamelContextAware { @@ -70,6 +73,7 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, private boolean enableJacksonTypeConverter; private boolean allowUnmarshallType; private boolean contentTypeHeader = true; + private TimeZone timezone; /** * Use the default Jackson {@link XmlMapper} and {@link Map} @@ -79,8 +83,8 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, } /** - * Use the default Jackson {@link XmlMapper} and with a custom - * unmarshal type + * Use the default Jackson {@link XmlMapper} and with a custom unmarshal + * type * * @param unmarshalType the custom unmarshal type */ @@ -89,25 +93,28 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, } /** - * Use the default Jackson {@link XmlMapper} and with a custom - * unmarshal type and JSON view + * Use the default Jackson {@link XmlMapper} and with a custom unmarshal + * type and JSON view * * @param unmarshalType the custom unmarshal type - * @param jsonView marker class to specify properties to be included during marshalling. - * See also http://wiki.fasterxml.com/JacksonJsonViews + * @param jsonView marker class to specify properties to be included during + * marshalling. See also + * http://wiki.fasterxml.com/JacksonJsonViews */ public JacksonXMLDataFormat(Class<?> unmarshalType, Class<?> jsonView) { this(unmarshalType, jsonView, true); } /** - * Use the default Jackson {@link XmlMapper} and with a custom - * unmarshal type and JSON view + * Use the default Jackson {@link XmlMapper} and with a custom unmarshal + * type and JSON view * - * @param unmarshalType the custom unmarshal type - * @param jsonView marker class to specify properties to be included during marshalling. - * See also http://wiki.fasterxml.com/JacksonJsonViews - * @param enableJaxbAnnotationModule if it is true, will enable the JaxbAnnotationModule. + * @param unmarshalType the custom unmarshal type + * @param jsonView marker class to specify properties to be included during + * marshalling. See also + * http://wiki.fasterxml.com/JacksonJsonViews + * @param enableJaxbAnnotationModule if it is true, will enable the + * JaxbAnnotationModule. */ public JacksonXMLDataFormat(Class<?> unmarshalType, Class<?> jsonView, boolean enableJaxbAnnotationModule) { this.unmarshalType = unmarshalType; @@ -118,7 +125,7 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, /** * Use a custom Jackson mapper and and unmarshal type * - * @param mapper the custom mapper + * @param mapper the custom mapper * @param unmarshalType the custom unmarshal type */ public JacksonXMLDataFormat(XmlMapper mapper, Class<?> unmarshalType) { @@ -128,10 +135,11 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, /** * Use a custom Jackson mapper, unmarshal type and JSON view * - * @param mapper the custom mapper + * @param mapper the custom mapper * @param unmarshalType the custom unmarshal type - * @param jsonView marker class to specify properties to be included during marshalling. - * See also http://wiki.fasterxml.com/JacksonJsonViews + * @param jsonView marker class to specify properties to be included during + * marshalling. See also + * http://wiki.fasterxml.com/JacksonJsonViews */ public JacksonXMLDataFormat(XmlMapper mapper, Class<?> unmarshalType, Class<?> jsonView) { this.xmlMapper = mapper; @@ -283,8 +291,8 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, } /** - * To use custom Jackson {@link Module}s specified as a String with FQN class names. - * Multiple classes can be separated by comma. + * To use custom Jackson {@link Module}s specified as a String with FQN + * class names. Multiple classes can be separated by comma. */ public void setModuleClassNames(String moduleClassNames) { this.moduleClassNames = moduleClassNames; @@ -295,8 +303,8 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, } /** - * To use custom Jackson modules referred from the Camel registry. - * Multiple modules can be separated by comma. + * To use custom Jackson modules referred from the Camel registry. Multiple + * modules can be separated by comma. */ public void setModuleRefs(String moduleRefs) { this.moduleRefs = moduleRefs; @@ -318,7 +326,8 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, } /** - * Allows jackson to use the <tt>JMSType</tt> header as an indicator what the classname is for unmarshaling XML content to POJO + * Allows jackson to use the <tt>JMSType</tt> header as an indicator what + * the classname is for unmarshaling XML content to POJO * <p/> * By default this option is <tt>false</tt>. */ @@ -331,21 +340,24 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, } /** - * If enabled then Jackson is allowed to attempt to be used during Camels <a href="https://camel.apache.org/type-converter.html">type converter</a> - * as a {@link org.apache.camel.FallbackConverter} that attempts to convert POJOs to/from {@link Map}/{@link List} types. + * If enabled then Jackson is allowed to attempt to be used during Camels + * <a href="https://camel.apache.org/type-converter.html">type converter</a> + * as a {@link org.apache.camel.FallbackConverter} that attempts to convert + * POJOs to/from {@link Map}/{@link List} types. * <p/> * This should only be enabled when desired to be used. */ public void setEnableJacksonTypeConverter(boolean enableJacksonTypeConverter) { this.enableJacksonTypeConverter = enableJacksonTypeConverter; } - + public boolean isAllowUnmarshallType() { return allowUnmarshallType; } /** - * If enabled then Jackson is allowed to attempt to use the CamelJacksonUnmarshalType header during the unmarshalling. + * If enabled then Jackson is allowed to attempt to use the + * CamelJacksonUnmarshalType header during the unmarshalling. * <p/> * This should only be enabled when desired to be used. */ @@ -358,19 +370,32 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, } /** - * If enabled then Jackson will set the Content-Type header to <tt>application/xml</tt> when marshalling. + * If enabled then Jackson will set the Content-Type header to + * <tt>application/xml</tt> when marshalling. */ public void setContentTypeHeader(boolean contentTypeHeader) { this.contentTypeHeader = contentTypeHeader; } + public TimeZone getTimezone() { + return timezone; + } + + /** + * If set then Jackson will use the Timezone when marshalling/unmarshalling. + */ + public void setTimezone(TimeZone timezone) { + this.timezone = timezone; + } + public String getEnableFeatures() { return enableFeatures; } /** - * Set of features to enable on the Jackson {@link XmlMapper}. - * The features should be a name that matches a enum from {@link SerializationFeature}, {@link DeserializationFeature}, or {@link MapperFeature}. + * Set of features to enable on the Jackson {@link XmlMapper}. The features + * should be a name that matches a enum from {@link SerializationFeature}, + * {@link DeserializationFeature}, or {@link MapperFeature}. */ public void setEnableFeatures(String enableFeatures) { this.enableFeatures = enableFeatures; @@ -381,8 +406,9 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, } /** - * Set of features to disable on the Jackson {@link XmlMapper}. - * The features should be a name that matches a enum from {@link SerializationFeature}, {@link DeserializationFeature}, or {@link MapperFeature}. + * Set of features to disable on the Jackson {@link XmlMapper}. The features + * should be a name that matches a enum from {@link SerializationFeature}, + * {@link DeserializationFeature}, or {@link MapperFeature}. */ public void setDisableFeatures(String disableFeatures) { this.disableFeatures = disableFeatures; @@ -480,7 +506,8 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, xmlMapper.enable(mf); continue; } - throw new IllegalArgumentException("Enable feature: " + enable + " cannot be converted to an accepted enum of types [SerializationFeature,DeserializationFeature,MapperFeature]"); + throw new IllegalArgumentException("Enable feature: " + enable + + " cannot be converted to an accepted enum of types [SerializationFeature,DeserializationFeature,MapperFeature]"); } } if (disableFeatures != null) { @@ -503,7 +530,8 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, xmlMapper.disable(mf); continue; } - throw new IllegalArgumentException("Disable feature: " + disable + " cannot be converted to an accepted enum of types [SerializationFeature,DeserializationFeature,MapperFeature]"); + throw new IllegalArgumentException("Disable feature: " + disable + + " cannot be converted to an accepted enum of types [SerializationFeature,DeserializationFeature,MapperFeature]"); } } @@ -535,6 +563,10 @@ public class JacksonXMLDataFormat extends ServiceSupport implements DataFormat, xmlMapper.registerModule(module); } } + if (ObjectHelper.isNotEmpty(timezone)) { + LOG.debug("Setting timezone to XML Mapper: {}", timezone); + xmlMapper.setTimeZone(timezone); + } } @Override diff --git a/components/camel-jacksonxml/src/test/java/org/apache/camel/component/jacksonxml/JacksonMarshalDateTimezoneTest.java b/components/camel-jacksonxml/src/test/java/org/apache/camel/component/jacksonxml/JacksonMarshalDateTimezoneTest.java new file mode 100644 index 0000000..740b8aa --- /dev/null +++ b/components/camel-jacksonxml/src/test/java/org/apache/camel/component/jacksonxml/JacksonMarshalDateTimezoneTest.java @@ -0,0 +1,60 @@ +/** + * 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.camel.component.jacksonxml; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class JacksonMarshalDateTimezoneTest extends CamelTestSupport { + + @Test + public void testMarshalDate() throws Exception { + GregorianCalendar in = new GregorianCalendar(2017, Calendar.APRIL, 25, 17, 0, 10); + + MockEndpoint mock = getMockEndpoint("mock:result"); + + Object marshalled = template.requestBody("direct:in", in.getTime()); + String marshalledAsString = context.getTypeConverter().convertTo(String.class, marshalled); + assertEquals("<Date>1493132410000</Date>", marshalledAsString); + + mock.expectedMessageCount(1); + + mock.assertIsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + + @Override + public void configure() throws Exception { + JacksonXMLDataFormat format = new JacksonXMLDataFormat(); + TimeZone timeZone = TimeZone.getTimeZone("Africa/Ouagadougou"); + format.setTimezone(timeZone); + + from("direct:in").marshal(format).to("mock:result"); + } + }; + } + +} diff --git a/platforms/spring-boot/components-starter/camel-jackson-starter/src/main/java/org/apache/camel/component/jackson/springboot/JacksonDataFormatConfiguration.java b/platforms/spring-boot/components-starter/camel-jackson-starter/src/main/java/org/apache/camel/component/jackson/springboot/JacksonDataFormatConfiguration.java index e3bca66..c6c0130 100644 --- a/platforms/spring-boot/components-starter/camel-jackson-starter/src/main/java/org/apache/camel/component/jackson/springboot/JacksonDataFormatConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-jackson-starter/src/main/java/org/apache/camel/component/jackson/springboot/JacksonDataFormatConfiguration.java @@ -135,6 +135,12 @@ public class JacksonDataFormatConfiguration */ private Boolean allowUnmarshallType = false; /** + * If set then Jackson will use the Timezone when marshalling/unmarshalling. + * This option will have no effect on the others Json DataFormat like gson + * fastjson and xstream. + */ + private String timezone; + /** * Whether the data format should set the Content-Type header with the type * from the data format if the data format is capable of doing so. For * example application/xml for data formats marshalling to XML or @@ -270,6 +276,14 @@ public class JacksonDataFormatConfiguration this.allowUnmarshallType = allowUnmarshallType; } + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + public Boolean getContentTypeHeader() { return contentTypeHeader; } -- To stop receiving notification emails like this one, please contact "commits@camel.apache.org" <commits@camel.apache.org>.