我在一个Spring项目中工作,以制作一个web应用程序,因此有一个Tomcat服务器允许我使用web应用程序
我在这个web应用程序上有两个功能,第一个允许我在Postgresql数据库上上传文件(它工作正常(。但在那之后,我希望能够下载这个文件。
这是我的服务方法。
public byte[] download(Integer id){
Line line = getById(Line.class, id);
int blobLenght;
byte[] fileToReturn = null;
Blob file = line.getFile();
blobLenght = (int)file.length();
fileToReturn = file.getBytes(1,blobLenght);
return fileToReturn;
}
在我的RestController上,我有一个带有注释@RequestMapping的方法。此方法返回一个ResponseEntity。在后面的方法中,lineService被注入(@Autowired(在类的顶部。
@RequestMapping(value = "/download", method = RequestMethod.GET)
public ResponseEntity<?> download(@RequestParam("id" Integer id)
{
byte[] fileToDownload = lineService.download(id);
return new ResponseEntity<byte[]>(fileToDownload,HttpStatus.OK);
}
我已经尽可能地简化了这个方法。
这是我的问题。事实上,当我一个接一个地提出一些请求时,我意识到了一种有效的方法。但是,服务器必须能够支持同时接收大量请求。现在,当我同时测试多个请求时,我得到了一个OutOfMemoryError:Java堆空间
我试图在方法"download"上实现Stream,但我得到了相同的错误。我无法很好地实现流。我尝试了许多在互联网上找到的解决方案,这是我实现的最后一个:
public ResponseEntity<byte[]> download(Integer id){
Line line = getById(Line.class, id);
HttpHeaders headers = new HttpHeaders();
InputStream is = line.getFile().getBinaryStream;
byte[] fileToReturn = IOUtils.toByteArray(is);
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(fileToDownload,HttpStatus.OK);
return responseEntity;
}
你知道我如何更新我的程序以满足项目的要求吗
如果我进展顺利,你能告诉我哪里错了吗?或者你有什么建议吗?
谢谢你的帮助!
下午。
我用stream修改了"download"方法,它能像我想要的那样正常工作。
public void download(Integer id, HttpServletResponse response){
Line line = getById(Line.class, id);
InputStream is = line.getFile().getBinaryStream;
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
}
我的控制器是这样的:
public ResponseEntity<?> download(@RequestParam("id") Integer id, HttpServletResponse response)
{
lineService.download(id,response);
return new ResponseEntity<>(HttpStatus.OK);
}
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.springframework.core.io.Resource;
@RestController
public class SomeClass{
@GetMapping("/{fileName}")
public ResponseEntity<Resource> getFile(@PathVariable String fileName, HttpServletRequest request, HttpServletResponse response) throws Exception {
Resource file = getFileAsResource(fileName);
HttpHeaders headers = prepareHeaderForFileReturn(fileName, request, response);
return new ResponseEntity<Resource>(file, headers, HttpStatus.OK);
}
private HttpHeaders prepareHeaderForFileReturn(String fileName, HttpServletRequest request,
HttpServletResponse response) {
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.CONTENT_TYPE, getContentTypeForAttachment(fileName));
response.setHeader("Content-Disposition", "attachment; filename="" + fileName + """);
return headers;
}
public Resource getFileAsResource(String filename) throws FileNotFoundException {
String filePath = path + "/" + filename;
Resource file = loadAsResource(filePath);
return file;
}
private Resource loadAsResource(String filename) throws FileNotFoundException {
try {
Path file = Paths.get(filename);
org.springframework.core.io.Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
} else {
log.error("Could not read file: " + filename);
throw new FileNotFoundException();
}
} catch (MalformedURLException e) {
log.error("Could not read file: " + filename, e);
throw new FileNotFoundException();
}
}
//Obtains a content type for file by his extension.
public String getContentTypeForAttachment(String fileName) {
String fileExtension = com.google.common.io.Files.getFileExtension(fileName);
if (fileExtension.equals("pdf")) return "application/pdf";
else if (fileExtension.equals("doc")) return "application/msword";
else if (fileExtension.equals("jpeg")) return "image/jpeg";
}
}