[Gena Co.] Internship Project/GENA Labeling Tool
(25.03.05) Label CRUD & CSV File Download 기능 구현
Genie;
2025. 3. 6. 10:39
Label CRUD 구현
// Sample 엔터티
@Entity
@Table(name = "samples")
public class Sample extends Timestamp {
...
@Column(columnDefinition = "JSON")
@Convert(converter = ListToJsonConverter.class)
private List<String> labels;
- 샘플과 N:M 관계를 형성할 경우 PoC단계에서 중간 테이블이 계속 생성이 될 수 있음 -> Sample 에 Json 타입으로 리스트로 지정
- 이벤트 소싱기반 이기 때문에 중간 테이블에 비효율적으로 기록이 많이 될 수 있다는 점
File Download 기능 구현
@Transactional
public InputStreamResource getCsvFile(String datasetName) {
// 샘플은 sample_data에서의 id 기준으로 오름차순으로 정렬
List<Sample> samples = sampleRepository.findLatestUpdatedSampleOfDataset(datasetName);
if (samples.isEmpty()) throw new FileProcessingException("No data found for dataset");
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
CSVWriter csvWriter = new CSVWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
// 첫번째로 얻은 데이터를 Json 객체로 바꾸고, 키를 얻어서 CSV의 컬럼, Header로 사용
JsonObject firstSampleData = JsonParser.parseString(samples.get(0).getSampleData()).getAsJsonObject();
String[] headers = firstSampleData.keySet().toArray(new String[0]);
csvWriter.writeNext(headers);
// Sample 마다 data을 JSON으로 만들어서 CSV 파일의 로우 데이터 하나씩 추가
for (Sample sample : samples) {
JsonObject sampleData = JsonParser.parseString(sample.getSampleData()).getAsJsonObject();
String[] row = Arrays.stream(headers)
.map(header -> sampleData.has(header) ? sampleData.get(header).getAsString() : "")
.toArray(String[]::new);
csvWriter.writeNext(row);
}
csvWriter.close();
// 바이트타입으로 InputStreamResource 객체로 만듬
return new InputStreamResource(new ByteArrayInputStream(out.toByteArray()));
} catch (Exception e) {
throw new FileProcessingException("Error generating CSV file");
}
}
@GetMapping("/download/{dataset_name}")
public ResponseEntity<InputStreamResource> downloadCsvFile(@PathVariable(name = "dataset_name") String datasetName) {
InputStreamResource resource = datasetService.getCsvFile(datasetName);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + datasetName.replace(" ", "_") + ".csv")
.contentType(MediaType.parseMediaType("text/csv"))
.body(resource);
}
- 서비스단에서 나온 Resource를 헤더에 CNTENT_DIPOSITION과 미디어 타입을 지정을 해서 클라이언트가 CSV파일로 바로저장할 수 있도록 함