我已经编写了一个spring boot web / rest应用程序来处理遗留系统(DB表),该应用程序执行以下操作:
这里的问题是一些账单文件很大(1-2 GB)而且我得到了:
java.lang.OutOfMemoryError: Java heap space
当我试图选择文件内容时,这会发生在Hibernate中
现在如何让用户下载大文件而不会出现上述错误?请在下面查看POJO课程和Repos
实体类
@Entity
public class EbillStatus implements Serializable {
private static final long serialVersionUID = 1L;
@Id @GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy="uuid")
@Column(name="EBILL_STATUS_ID")
private String id;
@Column(name="CORPORATE_EBILL_ID", insertable=false, updatable=false)
private String corporateEbillId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="COMPLETION_DATETIME")
private Date completionDatetime;
@Column(name="FILENAME", insertable=false, updatable=false)
private String filename;
@Lob
private byte[] fileContent;
@Column(name="USER_ID")
private String username;
@Column(name="STATUS_ID")
private Integer status;
@Column(name="BILL_COUNT", insertable=false, updatable=false)
private Integer billCount;
private Integer accountCount;
}
存储库:
public interface EbillStatusRepository extends JpaRepository<EbillStatus, String> {
EbillStatus findByCorporateEbill(CorporateEbill corporateEbill);
@Query(value="select s FROM EbillStatus s WHERE s.corporateEbillId=?1")
EbillStatus findFile(String corporateEbillId);
}
服务方法实施:
@Service
public class EbillServiceImpl implements EbillService {
private EbillStatusRepository statusRepo;
@Autowired
public EbillServiceImpl(EbillStatusRepository statusRepo){
this.statusRepo = statusRepo;
}
@Override
public EbillFileModel getEbillFile(String username, String eBillId) throws NotFoundException{
EbillStatus ebill= statusRepo.findFile(eBillId);
if(ebill == null || !isEbillFileAvailable(ebill.getStatus()))
throw new NotFoundException("file not available for username: "+username+", eBillId: "+ eBillId);
return new EbillFileModel(ebill.getFilename(), ebill.getFileContent());
}
private boolean isEbillFileAvailable(Integer status){
return COMPLETED.equals(String.valueOf(status)) || DELIVERED.equals(String.valueOf(status));
}
}
给控制器的Pojo类
public class EbillFileModel {
private String fileName;
private byte[] fileContent;
public EbillFileModel(String fileName, byte[] fileContent) {
super();
this.fileName = fileName;
this.fileContent = fileContent;
}
public EbillFileModel() {
super();
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public byte[] getFileContent() {
return fileContent;
}
public void setFileContent(byte[] fileContent) {
this.fileContent = fileContent;
}
}
下载文件的控制器方法
@GetMapping(value = "/{username}/order/{eBillId}/download", produces = "application/zip")
public ResponseEntity<ByteArrayResource> downloadEbillFile(@PathVariable String username, @PathVariable String eBillId)
throws IOException, NotFoundException {
EbillFileModel file = ebillservice.getEbillFile(username, eBillId);
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CACHE_CONTROL, CACHE_CONTROL_VAL);
headers.add(HttpHeaders.PRAGMA,PRAGMA_VAL);
headers.setContentDispositionFormData(ATTACHMENT, file.getFileName());
headers.add(HttpHeaders.EXPIRES, ZERO);
return ResponseEntity
.ok()
.headers(headers)
.contentType(APPLICATION_ZIP)
.body(new ByteArrayResource(file.getFileContent()));
}
摘要和注释: