java - C# 和 Java - 将文件从 Android 上传到 WCF

标签 java c# android wcf

我正在尝试将文件从 Android 上传到 WCF 服务。 我已经到了触发 WCF 上的方法并保存文件的地步。 尝试打开文件时,我收到一条错误消息,指出文件已损坏。

我认为错误可能出在 HttpFileUpload 类中,其中一个静态变量不正确,或者我发送的不是流,而是服务以某种方式转换为流的其他内容,从而导致损坏。

使用的代码可以在下面找到。

安卓代码:

HttpFileUpload 类:

找到 HttpFileUpload 代码 here :

private static final String LINE_FEED = "\r\n";
private String charset = "UTF-8";

public HttpFileUpload(String requestURL) throws IOException {

    // creates a unique boundary based on time stamp
    boundary = "===" + System.currentTimeMillis() + "===";

    URL url = new URL(requestURL);
    httpConn = (HttpURLConnection) url.openConnection();
    httpConn.setUseCaches(false);
    httpConn.setDoOutput(true); // indicates POST method
    httpConn.setDoInput(true);
    httpConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
    httpConn.setRequestProperty("Host", "x.x.x.x:x");
    outputStream = httpConn.getOutputStream();
    writer = new PrintWriter(new OutputStreamWriter(outputStream, charset), true);
}

public void addFilePart(String fieldName, File uploadFile) throws IOException {
    String fileName = uploadFile.getName();
    writer.append("--" + boundary).append(LINE_FEED);
    writer.append("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + fileName + "\"").append(LINE_FEED); // form-data
    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(fileName)).append(LINE_FEED);
    writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
    writer.append(LINE_FEED);
    writer.flush();

    FileInputStream inputStream = new FileInputStream(uploadFile);
    byte[] buffer = new byte[4096];
    int bytesRead = -1;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, bytesRead);
    }
    outputStream.flush();
    inputStream.close();

    writer.append(LINE_FEED);
    writer.flush();
}

public List<String> finish() throws IOException {
    List<String> response = new ArrayList<String>();

    writer.append(LINE_FEED).flush();
    writer.append("--" + boundary + "--").append(LINE_FEED);
    writer.close();

    int status = httpConn.getResponseCode();
    if (status == HttpURLConnection.HTTP_OK) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
        String line = null;
        while ((line = reader.readLine()) != null) {
            response.add(line);
        }
        reader.close();
        httpConn.disconnect();
    } else {
        throw new IOException("Server returned status: " + status);
    }

    return response;
}

服务连接器类

    String urlTo = LOCATION + "/UploadUserProfilePicture";
    File file = new File(imagePath);

    try {
        HttpFileUpload httpFileUpload = new HttpFileUpload(urlTo);

        httpFileUpload.addFilePart("image", file);

        List<String> responses = httpFileUpload.finish();

        for (String line : responses) {
            System.out.println(line);
        }

        return responses.get(0);

    } catch (Exception ex) {
        return ex.toString();
    }

WCF 服务代码

移动服务:

    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    [OperationContract]
    Result UploadUserProfilePicture(Stream image);

移动服务:

FileType fileType = bytes.GetFileType() 是一个返回扩展名的插件。目前该插件不起作用,因为 fileType 始终为空。 但是图像变量可能已经损坏。

public Result UploadUserProfilePicture(Stream image)
    {
        try
        {
            var bytes = CommonMethods.ReadToEnd(image);
            FileType fileType = bytes.GetFileType();

            Guid guid = Guid.NewGuid();
            string imageName = guid.ToString() + "." + fileType.Extension;
            var buf = new byte[1024];
            var path = Path.Combine(@"C:\fileUpload\" + imageName); //" ocd

            File.WriteAllBytes(path, bytes);

            return new Result
            {
                Success = true,
                Message = imageName
            };
        }
        catch(Exception ex)
        {
            return new Result
            {
                Success = false,
                Message = ex.ToString()
            };
        }
    }

最佳答案

在没有尝试结合使用 Android/WCF REST 的情况下,我在您的代码中注意到了一些事情。

首先,您在操作契约中说您的 REST 方法需要 JSON 并返回 JSON。但 Android 代码并未发送 JSON。它只是按原样发送输入文件的内容。这是我认为不正确的一件事。如果您想像浏览器表单一样将内容上传到网站,那么您使用的代码很好,但这与使用 REST 请求不同。

另一件事是:您的 REST 方法不会采用 Stream 参数,因为它没有获得流。

我要做的第一件事是设计 REST POST 方法,使其接受这样的 JSON 对象:

{ imageBytes = "0dac...." }

imageBytes 是您要保存的图像的 base64 编码版本(例如:PNG 文件的 base64 编码字节)。然后,您可以使用其他方法来测试它是否有效。

然后我会更改 Android 代码以便它

  1. 读取要发送的文件并创建该文件的 base64 编码版本。
  2. 如上所述在 JSON 对象中发送 base64 编码版本。

然后事情应该解决了。正如我上面所说,我自己以前没有在那个组合中做过,所以我没有可以给你的示例代码。

关于java - C# 和 Java - 将文件从 Android 上传到 WCF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36178846/

相关文章:

java - 如何处理 Java 中从对象序列化为 JSON 期间的 Stackoverflow 错误

c# - 命名空间中不存在类型或命名空间名称 'GetName'

c# - 当不能简单地重载时混合可选参数和参数

android - 能够为谷歌地图 Intent 选择方向类型

Android:TabHost.TabSpec setIndicator(CharSequence 标签)

android - 根据构建风格引用不同的 Assets

java - 如何在不执行事件的情况下将值从 JSP 传递到 Servlet?

java - 如何强制 Firefox 发送隐藏字段?

java - 使用 POI 和 Jsoup 的超链接位于错误位置

c# - WPF 仪表板覆盖第 3 方应用程序