Direct transmission memory byte [] file commons-httpclient

Projects need to generate an image file, and upload it to a third party platform. Interface to third-party platform is http interface. And provides a more comprehensive interface documentation.

private static final String username = "admin";
private static final String password = "123456";
public static void create(){
    String auth = encodeBase64(username+":"+password);
    HttpClient httpClient = HttpClients.createDefault();
    String url = "http://yourdomain/example-url";
    HttpPost httpPost = new HttpPost(url);
    httpPost.setHeader("Authorization", "Basic " + auth);
    //添加认证消息头
    try {
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
        //添加要上传的文件
        multipartEntityBuilder.addBinaryBody("FILE", new File("E://111.jpg")).setMode(HttpMultipartMode.RFC6532);
        //传入参数
        multipartEntityBuilder.addPart("IMAGE_TYPE", new StringBody("111",ContentType.APPLICATION_JSON));
        multipartEntityBuilder.addPart("PAGE_NUM", new StringBody("1",ContentType.APPLICATION_JSON));
        multipartEntityBuilder.addPart("CREATE_TIME", new StringBody("2018-3-8 1:38:56",ContentType.APPLICATION_JSON));
        httpPost.setEntity(multipartEntityBuilder.build());
        HttpResponse httpResponse = httpClient.execute(httpPost);
        int code = httpResponse.getStatusLine().getStatusCode();
        if (code == 200) {
            String strResult = EntityUtils.toString(httpResponse.getEntity());
            System.out.println(strResult);
        } else{
            HttpEntity httpEntity = httpResponse.getEntity();
            String content = EntityUtils.toString(httpEntity);
            System.out.println(content);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}
public static void main(String[] args) throws Exception {
    create();
}

Document call based httpClient way, and the practice of uploading files is to upload local File.
The project has been used in older commons-httpclient.

And my file is already generating good in-memory byte [] data. More direct approach is to first byte [] to save the data to a temporary directory. In the new File by reading the file and upload it. But as a obsessive-compulsive disorder, so unnecessary is unacceptable. So we need to explore how to lower commons-httpclient upload byte [] file format directly.

First, of course, is to look at how commons-httpclient upload files.

One example is beginning to find:

MultipartPostMethod filePost = new MultipartPostMethod(targetURL);
filePost.addParameter( "fileName" , targetFilePath);
HttpClient client = new HttpClient();
 
// 由于要上传的文件可能比较大 , 因此在此设置最大的连接超时时间
client.getHttpConnectionManager(). getParams().setConnectionTimeout(5000);
int status = client.executeMethod(filePost);

However, used in the project are commons-httpclient-3.0, MultipartPostMethod has been abandoned. But also directly addParameter( "fileName" , targetFilePath);read the source code under a bad adjustment.

(: Http: //svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/examples/MultipartFileUploadApp.java view = co? Address) to find the last example of the official website

By the way, commons-httpclient has stopped maintenance, we recommended httpClient.

Some sample code adjustment.

PostMethod filePost = new PostMethod(targetURL);
File targetFile = new File("E:/111.jpg");
try {
    System.out.println("Uploading " + targetFile.getName() + " to " + targetURL);
    Part[] parts = {
            new FilePart(targetFile.getName(), targetFile)
    };
    filePost.setRequestEntity(
            new MultipartRequestEntity(parts, filePost.getParams())
    );
    HttpClient client = new HttpClient();
    client.getHttpConnectionManager().
            getParams().setConnectionTimeout(5000);
    int status = client.executeMethod(filePost);
    if (status == HttpStatus.SC_OK) {
        System.out.println(
                "Upload complete, response=" + filePost.getResponseBodyAsString()
        );
    } else {
        System.out.println(
                "Upload failed, response=" + HttpStatus.getStatusText(status)
        );
    }
} catch (Exception ex) {
    System.out.println("ERROR: " + ex.getClass().getName() + " " + ex.getMessage());
    ex.printStackTrace();
} finally {
    filePost.releaseConnection();
}

The main parameters can be seen in parts inside. FilePart which is the file you want to upload parameters. The first argument of the constructor FilePart parameter names, the second file objects.
View FilePart source, the constructor:

public FilePart(String name, File file)
        throws FileNotFoundException {
    this(name, ((PartSource) (new FilePartSource(file))), null, null);
}

It can be seen that the objects to be packaged File FilePartSource.
Further sendData following method FilePart

protected void sendData(OutputStream out) throws IOException {
    LOG.trace("enter sendData(OutputStream out)");
    if (lengthOfData() == 0L) {
        LOG.debug("No data to send.");
        return;
    }
    byte tmp[] = new byte[4096];
    InputStream instream = source.createInputStream();
    int i;
    try {
        while ((i = instream.read(tmp)) >= 0) out.write(tmp, 0, i);
    } finally {
        instream.close();
    }
}

You can guess this is to get http link OutputStream, entered, and write data. Written content from the source inside InputStream get. The source is in front of FilePartSource.
View FilePartSource source, the equivalent of one package is File. The main method is the interface PartSource several methods of implementation.

public interface PartSource {

    public abstract long getLength();

    public abstract String getFileName();

    public abstract InputStream createInputStream()
            throws IOException;
}

Think sendData method which calls source.createInputStream();If this is not the place to get a FileInputStream InputStream but ByteArrayInputStream if not can it? That write their own BytesFilePartSource PartSource class implements an interface, but not encapsulated File, but the package byte [] is not on it. Then the incoming write their own BytesFilePartSource build FilePart. According FilePartSource wrote his BytesFilePartSource.

public class BytesFilePartSource implements PartSource {

    private byte[] bytes;
    private String fileName;

    public BytesFilePartSource(String fileName, byte[] bytes)
            throws FileNotFoundException {
        this.fileName = fileName;
        this.bytes = bytes;

    }

    @Override
    public long getLength() {
        if (bytes != null)
            return bytes.length;
        else
            return 0L;
    }

    @Override
    public String getFileName() {
        return fileName != null ? fileName : "noname";
    }

    @Override
    public InputStream createInputStream() throws IOException {
        if (bytes != null)
            return new ByteArrayInputStream(bytes);
        else
            return new ByteArrayInputStream(new byte[0]);
    }

}

In fact, look for the code found in the jar has a class that implements this functionality: ByteArrayPartSource. So use this class on the line, do not repeat the wheel made.

The main code is as follows:

HttpClient httpClient = new HttpClient();
httpClient.getHttpConnectionManager().
        getParams().setConnectionTimeout(5000);
PostMethod postMethod = new PostMethod(url);
// 添加认证消息头
postMethod.setRequestHeader("Authorization", "Basic " + auth);
try {
    Part[] parts = {
            new FilePart("FILE", new ByteArrayPartSource("111.jpg", imageBytes)),
            new StringPart("IMAGE_TYPE", imageType, "GBK"),
            new StringPart("SEQ_NUMBER", pageNum + "", "GBK"),
            new StringPart("PAGE_NUM", time, "GBK"),
            new StringPart("CREATE_TIME", time, "GBK")
    };
    postMethod.setRequestEntity(new MultipartRequestEntity(parts,
            postMethod.getParams()));
    int status = httpClient.executeMethod(postMethod);
    log.info("status:" + status + "Result:" + strResult);
} catch (Exception e) {
    e.printStackTrace();
    contentId = "";
} finally {
    postMethod.releaseConnection();
}

Finally, in fact, the latest httpclient also support sending binary data directly, no need to save data to disk and then read.

Guess you like

Origin www.cnblogs.com/jimmyfan/p/11348700.html