背景: 最近接到一個老項目需求,之前開發的WPS開放平臺文件(商密集成)預覽功能因為升級需要重新對接api,新的上傳文件接口踩坑特意記錄一下。
這里出問題的是第二步,請求文件上傳信息
踩坑代碼 調用后403 postman粘貼請求頭和地址發起模擬調用成功
private String upload(StoreRequest storeRequest, File file) throws IOException, URISyntaxException {URI url = new URIBuilder(storeRequest.getUrl()).build();HttpHeaders headers = new HttpHeaders();List<Header> storeRequestHeaders = storeRequest.getHeaders();storeRequestHeaders.forEach(header -> headers.add(header.getName(), header.getValue()));byte[] fileBytes = Files.readAllBytes(file.toPath());HttpEntity<byte[]> requestEntity = new HttpEntity<>(fileBytes, headers);return restTemplate.postForObject(url,requestEntity, String.class).getBody();}
修改后:
private String upload(StoreRequest storeRequest, File file) throws IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {// 1. 讀取文件為字節數組byte[] fileBytes = Files.readAllBytes(file.toPath());// 2. 創建信任所有證書的 HttpClientSSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -> true).build();try (CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build()) {// 3. 創建 POST 請求HttpPost httpPost = new HttpPost(storeRequest.getUrl());// 4. 設置 Headers(保持原始 Content-Type)List<Header> storeRequestHeaders = storeRequest.getHeaders();storeRequestHeaders.forEach(header ->httpPost.addHeader(header.getName(), header.getValue()));// 5. 設置請求體(二進制數據)ByteArrayEntity requestEntity = new ByteArrayEntity(fileBytes);httpPost.setEntity(requestEntity);// 6. 執行請求并獲取響應HttpResponse response = httpClient.execute(httpPost);org.apache.http.Header[] headers = response.getHeaders("X-Wps3-Info-Token");// 7. 返回響應頭中的 Tokenreturn headers[0].getValue();}}
問題原因
使用RestTemplate會自動根據上傳二進制文件自動響應Content-Type為application/octet-stream
后與wps開發確認,此處的確是傳空字符串。