JPA字段名称大小写与JSON字段名称不匹配

时间:2014-03-20 01:28:57

标签: java json jpa

我是JPA的新手并尝试将JSON字符串传递给由JPA实体支持的Web服务。但是,我很难搞清楚案例/命名惯例。以下是我的实体中的结构,但是当我传递我的JSON语句时,它需要" userId"和" enrollmentstatus" (注意案例差异)或者它会产生关于"无法识别的字段' enrollmentStatus'"的错误。对于一个人来说,他们坚持使用camelCase而另一个领域都是小写的。它似乎并不一致。我在这里错过或误解了什么?提前谢谢。

@Basic(optional = false)
@NotNull
@Column(name = "USERID")
private long userid;

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "ENROLLMENTSTATUS")
private String enrollmentstatus;

以下错误消息:

javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "enrollmentStatus" (Class entities.LearningActivity), not marked as ignorable
 at [Source: org.glassfish.jersey.message.internal.EntityInputStream@344a5b; line: 1, column: 75] (through reference chain: entities.LearningActivity["enrollmentStatus"])

root cause

org.glassfish.jersey.server.ContainerException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "enrollmentStatus" (Class entities.LearningActivity), not marked as ignorable
 at [Source: org.glassfish.jersey.message.internal.EntityInputStream@344a5b; line: 1, column: 75] (through reference chain: entities.LearningActivity["enrollmentStatus"])

JSON字符串:

{"移动":0,"用户id":12345" learngingActivityId" 134" enrollmentStatus":" C"" dateTimeEnrolled":" 2014-03-20T00:08:30.18375Z"" dateTimeCompleted":" 2014-03-20T00 :08:30.18375Z"" hoursSpent":0.0"得分":13.0,"通过":假," instructorNotes" :" u0000的"" studentComments":" u0000的"" internalData":" u0000的"}

EntityFacade代码:

@POST
@Override
@Consumes({"application/xml", "application/json"})
@Path("add")
public void create(LearningActivity entity) {
    super.create(entity);
}

日志文件:

[2014-03-20T08:01:51.777-0700] [glassfish 4.0] [FINE] [] [org.glassfish.jersey.server.wadl.internal.generators.WadlGeneratorJAXBGrammarGenerator] [tid: _ThreadID=111 _ThreadName=http-listener-1(3)] [timeMillis: 1395327711777] [levelValue: 500] [CLASSNAME: org.glassfish.jersey.server.wadl.internal.generators.WadlGeneratorJAXBGrammarGenerator$6] [METHODNAME: resolve] [[

java.lang.InstantiationException
    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.glassfish.jersey.server.wadl.internal.generators.WadlGeneratorJAXBGrammarGenerator$6.resolve(WadlGeneratorJAXBGrammarGenerator.java:420)
    at org.glassfish.jersey.server.wadl.WadlGenerator$ExternalGrammarDefinition.resolve(WadlGenerator.java:179)
    at org.glassfish.jersey.server.wadl.internal.ApplicationDescription.resolve(ApplicationDescription.java:82)
    at org.glassfish.jersey.server.wadl.internal.generators.WadlGeneratorJAXBGrammarGenerator.attachTypes(WadlGeneratorJAXBGrammarGenerator.java:481)
    at org.glassfish.jersey.server.wadl.internal.WadlBuilder.generate(WadlBuilder.java:149)
    at org.glassfish.jersey.server.wadl.internal.WadlApplicationContextImpl.getApplication(WadlApplicationContextImpl.java:153)
    at org.glassfish.jersey.server.wadl.processor.WadlModelProcessor$OptionsHandler.apply(WadlModelProcessor.java:134)
    at org.glassfish.jersey.server.wadl.processor.WadlModelProcessor$OptionsHandler.apply(WadlModelProcessor.java:118)
    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.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:125)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ObjectOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:167)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:91)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:346)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:341)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:224)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:198)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:946)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:323)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:724)
]]

[2014-03-20T08:01:51.779-0700] [glassfish 4.0] [FINE] [] [org.glassfish.jersey.server.wadl.internal.generators.WadlGeneratorJAXBGrammarGenerator] [tid: _ThreadID=111 _ThreadName=http-listener-1(3)] [timeMillis: 1395327711779] [levelValue: 500] [CLASSNAME: org.glassfish.jersey.server.wadl.internal.generators.WadlGeneratorJAXBGrammarGenerator] [METHODNAME: attachTypes] [[
  Couldn't find JAX-B element for class javax.ws.rs.core.Response]]

2 个答案:

答案 0 :(得分:3)

原始错误消息很好地表明了正在发生的事情:

  

org.codehaus.jackson.map.exc.UnrecognizedPropertyException:无法识别的字段“enrollmentStatus”(类entities.LearningActivity),未标记为可忽略

由案件差异引起。 Jackson是GF使用的JSON序列化器/解串器,它尝试在JSON文件和实体类之间执行区分大小写的匹配 - 并且失败。我看到三种可能的解决方案:

最简单的一个,更改实体字段的名称以匹配JSON案例

或者,只需添加@JsonProperty注释即可告诉Jackson实体字段enrollmentstatus应映射到JSON字段enrollmentStatus

@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "ENROLLMENTSTATUS")
@JsonProperty("enrollmentStatus")
private String enrollmentstatus;

最后但我认为它有点乱,使用JSON侧套管为现场提供吸气剂和固定器

public String getEnrollmentStatus() {
    return enrollmentstatus;
}

public void setEnrollmentStatus(String value) {
    this.enrollmentstatus = value;
}

关于那个堆栈跟踪,我发现案例问题与该问题之间没有明显的联系(但是人们永远都不知道)。如果错误没有消失,你已经修复了案例问题,除非你真的需要这个功能,否则尝试禁用WADL生成可能是值得的。该程序在Jersey documentation中解释,其实质是

  

默认情况下,在Jersey中启用WADL生成。这意味着默认情况下会将OPTIONS方法添加到每个资源,并且还会部署自动生成的/application.wadl资源。要覆盖此默认行为并在Jersey中禁用WADL生成,请在应用程序中设置配置属性:

     

jersey.config.server.wadl.disableWadl =真

     

如果Jersey应用程序部署在带有web.xml的servlet中,或者可以从Application返回属性,则可以在web.xml中设置此属性。的GetProperties()。有关在各种部署中设置应用程序配置属性的详细信息,请参阅部署一章。

答案 1 :(得分:0)

最后解决了不一致的案例。看来JSON字段名称的大小写必须与getter / setter函数匹配,而不是实际的变量/字段名称。在我的例子中,我手动向实体添加了两个字段,但是使用了camel case作为get / set名称。即, getLearningActivityId setLearningActivityId ,getUserId和setUserId。只要我将我的get / set方法更改为 setLearningactivityid getLearningactivityid ,一切都是一致的。线索来了,当我注意到Netbeans创建的所有get / set方法的格式之后,只有get / set之后的第一个字母大写。显然,Jackson在get / set方法的前三个字母(包括case)之后抓取名称,并使用方法名称的右手部分作为匹配的名称,并用。创建JSON字符串。