Java Restful web服务方法消费MultiPart数据抛出异常
Java Restful web service method to consume MultiPart data throwing exception
我正在尝试将图像从 android 设备上传到服务器。正在调用我的 Web 服务方法,但它抛出一些异常。我尝试在网上搜索数小时,但没有找到任何解决方案。我是第一次使用 multipart。
我已经改变了我的网络服务方法。[编辑]
这是我的 android 客户端代码
protected Boolean doInBackground(String... urls) {
try{
URL urlImage = new URL("http://10.0.2.2:8080/LostLove_services/love/Recipe/coverpic");
HttpURLConnection urlConnectionImage = (HttpURLConnection) urlImage.openConnection();
ImageButton coverImage = (ImageButton)findViewById(R.id.CoverPic);
Bitmap bitmap = ((BitmapDrawable)coverImage.getDrawable()).getBitmap();
urlConnectionImage.setUseCaches(false);
urlConnectionImage.setDoOutput(true);
urlConnectionImage.setDoInput(true);
urlConnectionImage.setRequestMethod("POST");
urlConnectionImage.setRequestProperty("Connection", "Keep-Alive");
urlConnectionImage.setRequestProperty("Cache-Control", "no-cache");
urlConnectionImage.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + this.boundary);
DataOutputStream request = new DataOutputStream(urlConnectionImage.getOutputStream());
request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" + this.attachmentName + "\";filename=\"" + this.attachmentFileName + "\"" + this.crlf);
request.writeBytes(this.crlf);
/* byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
for (int i = 0; i < bitmap.getWidth(); ++i) {
for (int j = 0; j < bitmap.getHeight(); ++j) {
//we're interested only in the MSB of the first byte,
//since the other 3 bytes are identical for B&W images
pixels[i + j] = (byte) ((bitmap.getPixel(i, j) & 0x80) >> 7);
}
}
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
// Log.d("pixel size",pixels.clone().toString());
// Log.d("real size",Integer.toString(pixels.length));
request.write(bitmapdata);
request.writeBytes(this.crlf);
request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf);
request.flush();
Log.d("imageout",Integer.toString(urlConnectionImage.getResponseCode()));
request.close();
switch (urlConnection.getResponseCode()) {
case HttpURLConnection.HTTP_OK:
return true;
default:
return false; // abort
}
// urlConnection.connect();
}
catch (Exception e)
{
Log.d("exeJsonPublish",e.toString());
return false;
}
}
这是我的网络服务方法[已编辑]。我在缓冲图像中得到空值。
@Path("/coverpic")
@POST
// @Consumes("multipart/form-data")
public String retrieveImage(FormDataMultiPart multipart)
{
Iterator it = multipart.getFields().keySet().iterator();
//System.out.println(it.next());
FormDataBodyPart body = multipart.getField("bitmap");
InputStream ins = ((BodyPartEntity )body.getEntity()).getInputStream();
String uploadedFileLocation = "E:\torr\A.bmp" ;
if(ins == null)
System.out.println("is null");
// writeToFile(ins, uploadedFileLocation);
try {
BufferedImage bi = ImageIO.read(ins);
if(bi==null)
System.out.println("bi is null");
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
System.out.println("exec is "+e);
}
// System.out.println(multipart.getFields().keySet().iterator());
/*try {
InputStream source = ins;
//BufferedImage bi = ImageIO.(source);
BufferedImage bi = ImageIO.read(source);
File file = new File("E:\aditya.bmp");
if (file.isDirectory()) {
ImageIO.write(bi, "bmp", file);
} else {
file.mkdirs();
ImageIO.write(bi, "bmp", file);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
System.out.println("in retrieveImage"+ multipart.getBodyParts());
return null;
}
我已经更正了我的代码。现在它正在工作。在 android doInBackground 方法中未正确创建位图。
像这样使用 uploadFile 方法:
public Response uploadFile(
@DefaultValue("true") @FormDataParam("enabled") boolean enabled,
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail)
{
//Your code
}
这里的逻辑是将 FormDataParam 设置为 true。
这是我对服务器和客户端代码的回答,可能对你有帮助
File Upload with Jax RS
您可以使用 FormDataMultiPart
@POST
@Path("/coverpic")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(FormDataMultiPart multiPart){
FormDataBodyPart body = multiPart.getField(<your fieldname>);
InputStream ins = ((BodyPartEntity) body.getEntity()).getInputStream();
///.....
///.....
return Response.status(200).entity(output).build();
}
请检查您的字段名称“file”是否真的出现在 multipart 中,否则循环遍历 multiPart 并使用
获取所有字段名称
multiPart.getFields().keySet().iterator()
你必须使用多部分依赖
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
在Eclipse中查看Dynamic web Module版本是2.5还是3.0。我认为 multipart 只适用于 3.0 或更高版本。请告诉我版本是什么。
我正在尝试将图像从 android 设备上传到服务器。正在调用我的 Web 服务方法,但它抛出一些异常。我尝试在网上搜索数小时,但没有找到任何解决方案。我是第一次使用 multipart。 我已经改变了我的网络服务方法。[编辑] 这是我的 android 客户端代码
protected Boolean doInBackground(String... urls) {
try{
URL urlImage = new URL("http://10.0.2.2:8080/LostLove_services/love/Recipe/coverpic");
HttpURLConnection urlConnectionImage = (HttpURLConnection) urlImage.openConnection();
ImageButton coverImage = (ImageButton)findViewById(R.id.CoverPic);
Bitmap bitmap = ((BitmapDrawable)coverImage.getDrawable()).getBitmap();
urlConnectionImage.setUseCaches(false);
urlConnectionImage.setDoOutput(true);
urlConnectionImage.setDoInput(true);
urlConnectionImage.setRequestMethod("POST");
urlConnectionImage.setRequestProperty("Connection", "Keep-Alive");
urlConnectionImage.setRequestProperty("Cache-Control", "no-cache");
urlConnectionImage.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + this.boundary);
DataOutputStream request = new DataOutputStream(urlConnectionImage.getOutputStream());
request.writeBytes(this.twoHyphens + this.boundary + this.crlf);
request.writeBytes("Content-Disposition: form-data; name=\"" + this.attachmentName + "\";filename=\"" + this.attachmentFileName + "\"" + this.crlf);
request.writeBytes(this.crlf);
/* byte[] pixels = new byte[bitmap.getWidth() * bitmap.getHeight()];
for (int i = 0; i < bitmap.getWidth(); ++i) {
for (int j = 0; j < bitmap.getHeight(); ++j) {
//we're interested only in the MSB of the first byte,
//since the other 3 bytes are identical for B&W images
pixels[i + j] = (byte) ((bitmap.getPixel(i, j) & 0x80) >> 7);
}
}
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
byte[] bitmapdata = bos.toByteArray();
// Log.d("pixel size",pixels.clone().toString());
// Log.d("real size",Integer.toString(pixels.length));
request.write(bitmapdata);
request.writeBytes(this.crlf);
request.writeBytes(this.twoHyphens + this.boundary + this.twoHyphens + this.crlf);
request.flush();
Log.d("imageout",Integer.toString(urlConnectionImage.getResponseCode()));
request.close();
switch (urlConnection.getResponseCode()) {
case HttpURLConnection.HTTP_OK:
return true;
default:
return false; // abort
}
// urlConnection.connect();
}
catch (Exception e)
{
Log.d("exeJsonPublish",e.toString());
return false;
}
}
这是我的网络服务方法[已编辑]。我在缓冲图像中得到空值。
@Path("/coverpic")
@POST
// @Consumes("multipart/form-data")
public String retrieveImage(FormDataMultiPart multipart)
{
Iterator it = multipart.getFields().keySet().iterator();
//System.out.println(it.next());
FormDataBodyPart body = multipart.getField("bitmap");
InputStream ins = ((BodyPartEntity )body.getEntity()).getInputStream();
String uploadedFileLocation = "E:\torr\A.bmp" ;
if(ins == null)
System.out.println("is null");
// writeToFile(ins, uploadedFileLocation);
try {
BufferedImage bi = ImageIO.read(ins);
if(bi==null)
System.out.println("bi is null");
} catch (Exception e) {
// TODO Auto-generated catch block
//e.printStackTrace();
System.out.println("exec is "+e);
}
// System.out.println(multipart.getFields().keySet().iterator());
/*try {
InputStream source = ins;
//BufferedImage bi = ImageIO.(source);
BufferedImage bi = ImageIO.read(source);
File file = new File("E:\aditya.bmp");
if (file.isDirectory()) {
ImageIO.write(bi, "bmp", file);
} else {
file.mkdirs();
ImageIO.write(bi, "bmp", file);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
System.out.println("in retrieveImage"+ multipart.getBodyParts());
return null;
}
我已经更正了我的代码。现在它正在工作。在 android doInBackground 方法中未正确创建位图。
像这样使用 uploadFile 方法:
public Response uploadFile(
@DefaultValue("true") @FormDataParam("enabled") boolean enabled,
@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail)
{
//Your code
}
这里的逻辑是将 FormDataParam 设置为 true。
这是我对服务器和客户端代码的回答,可能对你有帮助
File Upload with Jax RS
您可以使用 FormDataMultiPart
@POST
@Path("/coverpic")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(FormDataMultiPart multiPart){
FormDataBodyPart body = multiPart.getField(<your fieldname>);
InputStream ins = ((BodyPartEntity) body.getEntity()).getInputStream();
///.....
///.....
return Response.status(200).entity(output).build();
}
请检查您的字段名称“file”是否真的出现在 multipart 中,否则循环遍历 multiPart 并使用
获取所有字段名称multiPart.getFields().keySet().iterator()
你必须使用多部分依赖
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.18.3</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
在Eclipse中查看Dynamic web Module版本是2.5还是3.0。我认为 multipart 只适用于 3.0 或更高版本。请告诉我版本是什么。