【问题标题】:Trying to display an image read from a MySQL table试图显示从 MySQL 表中读取的图像
【发布时间】:2013-02-04 21:45:50
【问题描述】:

我正在尝试从 MySQL 表中读取图像 该图像被定义为 longblob,我正在使用 Eclipse Juno(更新)、Java 和 GWT(最新版本)。但是,当我运行时,我在页面上收到错误消息(我的第一个视图没有显示):

onModuleLoad() threw an exception


Exception while loading module org.AwardTracker.client.AwardTracker. See Development Mode for details.
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:406)
at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:526)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.RuntimeException: Deferred binding failed for 'org.AwardTracker.client.DBConnection' (did you forget to inherit a required module?)
at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:53)
at com.google.gwt.core.shared.GWT.create(GWT.java:57)
at com.google.gwt.core.client.GWT.create(GWT.java:85)
at org.AwardTracker.client.LoginView.<init>(LoginView.java:29)
at org.AwardTracker.client.AwardTracker.onModuleLoad(AwardTracker.java:14)
... 9 more
Caused by: com.google.gwt.core.ext.UnableToCompleteException: (see previous log entries)
at com.google.gwt.dev.shell.ModuleSpace.rebind(ModuleSpace.java:605)
at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:465)
at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:49)
... 13 more

开发控制台有以下消息(前几行):

[DEBUG] [org.AwardTracker.AwardTracker] - Validating units:
[INFO] [org.AwardTracker.AwardTracker] - Ignored 4 units with compilation errors in first pass.
Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
[ERROR] [org.AwardTracker.AwardTracker] - Errors in 'file:/C:/Users/Glyndwr/Eclipse/Workspace/AwardTracker/src/org/AwardTracker/client/DBConnection.java'
[ERROR] [org.AwardTracker.AwardTracker] - Line 15: No source code is available for type java.sql.Blob; did you forget to inherit a required module?

我的 DBConnection 是:

package org.AwardTracker.client;

import java.util.List;
import java.sql.Blob;

import com.google.gwt.user.client.rpc.RemoteService;

/**
 * The client side stub for the RPC service.
 */
public interface DBConnection extends RemoteService {
public User authenticateUser(String user, String pass, String level, String archived);
public User duplicateUser(String user, String pass, String level, String archived);
public User createUser(String user, String pass, String level, String archived);
public List<YouthMember> getYM(String id, String surname, String first_name, String dob, Blob image, String archived);
}

据此,我认为 java.sql.Blob 不能在 GWT 中使用。我应该使用什么?

我将图像存储在数据库中,而不是图像链接,因为我只有少量低分辨率图像要存储,因此数据库不应该因此而过度征税。

问候,

格林

我做了以下更改:

在 MySQLConnection 类的服务器端,我添加了以下方法(但是它有列出的错误):

public String getImageData(String id){
    ResultSet result = null;
    PreparedStatement ps = null;
    String imageDataString = null;
    try {
        // Read in the image from the database.
        ps = conn.prepareStatement(
              "SELECT at_cub_details.cd_photograph " +
                      "FROM at_cub_details " + 
                      "WHERE at_cub_details.cd_id = \"" + id + "\"");
        result = ps.executeQuery();
        while (result.next()) {
            File file = new File(result.getString(1));
            FileInputStream imageInFile = new FileInputStream(file);
            byte imageData[] = new byte[(int) file.length()];
            imageInFile.read(imageData);

            //Convert Image byte array into Base64 String
            imageDataString = encodeImage(imageData);

            imageInFile.close();
        }

    }
    catch (FileNotFoundException e) {
        System.out.println("getImageData - Image not found" + e);
    } 
    catch (IOException ioe) {
        System.out.println("getImageData - Exception while reading the Image " + ioe);
    }
    catch (SQLException e) {
      //do stuff on fail
        System.out.println("SQLException getImageData 1.");
        e.printStackTrace();
        user = null;
    }
    finally {
        if (result != null) {
            try {
                result.close();
            }
            catch (SQLException e) {
                System.out.println("SQLException getImageData 2.");
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
            }   
            catch (SQLException e) {
                System.out.println("SQLException getImageData 3.");
                e.printStackTrace();
            }
        }
    }
    return imageDataString;
}
 /**
  * Encodes the byte array into base64 string
  * @param imageByteArray - byte array
  * @return String a {@link java.lang.String}
  */
public static String encodeImage(byte[] imageByteArray) {
    return Base64.encodeBase64URLSafeString(imageByteArray); [This line has the error: Multiple markers at this line
- The method encodeBase64URLSafeString(byte[]) is undefined for the 
 type Base64
- Line breakpoint:MySQLConnection [line: 287] - encodeImage(byte[]). However I have import org.apache.commons.codec.binary.Base64;]

}

在客户端我有:

