2016-10-25 16:02:49.0|分类: java|浏览量: 2770
最近使用jsoup上传图片功能,接受端能接受到数据流,但是接受端不能识别出图片的类型image/jpeg,接受端认为这次上传只是数据流,接受端怎么不能识别出文件类型呢? 经过查看jsoup1.9.2源码发现:jsoup上传文件的时候,把所有输入流的格式都设置为Content-Type: application/octet-stream 代码如下: private static void writePost(final Connection.Request req, final OutputStream outputStream, final String bound) throws IOException { final Collection<Connection.KeyVal> data = req.data(); final BufferedWriter w = new BufferedWriter(new OutputStreamWriter(outputStream, req.postDataCharset())); if (bound != null) { // boundary will be set if we're in multipart mode for (Connection.KeyVal keyVal : data) { w.write("--"); w.write(bound); w.write("\r\n"); w.write("Content-Disposition: form-data; name=\""); w.write(encodeMimeName(keyVal.key())); // encodes " to %22 w.write("\""); if (keyVal.hasInputStream()) { w.write("; filename=\""); w.write(encodeMimeName(keyVal.value())); w.write("\"\r\nContent-Type: application/octet-stream\r\n\r\n"); w.flush(); // flush DataUtil.crossStreams(keyVal.inputStream(), outputStream); outputStream.flush(); } else { w.write("\r\n\r\n"); w.write(keyVal.value()); } w.write("\r\n"); } w.write("--"); w.write(bound); w.write("--"); } else if (req.requestBody() != null) { // data will be in query string, we're sending a plaintext body w.write(req.requestBody()); } else { // regular form data (application/x-www-form-urlencoded) boolean first = true; for (Connection.KeyVal keyVal : data) { if (!first) w.append('&'); else first = false; w.write(URLEncoder.encode(keyVal.key(), req.postDataCharset())); w.write('='); w.write(URLEncoder.encode(keyVal.value(), req.postDataCharset())); } } w.close(); } 经过源码找到了问题,怎么解决这个问题呢?jsoup上传文件的时候只能传参数InputStream,InputStream只能读取一次,再次读取InputStream获取不到内容,作者同时也增加了jsoup可以传参字节数组的功能。对jsoup源码进行改进 第一步: interface KeyVal 增加字段mimeType,byteArray /** * Update the mimeType of a keyval * @param key new key * @return this KeyVal, for chaining */ KeyVal mimeType(String mimeType); /** * Get the mimeType of a keyval * @return the key */ String mimeType();
/** * Add or update an input byte[] to this keyVal * @param bytes new byte[] * @return this KeyVal, for chaining */ KeyVal byteArray(byte[] bytes); byte[] byteArray(); boolean hasByteArray(); 第二步:KeyVal类实现上面的方法, public static class KeyVal implements Connection.KeyVal { private String key; private String value; private String mimeType;//conca自己增加的 private byte[] bytes; private InputStream stream; public KeyVal byteArray(byte[] bytes) { this.bytes = bytes; return this; } @Override public byte[] byteArray() { return bytes; } @Override public boolean hasByteArray() { return bytes!=null; } @Override public KeyVal mimeType(String mimeType) { Validate.notEmpty(mimeType, "Data mimeType must not be empty"); this.mimeType = mimeType; return this; } @Override public String mimeType() { // TODO Auto-generated method stub return mimeType; } } 第三步:修改上传方法writePost private static void writePost(final Connection.Request req, final OutputStream outputStream, final String bound) throws IOException { final Collection<Connection.KeyVal> data = req.data(); final BufferedWriter w = new BufferedWriter(new OutputStreamWriter(outputStream, req.postDataCharset())); if (bound != null) { // boundary will be set if we're in multipart mode for (Connection.KeyVal keyVal : data) { w.write("--"); w.write(bound); w.write("\r\n"); w.write("Content-Disposition: form-data; name=\""); w.write(encodeMimeName(keyVal.key())); // encodes " to %22 w.write("\""); if (keyVal.hasInputStream()) { w.write("; filename=\""); w.write(encodeMimeName(keyVal.value()));
if(keyVal.mimeType()!=null){ w.write("\"\r\nContent-Type: "+keyVal.mimeType()+"\r\n\r\n"); }else{ w.write("\"\r\nContent-Type: application/octet-stream\r\n\r\n"); }
w.flush(); // flush DataUtil.crossStreams(keyVal.inputStream(), outputStream); outputStream.flush(); }else if (keyVal.hasByteArray()) { w.write("; filename=\""); w.write(encodeMimeName(keyVal.value()));
if(keyVal.mimeType()!=null){ w.write("\"\r\nContent-Type: "+keyVal.mimeType()+"\r\n\r\n"); }else{ w.write("\"\r\nContent-Type: application/octet-stream\r\n\r\n"); }
w.flush(); // flush outputStream.write(keyVal.byteArray()); outputStream.flush(); } else { w.write("\r\n\r\n"); w.write(keyVal.value()); } w.write("\r\n"); } w.write("--"); w.write(bound); w.write("--"); } else if (req.requestBody() != null) { // data will be in query string, we're sending a plaintext body w.write(req.requestBody()); } else { // regular form data (application/x-www-form-urlencoded) boolean first = true; for (Connection.KeyVal keyVal : data) { if (!first) w.append('&'); else first = false; w.write(URLEncoder.encode(keyVal.key(), req.postDataCharset())); w.write('='); w.write(URLEncoder.encode(keyVal.value(), req.postDataCharset())); } } w.close(); } 第四步:使用例子代码如下: |