File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package kr.itn.itnhub.shared;
import kr.itn.itnhub.config.CurrentUser;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.List;
import java.util.Map;
/** 자료실. 기관에 딸리지 않는 공용 서식을 올려두고 내려받는다(요구사항 [26]). */
@RestController
public class SharedFileController {
private final SharedFileService service;
private final CurrentUser currentUser;
public SharedFileController(SharedFileService service, CurrentUser currentUser) {
this.service = service;
this.currentUser = currentUser;
}
@GetMapping("/api/shared-files")
public List<SharedFile> list() {
return service.list();
}
@PostMapping("/api/shared-files")
public List<SharedFile> add(@RequestPart("file") MultipartFile file,
@RequestPart(value = "description", required = false) String description,
Principal principal) throws IOException {
String name = file.getOriginalFilename() == null ? "file" : file.getOriginalFilename();
return service.add(name, description, file.getContentType(), file.getBytes(),
currentUser.displayName(principal));
}
@PutMapping("/api/shared-files/{id}")
public List<SharedFile> updateDescription(@PathVariable Long id,
@RequestBody Map<String, String> body) {
return service.updateDescription(id, body.get("description"));
}
/** 한글 파일명이 깨지지 않게 보고서 다운로드와 같은 RFC 5987 인코딩을 쓴다. */
@GetMapping("/api/shared-files/{id}")
public ResponseEntity<byte[]> download(@PathVariable Long id) {
SharedFileMapper.Content found = service.content(id);
String encodedName = URLEncoder.encode(found.fileName(), StandardCharsets.UTF_8)
.replace("+", "%20");
MediaType type = found.contentType() == null || found.contentType().isBlank()
? MediaType.APPLICATION_OCTET_STREAM
: MediaType.parseMediaType(found.contentType());
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedName)
.contentType(type)
.body(found.content());
}
@ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("/api/shared-files/{id}")
public void delete(@PathVariable Long id) {
service.delete(id);
}
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public Map<String, String> handleBadRequest(IllegalArgumentException e) {
return Map.of("message", e.getMessage());
}
}