如何在 spring 引导中一次调用具有不同文件名的多个 webmethod URL
How to Invoke Multiple webmethod URLs with different filename at once in spring boot
我对 Spring 启动项目还很陌生。
我正在编写后端代码,我有一个网络方法 url,它可以根据文件号一次只下载一个文件。当用户输入 fileNo 并提交时从前端调用它。
用户一次最多可输入5个文件号(逗号分隔)。
在这种情况下,我必须获取每个文件编号并将其设置到我的 url 中,调用它将下载 5 个文件并将其放入一个公共文件夹中。
下面的代码适用于一个 FileNo 并下载文件,
有没有我可以同时设置和调用所有 5 个 URL 的地方,下载所有 5 个文件并将其放在同一个文件夹中。
或者,如果我必须在我的 URL 中一一设置,那么该怎么做。做这个的最好方式是什么。 (经历了一些类似的帖子,但对我的解决方案没有任何好处)。在这里寻找解决方案。谢谢
@SneakyThrows
@RequestMapping(value = "/{fileName:.+}", method = RequestMethod.GET)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success"),
@ApiResponse(code = 500, message = "Server Error")
})
public ResponseEntity getCollateralDownloadData(@PathVariable("fileName") String fileName) {
String wmURL = "https://www.qa.referencesite.com/invoke/File_appDesigns.process:processTpfQuery?prdType=PTO&tpf_aif=one&SALESNO=&PRODNO=&OASN="+fileName;
try {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<byte[]> response = restTemplate.build()
.exchange(wmURL, HttpMethod.GET, entity, byte[].class);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/octet-stream"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
.body(response.getBody());
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.OK).body("Collateral Download Created successfully");
}
根据您的需要,有 2 种方法:
- 客户端可能会并发触发请求,所以客户端必须为每个文件号发送一个请求,你后端处理它
- 客户端可能只触发一个请求,所以你的后端应该修改为触发后续调用,等待结果并构建一个共同的响应。您可以使用 Spring WebFlux 工具或 Java ExecutorService.invokeAll() 方法来管理后续的并行请求。
此致。
这是我完成的完整代码流程。
@RestController
public class 下载OAFileController {
@Autowired
private RestTemplateBuilder restTemplate;
private static final int MYTHREADS = 30;
@SneakyThrows
@RequestMapping(value = "/downloadzippedFile/{fileName}", method = RequestMethod.GET)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success"),
@ApiResponse(code = 500, message = "Server Error")
})
public ResponseEntity<Object> downloadzipFiles(@PathVariable("fileName") String fileName) throws IOException, ExecutionException, InterruptedException {
downloadMultipleFilesToRemoteDiskUsingThread(fileName);
String zipFilename = "/Users/kumars22/Downloads/Files.zip";
File file = new File(zipFilename);
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition",
String.format("attachment; filename=\"%s\"",file.getName()));
headers.add("Cache-Control","no-cache, no-store, no-revalidate");
headers.add("pragma","no-cache");
headers.add("Expires","0");
ResponseEntity<Object> responseEntity = ResponseEntity.ok().headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource);
return responseEntity;
}
//创建了一个所有文件都将被下载的目录(在 AWS 中得到了一些 space 用于实际实施。
public static void createDirectory() {
File file = new File("/Users/kumars22/Downloads/Files");
if (!file.exists()) {
file.mkdir();
}
}
public static void downloadMultipleFilesToRemoteDiskUsingThread( String fileName ) throws ExecutionException, InterruptedException, IOException {
createDirectory();
ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
String[] serials = fileName.split(",");
String[] wmURLs = new String[serials.length];
for (int i =0;i<serials.length;i++) {
wmURLs[i] = "https://www.qa.referencesite.com/invoke/File_appDesigns.process:processTpfQuery?prdType=PTO&tpf_aif=one&SALESNO=&PRODNO=&OASN="+serials[i];
}
for (int i = 0; i < wmURLs.length; i++) {
String url = wmURLs[i];
Runnable worker = new MultipleCallThreadController(url,fileName,"James");
executor.execute(worker);
}
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
zipFiles("/Users/kumars22/Downloads/Files","/Users/kumars22/Downloads/Files.zip");
System.out.println("\nFinished all threads");
}
//Zip the Folder having all files
public static void zipFiles(String sourceDirPath, String zipFilePath) throws IOException {
Path p = Files.createFile(Paths.get(zipFilePath));
Path pp = Paths.get(sourceDirPath);
try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p));
Stream<Path> paths = Files.walk(pp)) {
paths
.filter(path -> !Files.isDirectory(path))
.forEach(path -> {
ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
try {
zs.putNextEntry(zipEntry);
Files.copy(path, zs);
zs.closeEntry();
} catch (IOException e) {
System.err.println(e);
}
});
}
}
我对 Spring 启动项目还很陌生。
我正在编写后端代码,我有一个网络方法 url,它可以根据文件号一次只下载一个文件。当用户输入 fileNo 并提交时从前端调用它。
用户一次最多可输入5个文件号(逗号分隔)。
在这种情况下,我必须获取每个文件编号并将其设置到我的 url 中,调用它将下载 5 个文件并将其放入一个公共文件夹中。
下面的代码适用于一个 FileNo 并下载文件,
有没有我可以同时设置和调用所有 5 个 URL 的地方,下载所有 5 个文件并将其放在同一个文件夹中。 或者,如果我必须在我的 URL 中一一设置,那么该怎么做。做这个的最好方式是什么。 (经历了一些类似的帖子,但对我的解决方案没有任何好处)。在这里寻找解决方案。谢谢
@SneakyThrows
@RequestMapping(value = "/{fileName:.+}", method = RequestMethod.GET)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success"),
@ApiResponse(code = 500, message = "Server Error")
})
public ResponseEntity getCollateralDownloadData(@PathVariable("fileName") String fileName) {
String wmURL = "https://www.qa.referencesite.com/invoke/File_appDesigns.process:processTpfQuery?prdType=PTO&tpf_aif=one&SALESNO=&PRODNO=&OASN="+fileName;
try {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<byte[]> response = restTemplate.build()
.exchange(wmURL, HttpMethod.GET, entity, byte[].class);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType("application/octet-stream"))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
.body(response.getBody());
} catch (Exception e) {
e.printStackTrace();
}
return ResponseEntity.status(HttpStatus.OK).body("Collateral Download Created successfully");
}
根据您的需要,有 2 种方法:
- 客户端可能会并发触发请求,所以客户端必须为每个文件号发送一个请求,你后端处理它
- 客户端可能只触发一个请求,所以你的后端应该修改为触发后续调用,等待结果并构建一个共同的响应。您可以使用 Spring WebFlux 工具或 Java ExecutorService.invokeAll() 方法来管理后续的并行请求。
此致。
这是我完成的完整代码流程。
@RestController public class 下载OAFileController {
@Autowired
private RestTemplateBuilder restTemplate;
private static final int MYTHREADS = 30;
@SneakyThrows
@RequestMapping(value = "/downloadzippedFile/{fileName}", method = RequestMethod.GET)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success"),
@ApiResponse(code = 500, message = "Server Error")
})
public ResponseEntity<Object> downloadzipFiles(@PathVariable("fileName") String fileName) throws IOException, ExecutionException, InterruptedException {
downloadMultipleFilesToRemoteDiskUsingThread(fileName);
String zipFilename = "/Users/kumars22/Downloads/Files.zip";
File file = new File(zipFilename);
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition",
String.format("attachment; filename=\"%s\"",file.getName()));
headers.add("Cache-Control","no-cache, no-store, no-revalidate");
headers.add("pragma","no-cache");
headers.add("Expires","0");
ResponseEntity<Object> responseEntity = ResponseEntity.ok().headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource);
return responseEntity;
}
//创建了一个所有文件都将被下载的目录(在 AWS 中得到了一些 space 用于实际实施。
public static void createDirectory() {
File file = new File("/Users/kumars22/Downloads/Files");
if (!file.exists()) {
file.mkdir();
}
}
public static void downloadMultipleFilesToRemoteDiskUsingThread( String fileName ) throws ExecutionException, InterruptedException, IOException {
createDirectory();
ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
String[] serials = fileName.split(",");
String[] wmURLs = new String[serials.length];
for (int i =0;i<serials.length;i++) {
wmURLs[i] = "https://www.qa.referencesite.com/invoke/File_appDesigns.process:processTpfQuery?prdType=PTO&tpf_aif=one&SALESNO=&PRODNO=&OASN="+serials[i];
}
for (int i = 0; i < wmURLs.length; i++) {
String url = wmURLs[i];
Runnable worker = new MultipleCallThreadController(url,fileName,"James");
executor.execute(worker);
}
executor.shutdown();
// Wait until all threads are finish
while (!executor.isTerminated()) {
}
zipFiles("/Users/kumars22/Downloads/Files","/Users/kumars22/Downloads/Files.zip");
System.out.println("\nFinished all threads");
}
//Zip the Folder having all files
public static void zipFiles(String sourceDirPath, String zipFilePath) throws IOException {
Path p = Files.createFile(Paths.get(zipFilePath));
Path pp = Paths.get(sourceDirPath);
try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p));
Stream<Path> paths = Files.walk(pp)) {
paths
.filter(path -> !Files.isDirectory(path))
.forEach(path -> {
ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
try {
zs.putNextEntry(zipEntry);
Files.copy(path, zs);
zs.closeEntry();
} catch (IOException e) {
System.err.println(e);
}
});
}
}