public void renderYouthMemberTable(List<YouthMember> youthMemberList) {
    if (youthMemberList != null) {
        int row = 0;
        int col = 0;
        flexTable.clear();
        for (YouthMember youthMember : youthMemberList) {
            String id = youthMember.getId();

            String imageDataString = getImageData(); [ Error: The method getImageData() is undefined for the type SelectPersonView]

            // Converting a Base64 String into Image byte array
            byte[] imageByteArray = decodeImage(imageDataString);

            // Write a image byte array into file system
            FileOutputStream imageOutFile = new FileOutputStream(
                    "/Users/jeeva/Pictures/wallpapers/water-drop-after-convert.jpg");
            imageOutFile.write(imageByteArray);

            flexTable.setWidget(row, col, new Label(imageByteArray)); [Error: The constructor Label(byte[]) is undefined]
            //flexTable.setWidget(row, col, new Label(youthMember.getId()));
            flexTable.setWidget(row + 1, col, new Label(youthMember.getSurname() + ", " + youthMember.getFirstname()));

            //imageOutFile.close();

            col = col + 1;
            if (col > 7) {
                row = row + 2;
                col = 0;
            }
        }
    }

}

/**
 * Decodes the base64 string into byte array
 * @param imageDataString - a {@link java.lang.String}
 * @return byte array
 */
public static byte[] decodeImage(String imageDataString) {
    return Base64.decodeBase64(imageDataString); [ With the error: The method decodeBase64(byte[]) in the type Base64 is not applicable for the arguments (String)]
    }

我从http://www.myjeeva.com/2012/07/how-to-convert-image-to-string-and-string-to-image-in-java/复制了这段代码

问候,

格林

【问题讨论】:

  • 一旦 Blob(或 BlobReplacement)到达客户端,您将如何处理它?您将如何实际绘制该图像?您是否考虑过只返回一个表示该图像 URL 的字符串,并拥有一个只提供这些图像的 servlet?
  • 我将在 flextable 中显示图像。我是否过于简单地假设我可以将图像存储在表格中,然后以与存储和显示字符串或整数相同的方式显示该图像?我宁愿将所有数据保存在一个数据库中。问候,格林。
  • 可能 - 你以前做过 HTML 工作吗?字符串和整数都可以很容易地呈现为相同的东西 - 字符串。仅使用字符串无法绘制图像(除非您只是在谈论 &lt;img&gt; 标签),但如果您愿意放弃旧版本的 IE,您可以接近 data: urls。
  • 您好 Colin,我知道我可以使用标签 src 在 html 中显示图像。但是,我知道源必须是文件和可选的目录路径(例如,images\picture.jpg)。我如何在 Eclipse java GWT 中从存储为 longblob 的 MySQL 表中提取图像(即小 jpg 图片 - 头部和肩部),然后在小部件(即 flextable)中显示图像。下一步是使图像可选择,以便用户选择图像,并在选择图像时将它们带到该人的详细信息视图。问候,格林。
  • 您在这里添加了很多部分 - Eclipse 可用于编写代码,但它不会运行它; GWT 客户端代码仅在浏览器中运行,因此它无法将文件提取到服务器上的文件系统中。您必须有一个提供此文件的 servlet。如果是我,我不会费心将它提取到文件系统,而只是从另一个专门为此任务构建的 servlet 中流式传输结果。至于选择图像 - 先走,然后跑 - 否则这个问题只会越来越多。

标签: java mysql eclipse image gwt


【解决方案1】:

当您使用 GWT 时,不要忘记您的最终代码是 javascript。所以有些课程不可用。

但是:

-> GWT 中的图像可以有一个用于源 url 的 servlet url(带参数)。

-> 此处描述的其他方式:GWT - image from database:使用在回调时返回 base64 字符串 + 图像初始化的服务 rpc。

希望对你的问题有用。

【讨论】:

  • 您好,感谢您提供此信息。我一直在看类似的东西。但是,我首先需要解决第一个错误。在 DBConnection 中,我定义了“public List getYM(String id, String surname, String first_name, String dob, Blob image, String archived);”。这会产生错误。那我该怎么办?我是否通过我的所有代码将“Blob”更改为“String”?但是,这与 MySQL 列定义不匹配;这有关系吗?或者我应该改变我的表格,转换图像并将图像存储为字符串?
  • 我已尝试将所有“Blob”更改为“String”。当我尝试为“String base64 = Base64Utils.toBase64(result.getString(5));”行实施推荐的解决方案时我收到错误“ Line breakpoint:MySQLConnection [line: 182] - getYM(String, String, String, String, String, String) - Base64Utils 类型中的 toBase64(byte[]) 方法不适用于参数(String )"。
  • 所以在我做任何事情之前我需要知道我应该如何存储图像和恢复图像(即 DBConnection.java 中的正确定义“public List getYM(String id, String surname , String first_name, String dob, String image, String archived);"。感谢您的帮助。问候,Glyn。
  • 我认为您的第一个问题是使用名为 DBConnection 的 rpc 服务。我认为您的远程服务应该是数据库数据和 GUI 表示之间的包装器(并且应该是面向功能的)。转换取决于您的 blob 内容(已经是 base64 ?)。这不是真正的 GWT 问题,只是检索您存储的数据并转换它们的问题:但是当您现在输入格式(blob 内容)和输出格式(base64 字符串)时,您的问题变得不那么具体了,您可以在外面找到解决方案GWT 主题:-)。希望我能很好地理解你的问题。问候
  • 嗨 fmy,我知道您正在尽最大努力提供帮助;我真诚地感谢你。但是,恐怕我没有java经验来理解你的回复。我在网上找到了一些其他信息,我将通过此尝试更新我的帖子。问候,格林。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
  • 2013-10-26
  • 2012-07-18
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 2016-04-26
相关资源
最近更新 更多