无法将 JSON 值反序列化为类型
Failed to de-serialize JSON value into type
我试图在我的网络服务中反序列化一个 post 请求,但我最终得到一个 HTTP 500 说 javax.json.bind.JsonbException: Error deserialize JSON value into type: class [C
。我正在使用 Jackson 来处理 JSON 的东西。
这是我从 Postman 发送的 JSON 字符串:
{"firstName":"FirstName","middleName":"middleName","lastName":"LastName","name":"SomeName","password":"[=11=]meR@nd0m","creationTimeStamp":1533950475466}
这是我的 POJO:
@XmlRootElement
public class UserFormInterceptor {
@Pattern(regexp = "^[\S][\p{L} .'-]+$") @Size(min = 2, max = 64) @NotEmpty @NotNull
private String firstName;
@Pattern(regexp = "^[\S][\p{L} .'-]+$") @Size(min = 2, max = 64)
private String middleName;
@Pattern(regexp = "^[\S][\p{L} .'-]+$") @Size(min = 2, max = 64) @NotEmpty @NotNull
private String lastName;
@Pattern(regexp = "^[a-zA-z][\w]*$") @Size(min = 8, max = 64) @NotEmpty @NotNull
private String name;
@Pattern(regexp = "(?=.*?[A-Z]+)(?=.*?[0-9]+)(?=.*?[\p{Punct}]+).*") @Size(min = 8, max = 64) @NotEmpty @NotNull
private char[] password;
@Positive @NotEmpty @NotNull
private long creationTimeStamp;
public UserFormInterceptor() {}
public UserFormInterceptor(@NotNull String name, @NotNull String password, @Positive long creationTimeStamp, @NotNull String firstName, String middleName, @NotNull String lastName) {
this.name = name;
this.password = password.toCharArray();
this.creationTimeStamp = creationTimeStamp;
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
}
@NotNull
public String getFirstName() {
return firstName;
}
public void setFirstName(@NotNull String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
@NotNull
public String getLastName() {
return lastName;
}
public void setLastName(@NotNull String lastName) {
this.lastName = lastName;
}
@NotNull
public String getName() {
return name;
}
public void setName(@NotNull String name) {
this.name = name;
}
@NotNull
public char[] getPassword() {
return password;
}
public void setPassword(@NotNull String password) {
this.password = password.toCharArray();
}
public long getCreationTimeStamp() {
return creationTimeStamp;
}
public void setCreationTimeStamp(long creationTimeStamp) {
this.creationTimeStamp = creationTimeStamp;
}
public Map<String, Object> buildMap() {
Map<String,Object> returnMap = new HashMap<>();
returnMap.put("name",this.getName());
returnMap.put("firstName",this.firstName);
returnMap.put("middleName",this.middleName==null ? "" : this.middleName);
returnMap.put("lastName",this.lastName);
returnMap.put("creationTimeStamp",Long.toString(this.getCreationTimeStamp()));
return returnMap;
}
}
这是我的请求处理程序class:
@Path("/users")
public class UserController {
private static final UserDAO userDao = new UserDAO();
@POST
@Path(value = "/signup")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(value = MediaType.APPLICATION_JSON)
public Response signUpUser(@Valid @NotNull UserFormInterceptor userSignUpForm) {
UserCreatorModel userCreatorModel = (UserCreatorModel) new UserCreatorModel(userSignUpForm)
.setUniqueId();
String response = userDao.addCustomer(userCreatorModel);
return Response.ok(response).build();
}
}
这些是我对 Jackson 的 Maven 依赖项:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider -->
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.6</version>
</dependency>
这是堆栈跟踪:
StandardWrapperValve[Controller Servlet]: Servlet.service() for servlet Controller Servlet threw exception
javax.json.bind.JsonbException: Error deserialize JSON value into type: class [C.
at org.eclipse.yasson.internal.serializer.DeserializerBuilder.build(DeserializerBuilder.java:113)
at org.eclipse.yasson.internal.serializer.ObjectDeserializer.deserializeNext(ObjectDeserializer.java:161)
at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserializeInternal(AbstractContainerDeserializer.java:84)
at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserialize(AbstractContainerDeserializer.java:60)
at org.eclipse.yasson.internal.Unmarshaller.deserializeItem(Unmarshaller.java:57)
at org.eclipse.yasson.internal.Unmarshaller.deserialize(Unmarshaller.java:50)
at org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:45)
at org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:85)
at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.readFrom(JsonBindingProvider.java:99)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:257)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:236)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:73)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1091)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:271)
at org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:97)
at org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:80)
at org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.apply(ParamValueFactoryWithSource.java:74)
at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:92)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:133)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:277)
at org.glassfish.jersey.internal.Errors.call(Errors.java:272)
at org.glassfish.jersey.internal.Errors.call(Errors.java:268)
at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1580)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:652)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:591)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242)
at org.glassfish.grizzly.filterchain.ExecutorResolver.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access0(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:748)
]]
我也已将 Jackson 依赖项的 jar 添加到应用服务器的 lib 目录中。
我正在使用 GlassFish 5.0 和 Jersey 2.26。
我做错了什么?如何解决?
线索在错误信息中:
Error deserialize JSON value into type: class [C
class[C
就是char[]
对应的class。
查看您的代码,您已将 password
声明为:
private char[] password;
改为
private String password;
这里发生的事情是 Jackson 不知道如何将 JSON 字符串反序列化为 char[]
。
有一种观点认为你不应该使用 Java 字符串来保存密码......因为它可能允许黑客从(比如说)非JVM 核心转储中的 GC 字符串。但现实情况是,如果黑客可以通过这种方式提取密码,他们很可能会做其他事情来获取密码。此外,完全相同的密码很可能位于 Glassfish 框架 classes and/or JSON 反序列化器内部创建的 String
对象中。在这种情况下使用 char[]
很可能是徒劳的。即使您解决了这些问题,只有尽快覆盖 char[]
的内容,使用 char[]
来表示密码才会更加安全。如果你让 char[]
在它仍然持有密码的情况下变得无法访问,你又回到了 String
问题。
我试图在我的网络服务中反序列化一个 post 请求,但我最终得到一个 HTTP 500 说 javax.json.bind.JsonbException: Error deserialize JSON value into type: class [C
。我正在使用 Jackson 来处理 JSON 的东西。
这是我从 Postman 发送的 JSON 字符串:
{"firstName":"FirstName","middleName":"middleName","lastName":"LastName","name":"SomeName","password":"[=11=]meR@nd0m","creationTimeStamp":1533950475466}
这是我的 POJO:
@XmlRootElement
public class UserFormInterceptor {
@Pattern(regexp = "^[\S][\p{L} .'-]+$") @Size(min = 2, max = 64) @NotEmpty @NotNull
private String firstName;
@Pattern(regexp = "^[\S][\p{L} .'-]+$") @Size(min = 2, max = 64)
private String middleName;
@Pattern(regexp = "^[\S][\p{L} .'-]+$") @Size(min = 2, max = 64) @NotEmpty @NotNull
private String lastName;
@Pattern(regexp = "^[a-zA-z][\w]*$") @Size(min = 8, max = 64) @NotEmpty @NotNull
private String name;
@Pattern(regexp = "(?=.*?[A-Z]+)(?=.*?[0-9]+)(?=.*?[\p{Punct}]+).*") @Size(min = 8, max = 64) @NotEmpty @NotNull
private char[] password;
@Positive @NotEmpty @NotNull
private long creationTimeStamp;
public UserFormInterceptor() {}
public UserFormInterceptor(@NotNull String name, @NotNull String password, @Positive long creationTimeStamp, @NotNull String firstName, String middleName, @NotNull String lastName) {
this.name = name;
this.password = password.toCharArray();
this.creationTimeStamp = creationTimeStamp;
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
}
@NotNull
public String getFirstName() {
return firstName;
}
public void setFirstName(@NotNull String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
@NotNull
public String getLastName() {
return lastName;
}
public void setLastName(@NotNull String lastName) {
this.lastName = lastName;
}
@NotNull
public String getName() {
return name;
}
public void setName(@NotNull String name) {
this.name = name;
}
@NotNull
public char[] getPassword() {
return password;
}
public void setPassword(@NotNull String password) {
this.password = password.toCharArray();
}
public long getCreationTimeStamp() {
return creationTimeStamp;
}
public void setCreationTimeStamp(long creationTimeStamp) {
this.creationTimeStamp = creationTimeStamp;
}
public Map<String, Object> buildMap() {
Map<String,Object> returnMap = new HashMap<>();
returnMap.put("name",this.getName());
returnMap.put("firstName",this.firstName);
returnMap.put("middleName",this.middleName==null ? "" : this.middleName);
returnMap.put("lastName",this.lastName);
returnMap.put("creationTimeStamp",Long.toString(this.getCreationTimeStamp()));
return returnMap;
}
}
这是我的请求处理程序class:
@Path("/users")
public class UserController {
private static final UserDAO userDao = new UserDAO();
@POST
@Path(value = "/signup")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(value = MediaType.APPLICATION_JSON)
public Response signUpUser(@Valid @NotNull UserFormInterceptor userSignUpForm) {
UserCreatorModel userCreatorModel = (UserCreatorModel) new UserCreatorModel(userSignUpForm)
.setUniqueId();
String response = userDao.addCustomer(userCreatorModel);
return Response.ok(response).build();
}
}
这些是我对 Jackson 的 Maven 依赖项:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider -->
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.6</version>
</dependency>
这是堆栈跟踪:
StandardWrapperValve[Controller Servlet]: Servlet.service() for servlet Controller Servlet threw exception
javax.json.bind.JsonbException: Error deserialize JSON value into type: class [C.
at org.eclipse.yasson.internal.serializer.DeserializerBuilder.build(DeserializerBuilder.java:113)
at org.eclipse.yasson.internal.serializer.ObjectDeserializer.deserializeNext(ObjectDeserializer.java:161)
at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserializeInternal(AbstractContainerDeserializer.java:84)
at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserialize(AbstractContainerDeserializer.java:60)
at org.eclipse.yasson.internal.Unmarshaller.deserializeItem(Unmarshaller.java:57)
at org.eclipse.yasson.internal.Unmarshaller.deserialize(Unmarshaller.java:50)
at org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:45)
at org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:85)
at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.readFrom(JsonBindingProvider.java:99)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:257)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:236)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:73)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1091)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:271)
at org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:97)
at org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:80)
at org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.apply(ParamValueFactoryWithSource.java:74)
at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:92)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:133)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:200)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:103)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:493)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:415)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:104)
at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:277)
at org.glassfish.jersey.internal.Errors.call(Errors.java:272)
at org.glassfish.jersey.internal.Errors.call(Errors.java:268)
at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
at org.glassfish.jersey.internal.Errors.process(Errors.java:268)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:289)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:256)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:703)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:416)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:370)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:389)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:342)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:229)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1580)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:258)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:652)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:591)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242)
at org.glassfish.grizzly.filterchain.ExecutorResolver.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access0(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
at java.lang.Thread.run(Thread.java:748)
]]
我也已将 Jackson 依赖项的 jar 添加到应用服务器的 lib 目录中。 我正在使用 GlassFish 5.0 和 Jersey 2.26。 我做错了什么?如何解决?
线索在错误信息中:
Error deserialize JSON value into type: class [C
class[C
就是char[]
对应的class。
查看您的代码,您已将 password
声明为:
private char[] password;
改为
private String password;
这里发生的事情是 Jackson 不知道如何将 JSON 字符串反序列化为 char[]
。
有一种观点认为你不应该使用 Java 字符串来保存密码......因为它可能允许黑客从(比如说)非JVM 核心转储中的 GC 字符串。但现实情况是,如果黑客可以通过这种方式提取密码,他们很可能会做其他事情来获取密码。此外,完全相同的密码很可能位于 Glassfish 框架 classes and/or JSON 反序列化器内部创建的 String
对象中。在这种情况下使用 char[]
很可能是徒劳的。即使您解决了这些问题,只有尽快覆盖 char[]
的内容,使用 char[]
来表示密码才会更加安全。如果你让 char[]
在它仍然持有密码的情况下变得无法访问,你又回到了 String
问题。