如何在 Jersey 客户端中默认使用 Genson 提供程序?
Posted
技术标签:
【中文标题】如何在 Jersey 客户端中默认使用 Genson 提供程序?【英文标题】:How to use Genson provider as default in Jersey client? 【发布时间】:2015-08-11 01:47:21 【问题描述】:我有一个基于 Jersey 框架的简单客户端。
我想使用 Genson 作为默认 JSON 提供程序。
首先我创建了一些实现ContextResolver
的类:
@Provider
public class GensonCustomResolver implements ContextResolver<Genson>
private final Genson genson = new Genson.Builder().setSkipNull(true).setDateFormat(new UtcDateFormat()).create();
@Override
public Genson getContext(Class<?> type)
return genson;
还有 UtcDateFormat 类:
public class UtcDateFormat extends DateFormat
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition)
return new StringBuffer("" + date.getTime());
@Override
public Date parse(String source, ParsePosition pos)
return new Date(Long.parseLong(source));
然后我用这个:
ClientConfig cfg = new DefaultClientConfig(GensonCustomResolver.class);
Client client = Client.create(cfg);
Integer meetingId = 1;
Meeting result = client.resource("http://mywebservise.com/").path("meeting")
.path(meetingId.toString()).get(ClientResponse.class).getEntity(Meeting.class);
但是,它失败了。以下是日志:
javax.ws.rs.WebApplicationException: com.owlike.genson.TransformationException: Could not deserialize to property 'created' of class class com.mypack.model.Meeting
at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:127)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:565)
at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:517)
at com.mypack.ws.MeetingsTest.getItem(MeetingsTest.java:159)
at com.mypack.ws.MeetingsTest.getItem(MeetingsTest.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:659)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:845)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1153)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:771)
at org.testng.TestRunner.run(TestRunner.java:621)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:357)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:352)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:310)
at org.testng.SuiteRunner.run(SuiteRunner.java:259)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1199)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1124)
at org.testng.TestNG.run(TestNG.java:1032)
at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:110)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:113)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: com.owlike.genson.TransformationException: Could not deserialize to property 'created' of class class com.mypack.model.Meeting
at com.owlike.genson.reflect.PropertyMutator.couldNotDeserialize(PropertyMutator.java:56)
at com.owlike.genson.reflect.PropertyMutator.deserialize(PropertyMutator.java:39)
at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:116)
at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:98)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:61)
at com.owlike.genson.Genson.deserialize(Genson.java:452)
at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:125)
... 48 more
Caused by: com.owlike.genson.TransformationException: Could not parse date 1432800716000
at com.owlike.genson.convert.DefaultConverters$DateConverter.deserialize(DefaultConverters.java:824)
at com.owlike.genson.convert.DefaultConverters$DateConverter.deserialize(DefaultConverters.java:788)
at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:61)
at com.owlike.genson.reflect.PropertyMutator.deserialize(PropertyMutator.java:37)
... 53 more
Caused by: java.text.ParseException: Unparseable date: "1432800716000"
at java.text.DateFormat.parse(DateFormat.java:357)
at com.owlike.genson.convert.DefaultConverters$DateConverter.read(DefaultConverters.java:830)
at com.owlike.genson.convert.DefaultConverters$DateConverter.deserialize(DefaultConverters.java:822)
... 56 more
怎么了? 附:泽西岛客户端 1.8 根森 0.98
【问题讨论】:
添加 println 以查看是否正在调用getContext
。查看GensonJsonConverter
的来源,看起来您的ContextResolver
应该被选中。如果没有,有一个构造函数可以将ContextResolver
传递给。
我检查了,getContext
被调用。我解决了这个问题。我为Genson.Builder()
使用了额外的配置。添加.useTimeInMillis(true)
而不是setDateFormat(new UtcDateFormat())
))))
【参考方案1】:
你应该升级到最新的 Genson 版本,有一些改进,providing a custom instance 到球衣更容易。
在较新的版本中,Genson 会自动检测输入的时间是毫秒还是日期字符串,并相应地处理它。
使用 useDateFormat(...) 注册的日期格式将在反序列化期间使用,但这也会将日期序列化为字符串。如果您想将它们序列化为 long(这是新版本中的默认值),您可以使用 useDateAsTimestamp(true) 对其进行定义。
我希望这能让事情更清楚一些。您可以查看the config options了解更多详情。
【讨论】:
以上是关于如何在 Jersey 客户端中默认使用 Genson 提供程序?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不手动转换为 JSON 的情况下使用 Jersey 客户端发布 Pojo?
如何让 Jersey 客户端使用 HttpsURLConnection 中设置的 defaultSSLSocketFactory?