无法使用 java 通过休息 api 从 mysql 检索图像
unable to retrieve image from mysql through rest api using java
我的问题看似简单,但我找不到答案。通过 Java 和 JDBI,我能够从 MySQL 数据库中检索图像并将其存储在本地。但是当我尝试休息 api 时,它在所附的屏幕截图中给出了错误。我已经搜索了很多,但找不到解决方案。
堆栈跟踪如下:
Type Exception Report
Message java.lang.IllegalStateException: No container builder available for java.sql.Blob
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
javax.servlet.ServletException: java.lang.IllegalStateException: No container builder available for java.sql.Blob
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:489)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause
java.lang.IllegalStateException: No container builder available for java.sql.Blob
org.skife.jdbi.v2.ContainerFactoryRegistry.createBuilderFor(ContainerFactoryRegistry.java:73)
org.skife.jdbi.v2.Query.first(Query.java:271)
org.skife.jdbi.v2.sqlobject.ResultReturnThing$SingleValueResultReturnThing.result(ResultReturnThing.java:110)
org.skife.jdbi.v2.sqlobject.ResultReturnThing.map(ResultReturnThing.java:46)
org.skife.jdbi.v2.sqlobject.QueryHandler.invoke(QueryHandler.java:43)
org.skife.jdbi.v2.sqlobject.SqlObject.invoke(SqlObject.java:212)
org.skife.jdbi.v2.sqlobject.SqlObject.intercept(SqlObject.java:127)
org.skife.jdbi.v2.sqlobject.CloseInternalDoNotUseThisClass$$EnhancerByCGLIB$d85a881.retrieveImage(<generated>)
com.sample.obs.factory.BooksFactory.retrieveImage(BooksFactory.java:188)
com.sample.obs.model.Books.listAllBooks(Books.java:378)
com.sample.obs.util.BooksRest.listAllBooks(BooksRest.java:29)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.invoke(ResourceMethodInvocationHandlerFactory.java:81)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.run(AbstractJavaResourceMethodDispatcher.java:144)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:326)
org.glassfish.jersey.internal.Errors.call(Errors.java:271)
org.glassfish.jersey.internal.Errors.call(Errors.java:267)
org.glassfish.jersey.internal.Errors.process(Errors.java:315)
org.glassfish.jersey.internal.Errors.process(Errors.java:297)
org.glassfish.jersey.internal.Errors.process(Errors.java:267)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
添加其余 api 和下面的 listAllBooks 方法:
@GET
@Produces(MediaType.APPLICATION_JSON)
public final Books[] listAllBooks() {
Books b = new Books();
Books[] shelf = b.listAllBooks();
return shelf;
}
public final Books[] listAllBooks() {
Books[] bList = BooksFactory.listAllBooks();
for(Books b: bList) {
String path = "E:\" + b.getBookId() + ".png";
Blob imageBlob = BooksFactory.retrieveImage(b.getBookId());
try {
byte[] image = handleBlob(imageBlob);
if (image != null) {
FileOutputStream fos = new FileOutputStream(path);
fos.write(image);
fos.close();
b.setImageUrl(path);
} else {
System.out.println("Image not available");
b.setImageUrl(null);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int avail = BooksFactory.retrieveAvailableCopies(b.getBookId());
b.setAvailableCopies(avail);
}
return bList;
}
DAO 和工厂方法return 一个 Blob,我有一个映射器用于从 DB 获取 blob。
请指导如何解决这个问题。
我终于找到了问题的解决方案。我将以下代码添加到 dbi 对象。
dbi.registerContainerFactory(new ContainerFactory<Blob>(){
@Override
public boolean accepts(Class<?> arg0) {
return false;
}
@Override
public ContainerBuilder<Blob> newContainerBuilderFor(Class<?> arg0) {
return newContainerBuilderFor(arg0);
}
});
我按照 this link 找到了解决方案。
我的问题看似简单,但我找不到答案。通过 Java 和 JDBI,我能够从 MySQL 数据库中检索图像并将其存储在本地。但是当我尝试休息 api 时,它在所附的屏幕截图中给出了错误。我已经搜索了很多,但找不到解决方案。
堆栈跟踪如下:
Type Exception Report
Message java.lang.IllegalStateException: No container builder available for java.sql.Blob
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
javax.servlet.ServletException: java.lang.IllegalStateException: No container builder available for java.sql.Blob
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:489)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause
java.lang.IllegalStateException: No container builder available for java.sql.Blob
org.skife.jdbi.v2.ContainerFactoryRegistry.createBuilderFor(ContainerFactoryRegistry.java:73)
org.skife.jdbi.v2.Query.first(Query.java:271)
org.skife.jdbi.v2.sqlobject.ResultReturnThing$SingleValueResultReturnThing.result(ResultReturnThing.java:110)
org.skife.jdbi.v2.sqlobject.ResultReturnThing.map(ResultReturnThing.java:46)
org.skife.jdbi.v2.sqlobject.QueryHandler.invoke(QueryHandler.java:43)
org.skife.jdbi.v2.sqlobject.SqlObject.invoke(SqlObject.java:212)
org.skife.jdbi.v2.sqlobject.SqlObject.intercept(SqlObject.java:127)
org.skife.jdbi.v2.sqlobject.CloseInternalDoNotUseThisClass$$EnhancerByCGLIB$d85a881.retrieveImage(<generated>)
com.sample.obs.factory.BooksFactory.retrieveImage(BooksFactory.java:188)
com.sample.obs.model.Books.listAllBooks(Books.java:378)
com.sample.obs.util.BooksRest.listAllBooks(BooksRest.java:29)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.invoke(ResourceMethodInvocationHandlerFactory.java:81)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.run(AbstractJavaResourceMethodDispatcher.java:144)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:161)
org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:205)
org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:326)
org.glassfish.jersey.internal.Errors.call(Errors.java:271)
org.glassfish.jersey.internal.Errors.call(Errors.java:267)
org.glassfish.jersey.internal.Errors.process(Errors.java:315)
org.glassfish.jersey.internal.Errors.process(Errors.java:297)
org.glassfish.jersey.internal.Errors.process(Errors.java:267)
org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
添加其余 api 和下面的 listAllBooks 方法:
@GET
@Produces(MediaType.APPLICATION_JSON)
public final Books[] listAllBooks() {
Books b = new Books();
Books[] shelf = b.listAllBooks();
return shelf;
}
public final Books[] listAllBooks() {
Books[] bList = BooksFactory.listAllBooks();
for(Books b: bList) {
String path = "E:\" + b.getBookId() + ".png";
Blob imageBlob = BooksFactory.retrieveImage(b.getBookId());
try {
byte[] image = handleBlob(imageBlob);
if (image != null) {
FileOutputStream fos = new FileOutputStream(path);
fos.write(image);
fos.close();
b.setImageUrl(path);
} else {
System.out.println("Image not available");
b.setImageUrl(null);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int avail = BooksFactory.retrieveAvailableCopies(b.getBookId());
b.setAvailableCopies(avail);
}
return bList;
}
DAO 和工厂方法return 一个 Blob,我有一个映射器用于从 DB 获取 blob。
请指导如何解决这个问题。
我终于找到了问题的解决方案。我将以下代码添加到 dbi 对象。
dbi.registerContainerFactory(new ContainerFactory<Blob>(){
@Override
public boolean accepts(Class<?> arg0) {
return false;
}
@Override
public ContainerBuilder<Blob> newContainerBuilderFor(Class<?> arg0) {
return newContainerBuilderFor(arg0);
}
});
我按照 this link 找到了解决方案。