我目前正在创建Android应用,但我遇到了一个问题。 我用Java和Jersey创建了后端部分(托管在服务器上)。
我的所有Web服务都是POST并返回一个JSON字符串,几乎所有这些字符串都只需要字符串,但其中一些还需要接收文件。
但是当我尝试向我的网络服务发送请求时,我在启动Android应用时遇到错误。响应代码为415或500,具体取决于内容类型。
我的问题是,如何在两侧设置内容类型,以便将发布请求从Android发送到我的服务器并获取JSON字符串?我需要添加,我有时也需要发送文件通过POST请求。
这就是我在Java代码中的内容
@POST
@Path("/login")
@Consumes("multipart/form-data")
public String getLogin(@FormDataParam("mail") String mail,
@FormDataParam("pwd") String pwd){ ...
这就是我的Android代码中的内容
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod(p.getMethod());
con.setRequestProperty("Content-type", "multipart/form-data");
提前谢谢。
答案 0 :(得分:0)
尝试将Content-Type
设置为application/json
。也就是说,如果您要向服务器发送JSON字符串。如果您要发送的文件是文本文件,请使用application/text
。否则,请查看here以获取有关不同文件格式的正确Content-Type
的信息。
答案 1 :(得分:0)
如果您不知道自己在做什么,尝试格式化多部分请求并非易事。你可以看到W3C documentation的样本格式和一些解释
Content-Type: multipart/form-data; boundary=AaB03x
--AaB03x
Content-Disposition: form-data; name="submit-name"
Larry
--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x--
在发出请求时,这几乎就是正文(和Content-Type标题)的样子。我已经制作了简单的帮助器类,适用于简单的String和文件盒。它并没有花太长时间制作,我没有经过测试,但它适用于简单的用例。我个人可能会做一些重构,但它会给你一个起点。
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;
public class MultipartHelper {
public String contentType;
public String boundary;
public HttpURLConnection connection;
private final List<FilePart> fileParts = new ArrayList<>();
private final List<StringPart> stringParts = new ArrayList<>();
public MultipartHelper(HttpURLConnection connection) throws IOException {
this(connection, "multipart/form-data");
}
public MultipartHelper(HttpURLConnection connection, String contentType) throws IOException {
this.boundary = String.valueOf(System.currentTimeMillis());
this.connection = connection;
contentType = contentType == null? "multipart/form-data": contentType;
contentType += "; boundary=" + boundary;
connection.setRequestProperty("Content-Type", contentType);
}
public void addStringPart(String data, String name) {
stringParts.add(new StringPart(data, name));
}
public void addFilePart(File file, String contentType, String name) {
if (contentType == null) {
contentType = "application/octet-stream";
}
fileParts.add(new FilePart(file, contentType, name));
}
public void makeRequest() {
Writer writer = null;
try {
OutputStream out = connection.getOutputStream();
writer = new BufferedWriter(new OutputStreamWriter(out));
for (StringPart sp: stringParts) {
writer.write("--" + boundary + "\r\n");
writer.write("Content-Disposition: form-data; name=" + sp.name + "\r\n");
writer.write("Content-Type: text/plain\r\n\r\n");
writer.write(sp.data + "\r\n");
}
writer.flush();
InputStream in = null;
for (FilePart fp: fileParts) {
writer.write("--" + boundary + "\r\n");
writer.write("Content-Disposition: form-data; name="
+ fp.name + "; filename=" + fp.file.getName() + "\r\n");
writer.write("Content-Type: " + fp.contentType + "\r\n\r\n");
writer.flush();
in = new FileInputStream(fp.file);
int count;
byte[] buffer = new byte[2048];
while ((count = in.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
out.flush();
writer.write("\r\n");
writer.flush();
in.close();
}
writer.write("--" + boundary + "--\r\r");
writer.flush();
out.close();
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
class StringPart {
String data;
String name;
public StringPart(String data, String name) {
this.data = data;
this.name = name;
}
}
class FilePart {
File file;
String name;
String contentType;
public FilePart(File file, String contentType, String name) {
this.file = file;
this.name = name;
this.contentType = contentType;
}
}
}
使用示例
final String urlStr = "http://localhost:8080/api/upload";
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection)url.openConnection(
new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8888)));
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
MultipartHelper multipart = new MultipartHelper(connection);
multipart.addStringPart("Hello Part 1", "string1");
multipart.addFilePart(new File("stackoverflow.png"), "image/png", "image");
multipart.makeRequest();
我个人虽然,我会选择已经拥有此功能的图书馆。例如,Retrofit具有多部分支持。这是一个非常受欢迎的休息客户端库。这是一个例子
首先需要依赖
的Maven
<dependency>
<groupId>com.squareup.retrofit</groupId>
<artifactId>retrofit</artifactId>
<version>1.9.0</version>
</dependency>
摇篮
compile 'com.squareup.retrofit:retrofit:1.9.0'
首先,您需要一个客户端服务接口
import retrofit.http.Multipart;
import retrofit.http.POST;
import retrofit.http.Part;
import retrofit.mime.TypedFile;
import retrofit.mime.TypedString;
public interface UploadService {
@Multipart
@POST("/upload")
retrofit.client.Response upload(@Part("image") TypedFile image,
@Part("string1") TypedString string1);
}
然后发出请求
RestAdapter adapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint("http://localhost:8080/api")
.build();
UploadService service = adapter.create(UploadService.class);
TypedFile file = new TypedFile("image/png", new File("stackoverflow.png"));
TypedString str = new TypedString("Hello World");
retrofit.client.Response response = service.upload(file, str);