0

我有一个android客户端,我想将图像从我的android发送到我的服务器,我将图像转换为字节数组,然后将字节数组转换为base64,我将base64字符串发送到服务器,我在服务器中对其进行解码然后存储它在我的 sql server 2008 r2 中。

我的问题

我无法将字符串存储到我的数据库然后正确检索它,我没有得到任何异常并且我得到了结果,但它似乎是错误的结果。

我通过这样做得出结论。

1-我将base64从android发送到服务器并将检索到的字符串保存在静态变量中。2-我要求服务器检索静态字符串,我得到了 android 中的图像。3-但是当我要求服务器检索我认为我将其保存在数据库中的图像时,我得到了错误的图像,实际上我得到了结果,但这个结果无法再次解码。

我会告诉你我在数据库中插入和检索图像的代码,请告诉我我做错了什么,

存储到数据库

void uploadImage(String image) {
Connection con = Database.getConnection();
        CallableStatement callableStatement = null;
        try {
            callableStatement = con
                    .prepareCall("{call insertRestaurantFoodImage(?,?)}");
            ByteArrayInputStream b = new ByteArrayInputStream(
                    stringImage.getBytes());
            callableStatement.setInt(1, ID);
            ;
            callableStatement.setBinaryStream(2, b,
                    stringImage.getBytes().length);
            callableStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
}

插入图像的存储过程是

ALTER PROCEDURE dbo.insertRestaurantFoodImage
    (
    @restaurantFoodID INT,
    @image VARBINARY(MAX)
    )
AS
BEGIN
    SET NOCOUNT ON
    UPDATE Food_Restaurant
    SET [image] = @image
    WHERE ID = @restaurantFoodID
END

从数据库中检索

Connection con = Database.getConnection();
            CallableStatement callableStatement = null;
            try {
                callableStatement = con
                        .prepareCall("{call getRestaurantFoodImage(?,?)}");
                callableStatement.setInt(1, getID());
                callableStatement.registerOutParameter(2,
                        java.sql.Types.VARBINARY);
                callableStatement.execute();
                byte[] bytes = callableStatement.getBytes(2);
                image = new String(bytes);
            } catch (SQLException e) {
                e.printStackTrace();
            }

从数据库中检索的存储过程是:

ALTER PROCEDURE dbo.getRestaurantFoodImage
(
    @foodRestaurantID INT,
    @image VARBINARY(MAX) OUTPUT
    )
AS
BEGIN
    SET NOCOUNT ON
    SELECT @image = [image]
    FROM Food_Restaurant
    WHERE ID = @foodRestaurantID
END

也许我说的太多了,但是在上一个问题中,一位用户告诉我,我不仅要输入代码,而且还必须提出我的问题和我在做什么。

对于那些问我如何在 android 中编码和解码的用户,这里是:

编码

private byte[] getBytesFromBitmap(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(CompressFormat.PNG, 70, stream);
        return stream.toByteArray();
    }

    private String getBase64(Bitmap bitmap) {
        String imgString = Base64.encodeToString(getBytesFromBitmap(bitmap),
                Base64.NO_WRAP);
        return imgString;
    }

解码

String retrievedBase63 = client2
                .getBaseURI("restaurantFoods/OneFood/" + 5 + "/getImage");
        //Log.d("image", image);
        byte[] decodedString = Base64.decode(retrievedBase63, Base64.DEFAULT);
        Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0,
                decodedString.length);
4

1 回答 1

1

正如我在 sql server 2008 r2 上对 jdbc 存储的 png 图像也发表评论(并回复)给出了不完整的数据,旧版本的 SQL Server 对varbinary和的限制为 8kb varchar。要么驱动程序根本不再支持getBytesor getString,要么您可能使用的是较旧的 JDBC 驱动程序。另一种可能性是您需要将 OUT 参数注册为java.sql.types.LONGVARBINARY(或LONGVARCHAR)。

无论如何(也在另一个问题中),我想知道为什么在存储数据之前首先在 base64 中编码。只需将原始字节存储在VARBINARY.

于 2013-06-08T08:50:25.610 回答