Use RestTemplate to upload files to the remote interface

There is a business need. Need to synchronize an online file to the existing service without local storage conversion. The solution finally adopted is to use the RestTemplate provided by Spring to remotely operate the http service and achieve online file synchronization upload.

The following is the core code for file upload

Error presentation


    try{
    
    
            MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
            postParameters.add("type",type);
            postParameters.add("subType",subType);
		 
            //获取文件名称
            URL openUrl = new URL(chenvaFilePath+fileUrl);
            URLConnection urlConnection = openUrl.openConnection();
            int fileLength = urlConnection.getContentLength();
            byte[]bytes = new byte[fileLength];
            // 读取流信息,一次性写入字节数组(与下面正确示例中不同之处)
            InputStream inputStream = urlConnection.getInputStream();
            inputStream.read(bytes);
            inputStream.close();

            HttpHeaders fileHeader = new HttpHeaders();
            fileHeader.setContentType(MediaType.parseMediaType(urlConnection.getContentType()));
            fileHeader.setContentDispositionFormData("upload", fileName);
            HttpEntity<ByteArrayResource> filePart = new HttpEntity<>(new
                    ByteArrayResource(bytes),fileHeader);
            postParameters.add("upload",filePart);
        } catch (Exception e) {
    
    
            updateSyncStatus(projectId,dictId,"4");
            throw new RuntimeException("文件上传错误");
        }


        HttpHeaders headers = new HttpHeaders();

        // 使用客户端的请求头,发起请求
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.add("Cookie", newCookie);
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36");
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity(postParameters, headers);
        restTemplate.setRequestFactory(new NoRedirectClientHttpRequestFactory());

        restTemplate.postForObject(UPLOAD_PATH, request, String.class) ;

Problem Description

      When using the code above to upload files, the upload can be successful. An error occurred while downloading the file. The pdf file is uploaded in this business program, the file size is correct when downloading, and the content is blank. Finally, ByteOutputStream is used to cache bytes. It can be downloaded correctly.

Correct example


     try{
    
    
            MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
            postParameters.add("type",type);
            postParameters.add("subType",subType);
            //获取文件名称
            URL openUrl = new URL(chenvaFilePath+fileUrl);
            URLConnection urlConnection = openUrl.openConnection();
            InputStream inputStream = openUrl.openStream();
                
            // 将读取到的字节缓存到此处,用到的使用直接一次性获取
            ByteOutputStream byteOutputStream = new ByteOutputStream();

            int index = -1;
            byte[] bytes = new byte[1024];
            while ((index = inputStream.read(bytes)) != -1) {
    
    
                byteOutputStream.write(bytes,0,index);
            }
            inputStream.close();

            HttpHeaders fileHeader = new HttpHeaders();
            fileHeader.setContentType(MediaType.parseMediaType(urlConnection.getContentType()));
            fileHeader.setContentDispositionFormData("upload", fileName);
            HttpEntity<ByteArrayResource> filePart = new HttpEntity<>(new
                    ByteArrayResource(byteOutputStream.getBytes()),fileHeader);
            postParameters.add("upload",filePart);
        } catch (Exception e) {
    
    
            throw new RuntimeException("文件上传错误");
        }

        HttpHeaders headers = new HttpHeaders();

        // 使用客户端的请求头,发起请求
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.add("Cookie", newCookie);
        headers.add("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36");
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity(postParameters, headers);
        restTemplate.setRequestFactory(new NoRedirectClientHttpRequestFactory());

        restTemplate.postForObject(UPLOAD_PATH, request, String.class) ;

Implement SimpleClientHttpRequestFactory class

public class NoRedirectClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
    
    

    @Override
    protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
    
    
        // TODO Auto-generated method stub
        super.prepareConnection(connection, httpMethod);
        // 禁止自动重定向
        connection.setFollowRedirects(false);
    }
}

    So far the file can be uploaded normally

Problem recurrence

    When using maven to package and compile, an error is prompted, and the error message is as follows:

com.sun.xml.internal.messaging.saaj.util程序包不存在

    So I started surfing the Internet, how could there be problems at the critical moment of going online?
    The reason is that the ByteOutputStream class is used in the above sample program, which causes maven to find this type of information when performing the compiler. You can specify this type of location information when maven is compiled and packaged.

          <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${
    
    maven-compiler-plugin.version}</version>
                <configuration>
                   <!--重要部分-->
                    <compilerArguments>
                        <bootclasspath>${
    
    env.JAVA_HOME}\jre\lib\rt.jar;${
    
    env.JAVA_HOME}\jre\lib\jce.jar</bootclasspath>
                    </compilerArguments>
                    <source>${
    
    java.version}</source>
                    <target>${
    
    java.version}</target>
                    <encoding>${
    
    maven.compiler.encoding}</encoding>
                    <verbose/>
                </configuration>
            </plugin>

    Among them, ${env.JAVA_HOME} is a java system variable, which can be used directly in maven. Use mvn help:system to view the built-in information systematically.

    There are also some commonly used built-in variables of maven as follows:

${
    
    basedir} 项目根目录
${
    
    project.build.directory} 构建目录,缺省为target
${
    
    project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
${
    
    project.build.finalName} 产出物名称,缺省为${
    
    project.artifactId}-${
    
    project.version} 当前版本
${
    
    project.packaging} 打包类型,缺省为jar

Guess you like

Origin blog.csdn.net/qq_37640410/article/details/108336232