비즈니스 요구가 있습니다. 로컬 저장소 변환없이 온라인 파일을 기존 서비스에 동기화해야합니다. 최종적으로 채택 된 솔루션은 Spring에서 제공하는 RestTemplate을 사용하여 http 서비스를 원격으로 운영하고 온라인 파일 동기화 업로드를 달성하는 것입니다.
다음은 파일 업로드를위한 핵심 코드입니다.
오류 표시
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) ;
문제 설명
위의 코드를 사용하여 파일을 업로드하면 업로드가 성공할 수 있습니다. 파일을 다운로드하는 동안 오류가 발생했습니다. 이 비즈니스 프로그램에서 pdf 파일이 업로드되고 다운로드시 파일 크기가 정확하며 내용이 비어 있습니다. 마지막으로 ByteOutputStream은 바이트를 캐시하는 데 사용됩니다. 올바르게 다운로드 할 수 있습니다.
올바른 예
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) ;
SimpleClientHttpRequestFactory 클래스 구현
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);
}
}
지금까지 파일을 정상적으로 업로드 할 수 있습니다.
문제 재발
maven을 사용하여 패키징 및 컴파일 할 때 오류가 프롬프트되고 오류 메시지는 다음과 같습니다.
com.sun.xml.internal.messaging.saaj.util程序包不存在
그래서 나는 인터넷 서핑을 시작했는데, 온라인 접속의 중요한 순간에 어떻게 문제가있을 수 있었습니까?
그 이유는 위의 샘플 프로그램에서 ByteOutputStream 클래스를 사용하기 때문에 maven이 컴파일러 수행시 이러한 유형의 정보를 찾게되는데, maven을 컴파일하고 패키징 할 때 이러한 유형의 위치 정보를 지정할 수 있습니다.
<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>
그중 $ {env.JAVA_HOME}은 자바 시스템 변수로 maven에서 직접 사용할 수 있습니다. 내장 정보를 체계적으로 보려면 mvn help : system을 사용하십시오.
다음과 같이 maven의 일반적인 내장 변수도 있습니다.
${
basedir} 项目根目录
${
project.build.directory} 构建目录,缺省为target
${
project.build.outputDirectory} 构建过程输出目录,缺省为target/classes
${
project.build.finalName} 产出物名称,缺省为${
project.artifactId}-${
project.version} 当前版本
${
project.packaging} 打包类型,缺省为jar