Category: Spring Boot

0

Spring - M1 맥북에서 Embeded Redis 사용하기

목차 Spring - M1 맥북에서 Embeded Redis 사용하기 Spring - Embeded Redis 사용하기 참고 https://github.com/ozimov/embedded-redis https://github.com/redis/redis-hashes M1 Mac 에서 Embedded Redis 사용시 에러M1 맥북에서 Embedded Redis 를 그냥 사용하려고 하면 다음과 같이 redis server 를 시작할 수 없다는 에러가 발생합니다. Caused by: java.lang.RuntimeException: Can't start redis server. Check logs for details. Redis process log: at redis.embedded.AbstractRedisInstance.awaitRedisServerReady(AbstractRedisInstance.java:70) ~[embedded-redis-0.7.3.jar:na] at redis.embedded.AbstractRedisInstance.start(AbstractRedisInstance.java:42) ~[embedded-redis-0.7.3.jar:na] Embedded Redis 라이브러리 확인Embedded Redis 라이브러리에서 제공해주는 Redis 아키택처 정보들을 확인하면 M1 맥북에 해당하는 aarch64 용 Redis 를 지원하지 않습니다. 따라서, M1 에서 Embedded Redis 를 사용하기 위해서는 M1 용 아키택처에 맞게 Redis 를 새롭게 빌드해서 Embedded Redis 라이브러리가 띄울 수 있게 제공해야 합니다.

0

Spring Boot - StreamingResponseBody

목차 Spring Boot - StreamingResponseBody Spring Boot - ResourceRegion Spring Boot - 파일 다운로드 서비스 구현하기 Spring Boot - 파일 업로드 서비스 구현하기 Spring Boot - Resource 추상화 Spring Boot - MultipartFile 에서 발생하는 예외 처리 Spring Boot - MultipartFile 를 이용한 파일 업로드 Spring Boot - Part 객체를 이용한 파일 업로드 참고 https://www.baeldung.com/spring-mvc-sse-streams StreamingResponseBody Spring 에서 제공하는 비동기 요청 처리를 위한 객체, 응답값을 Byte 로 변환해 Streaming 형태로 줄 때 사용하는 객체 @GetMapping("/video3")public ResponseEntity<StreamingResponseBody> handleRbe() throws FileNotFoundException { File file = new File("/Users/dongwoo-yang/spring-file/mysong.mp4"); InputStream inputStream = new FileInputStream(file); StreamingResponseBody stream = out -> { byte[] data = new byte[1024]; int length = 0; while((length = inputStream.read(data)) >= 0){ out.write(data, 0, length); } inputStream.close(); out.flush(); }; HttpHeaders headers = new HttpHeaders(); headers.add("Content-Type", "video/mp4"); headers.add("Content-Length", Long.toString(file.length())); return ResponseEntity.ok().headers(headers).body(stream);}

0

Spring Boot - Actuator + Prometheus + Grafana

목차 Spring Boot - Actuator + Prometheus + Grafana Spring Boot - 메시지 국제화 MessageSource Spring Boot - WebMvcConfigurer Spring Boot - @SpringBootApplication 알아보기 참고 https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator https://www.baeldung.com/spring-boot-actuators https://docs.spring.io/spring-boot/docs/2.1.8.RELEASE/reference/html/production-ready.html https://covenant.tistory.com/244 https://devbksheen.tistory.com/182 Spring Boot - Actuator Actuator 는 별도의 구현 없이 Metric 정보, 트래픽 정보, 데이터 베이스 등 운영환경에서 Application 상태 정보에 접근 할 수 있는 기능을 제공하고, HTTP 와 JMX 를 이용해 접근할 수 있다. https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#actuator.endpoints 공식 문서에서 Actuator 가 지원하는 End Point 를 확인할 수 있다. Actuator 의존성 추가implementation 'org.springframework.boot:spring-boot-starter-actuator' 의존성을 추가한 뒤 Spring Application 을 실행 시킨 후 http://localhost:8080/actuator 로 접속하면 현재 Application 에서 End Point 들을 확인할 수 있다.

0

Spring Boot - ResourceRegion

목차 Spring Boot - StreamingResponseBody Spring Boot - ResourceRegion Spring Boot - 파일 다운로드 서비스 구현하기 Spring Boot - 파일 업로드 서비스 구현하기 Spring Boot - Resource 추상화 Spring Boot - MultipartFile 에서 발생하는 예외 처리 Spring Boot - MultipartFile 를 이용한 파일 업로드 Spring Boot - Part 객체를 이용한 파일 업로드 Http Range Request 서버에서 클라이언트로 HTTP 메시지 중 일부만 전송할 수 있도록 허용하는 기술 대용량의 미디어 파일, 파일 전송 중 일시 정지 및 다시 시작이 가능하다 Client 가 Range Header 를 통해 특정 리소스의 일부를 요청하면 서버가 그 부분만 전송하는 방식으로 동작한다. Server 가 Range Request 를 지원하면 Response Http Header 에 Content-Range 가 존재한다. HTTP Range 요청에 대한 정상 응답 코드로는 PARTIAL_CONTENT(206) 을 반환한다. Range 요청에 대한 응답 값이 Body 에 담겨져 있다. Spring Boot - ResourceRegion HttpRange 는 Range Header 정보를 담든 객체다. Request Header 로부터 정보를 얻어올 수 있다. ResourceRegion 는 전달 받은 Resource 객체 로부터 Range 범위 만큼 나눠 가져오는 객체다. @RestController@Slf4jpublic class VideoController { @GetMapping(value = "/video") public ResponseEntity<ResourceRegion> streamVideo(@RequestHeader HttpHeaders headers) throws IOException { UrlResource video = new UrlResource("file:/Users/dongwoo-yang/spring-file/mysong.mp4"); ResourceRegion resourceRegion; final long size = 1000000L; long contentLength = video.contentLength(); Optional<HttpRange> optional = headers.getRange().stream().findFirst(); HttpRange httpRange; if (optional.isPresent()) { httpRange = optional.get(); long start = httpRange.getRangeStart(contentLength); long end = httpRange.getRangeEnd(contentLength); long rangeLength = Long.min(size, end - start + 1); resourceRegion = new ResourceRegion(video, start, rangeLength); } else { long rangeLength = Long.min(size, contentLength); resourceRegion = new ResourceRegion(video, 0, rangeLength); } return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT) .contentType(MediaTypeFactory.getMediaType(video).orElse(MediaType.APPLICATION_OCTET_STREAM)) .body(resourceRegion); }} 서버에서 전송해주는 Resource Size 가 1 MB(1000000) 로 잡혀 있어 1 MB 씩 부분적으로 응답받는 것을 확인할 수 있다.

0

Spring Boot - 메시지 국제화 MessageSource

목차 Post not found: spring-boot/spring-framework/springboot-actuator Post not found: spring-boot/spring-framework/springboot-messageresource Post not found: spring-boot/spring-framework/configuration/springboot-WebMvcConfigurer Post not found: spring-boot/spring-framework/configuration/springboot-autoconfiguration 참고 https://gist.github.com/dlxotn216/cb9fe1e40c7961da9d7147d9ebc876d6 메시지 관리를 위한 MessageSource어플리케이션 개발을 진행하다가 보면 메시지를 보낼때 하드 코딩으로 넣다 보면 같은 맥략으로 쓰인 메시지들이 서로 상이하게 관리되는 것을 느낄 수 있었고 무엇보다 가장 큰 문제는 메시지를 변경하게 될 경우 해당 메시지가 사용된 소스를 전부 찾아 변경해 줘야 하는 문제점이 있다. 이런 메시지 파편화를 막고 한 곳에서 모든 메시지를 관리할 수 있도록 Spring 에서는 MessageSource 를 제공한다. MessageSource 메시지를 한 파일 message.properties 에서 관리할 수 있다. 경로 : main/resource/message.properties 메시지에 대한 다국어 처리 를 지원한다. 사용법 : message_[언어코드].properties 영어 : message_en.properties 한국어 : message_ko.properties 메시지 등록 경로 : main/resource/message.properties

0

Spring - Embedded Kafka 사용하기

목자 Spring - Kafka Spring - Kafka Java Config 사용하기 Spring - Embedded Kafka 사용하기 스프링 부트 카프카 사용하기참고https://www.baeldung.com/spring-boot-kafka-testing 의존성testImplementation 'org.springframework.boot:spring-boot-starter-test'testImplementation 'org.springframework.kafka:spring-kafka-test'// https://mvnrepository.com/artifact/org.testcontainers/kafkatestImplementation group: 'org.testcontainers', name: 'kafka', version: '1.16.3' Spring Propertiesspring: kafka: consumer: auto-offset-reset: earliest group-id: baeldungtest: topic: embedded-test-topic

0

Spring - Kafka Java Config 사용하기

목자 Spring - Kafka Spring - Kafka Java Config 사용하기 Spring - Embedded Kafka 사용하기 스프링 부트 카프카 사용하기참고https://www.baeldung.com/spring-kafka 목자 Post not found: spring-boot/spring-kafka/springboot-kafka Post not found: spring-boot/spring-kafka/springboot-kafka-javaconfig 의존성 추가implementation 'org.springframework.kafka:spring-kafka'testImplementation 'org.springframework.kafka:spring-kafka-test'

0

Spring - Kafka

스프링 부트 카프카 사용하기목자 Spring - Kafka Spring - Kafka Java Config 사용하기 Spring - Embedded Kafka 사용하기 의존성 추가implementation 'org.springframework.kafka:spring-kafka'testImplementation 'org.springframework.kafka:spring-kafka-test' 카프카에 접속하기 위한 설정Consumer 설정 spring.kafka.consumer.bootstrap-servers 카프카에 연결을 하기 위한 접속 주소 spring.kafka.consumer.group-id kafka Consumer 그룹에 대한 정보 spring.kafka.consumer.auto-offset-reset topic에 붙은 consumer의 offset 정보가 존재하지 않거나 오류가 발생해 offset을 사용할 수 없는 경우 처리하기 위한 옵션 latest : 가장 마지막 offset부터 earliest : 가장 처음 offset부터 none : offset 정보가 없으면 Exception 발생 spring.kafka.consumer.key-deserializer 카프카에서 전달받은 key 를 역질렬화 할때 사용하는 역질렬화 클래스 StringDeserializer 는 문자열 데이터만 사용 가능한 역직렬화 도구 spring.kafka.consumer.value-deserializer 카프카에서 전달받은 value 를 역질렬화 할때 사용하는 역질렬화 클래스 StringDeserializer 는 문자열 데이터만 사용 가능한 역직렬화 도구 Producer 설정

0

Spring - Embeded Redis 사용하기

목차 Spring - M1 맥북에서 Embeded Redis 사용하기 Spring - Embeded Redis 사용하기 참고https://www.baeldung.com/spring-embedded-redis Embeded Redis 사용하기 보통 Local 에서 테스트를 위해 많이 사용하며, 별도의 Redis 를 설치하지 않고 실행할 수 있게 해줍니다. 보통 Redis를 사용하는 스프링 프로젝트를 Local에서 프로젝트 실행시 Redis를 선행적으로 설치해줘야 한다. 이 문제를 Embedded Redis를 사용해 프로젝트가 Local 환경에 의존적이지 않고 프로젝트 만으로 구동할 수 있도록 한다. 1. Embedded Redis 사용을 위한 의존성 추가build.gradle 에 다음 Embedded Redis 사용을 위한 의존성을 추가해줍니다.

0

Spring Boot - WebMvcConfigurer

Matrix Variable 설정 참고 https://www.baeldung.com/spring-mvc-matrix-variables WebMvcConfigurer Spring MVC 설정을 추가, 변경하기 위해 사용하는 인터페이스WebMvcConfigurer 인터페이스는 CORS, Interceptor, ViewResolver, MessageConverter 등 여러가지 설정을 변경, 추가할 수 있게 도와준다. WebMvcConfigurer 인터페이스내 메소드들은 default 로 선어돼 있어 필요한 것만 구현하면 된다. add~: 기본 설정이 없는 Bean에 대하여 새로운 설정 Bean을 추가함 configure~: 기존 설정 대신 새롭게 정의한 설정 Bean을 사용한다. (set 메소드) extend~: 기존 설정에 새롭게 정의한 설정 Bean을 추가한다. (add 메소드) WebMvcConfigurer.java public interface WebMvcConfigurer { default void configurePathMatch(PathMatchConfigurer configurer) {} default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {} default void configureAsyncSupport(AsyncSupportConfigurer configurer) {} default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {} default void addFormatters(FormatterRegistry registry) {} default void addInterceptors(InterceptorRegistry registry) {} default void addResourceHandlers(ResourceHandlerRegistry registry) {} default void addCorsMappings(CorsRegistry registry) {} default void addViewControllers(ViewControllerRegistry registry) {} default void configureViewResolvers(ViewResolverRegistry registry) {} default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {} default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {} default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {} default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {} default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {} default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {} @Nullable default Validator getValidator() {return null;} @Nullable default MessageCodesResolver getMessageCodesResolver() {return null;}} CORS 설정Spring Boot 에서는 기본적으로 CORS에 대한 설정이 없기 때문에 CORS 를 사용하기 위해서는 WebMvcConfigurer 내 addCorsMappings 메소드를 이용해 설정해줘야 한다.

0

Spring Boot - MultipartFile 에서 발생하는 예외 처리

목차 Spring Boot - StreamingResponseBody Spring Boot - ResourceRegion Spring Boot - 파일 다운로드 서비스 구현하기 Spring Boot - 파일 업로드 서비스 구현하기 Spring Boot - Resource 추상화 Spring Boot - MultipartFile 에서 발생하는 예외 처리 Spring Boot - MultipartFile 를 이용한 파일 업로드 Spring Boot - Part 객체를 이용한 파일 업로드 MaxUploadSizeExceededException 예외MaxUploadSizeExceededException 예외가 발생하는 경우는 크게 두 가지가 있다. 첫 번째는 FileSizeLimitExceededException 예외가 발생했을 때 두 번째는 SizeLimitExceededException 예외가 발생했을 때다. FileSizeLimitExceededException 서버로 전송되는 각 파일 크기가 제한을 초과했을 때 발생하는 예외, 기본값은 1MB다.org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes. SizeLimitExceededException 서버로 전송되는 모든 파일 크기가 제한을 초과했을 때 발생하는 예외, 기본값은 10MB다.org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (29404104) exceeds the configured maximum (10485760)

0

Spring Boot - Resource 추상화

목차 Spring Boot - StreamingResponseBody Spring Boot - ResourceRegion Spring Boot - 파일 다운로드 서비스 구현하기 Spring Boot - 파일 업로드 서비스 구현하기 Spring Boot - Resource 추상화 Spring Boot - MultipartFile 에서 발생하는 예외 처리 Spring Boot - MultipartFile 를 이용한 파일 업로드 Spring Boot - Part 객체를 이용한 파일 업로드 Spring boot Resource 추상화https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/resources.html Resource 는 java.net.URL 을 추상화 해 스프링 프레임워크에서 Low-Level에 있는 자원에 쉽게 접근할 수 있도록 지원한다 ClassPath를 기준으로 리소스를 가져오는 기능의 부재 ServletContext를 기준으로 상대 경로를 읽어오는 기능의 부재 Resource.java public interface Resource extends InputStreamSource { boolean exists(); URL getURL() throws IOException; URI getURI() throws IOException; File getFile() throws IOException; long contentLength() throws IOException; long lastModified() throws IOException; Resource createRelative(String relativePath) throws IOException; @Nullable String getFilename(); String getDescription(); default boolean isReadable() { return exists(); } default boolean isOpen() { return false; } default boolean isFile() { return false; } default ReadableByteChannel readableChannel() throws IOException { return Channels.newChannel(getInputStream()); }} Resource 구현체

0

Spring Boot - 파일 다운로드 서비스 구현하기

목차 Spring Boot - StreamingResponseBody Spring Boot - ResourceRegion Spring Boot - 파일 다운로드 서비스 구현하기 Spring Boot - 파일 업로드 서비스 구현하기 Spring Boot - Resource 추상화 Spring Boot - MultipartFile 에서 발생하는 예외 처리 Spring Boot - MultipartFile 를 이용한 파일 업로드 Spring Boot - Part 객체를 이용한 파일 업로드 파일 다운로드를 위한 HTTP 해더서버에 저장된 파일을 다운 받기 위해서는 Response 해더에 Content-Disposition 정보가 필요합니다. Content-Disposition 는 HTTP 프로토콜에서 사용되는 헤더로, 서버가 클라이언트에게 제공하는 콘텐츠가 브라우저에 표시될지 또는 다운로드할지, 그리고 다운로드될 경우 파일 이름은 무엇인지 등을 지정합니다. Content-Disposition 는 inline, attachment 두 가지 종류가 있습니다. Content-Disposition 값이 inline 면 콘텐츠가 브라우저에서 직접 표시됩니다. attachment 면 콘텐츠가 다운로드를 위한 파일로 제공됩니다. filename 속성을 이용하면 다운로드하기 위한 파일이름을 지정할 수 있습니다. // Content-Disposition 값이 inline 일 경우 브라우저에 직접 표시됩니다.Content-Disposition: inline// attachment 일 경우 리소스를 파일로 다운로드할 수 있습니다. filename 속성을 통해 파일 이름을 지정할 수 있습니다.Content-Disposition: attachment; filename="example.txt" 리소스 다운로드 서비스 구현리소스를 반환하는 Response 객체에 Content-Disposition 해더를 추가해줍니다.

0

Spring Boot - 파일 업로드 서비스 구현하기

목차 Spring Boot - StreamingResponseBody Spring Boot - ResourceRegion Spring Boot - 파일 다운로드 서비스 구현하기 Spring Boot - 파일 업로드 서비스 구현하기 Spring Boot - Resource 추상화 Spring Boot - MultipartFile 에서 발생하는 예외 처리 Spring Boot - MultipartFile 를 이용한 파일 업로드 Spring Boot - Part 객체를 이용한 파일 업로드 DTO 생성하기@Datapublic class Item { private Long id; private String itemName; private UploadFile attachFile; // 여러개의 이미지 파일을 입력하기 위한 List private List<UploadFile> imageFiles;} 파일을 업로드 할때 중복된 이름을 가진 파일이 있을 경우 해당 파일로 업데이트 되는 문제가 발생합니다. 이를 해결하기 위해 파일을 저장할때는 다름 이름으로 저장하고 원래 파일이름을 별도로 저장합니다. 저장된 파일이름과 매핑되는 원래 파일 이름을 가져올 수 있도록 UploadFile 객체를 생성합니다. @Datapublic class UploadFile { private String uploadFileName; private String storeFileName; public UploadFile(String uploadFileName, String storeFileName) { this.uploadFileName = uploadFileName; this.storeFileName = storeFileName; }} 파일 저장 - 서비스 구현파일에서 확장자 추출하기

0

Spring Boot - MultipartFile 를 이용한 파일 업로드

목차 Spring Boot - StreamingResponseBody Spring Boot - ResourceRegion Spring Boot - 파일 다운로드 서비스 구현하기 Spring Boot - 파일 업로드 서비스 구현하기 Spring Boot - Resource 추상화 Spring Boot - MultipartFile 에서 발생하는 예외 처리 Spring Boot - MultipartFile 를 이용한 파일 업로드 Spring Boot - Part 객체를 이용한 파일 업로드 MultipartFile 인터페이스 multipart/form-data 요청을 처리하기 위해 만들어진 객체 Spring 에서는 멀티파트 요청을 처리 하기 위해 MultipartFile 객체를 제공합니다. public interface MultipartFile extends InputStreamSource { // 전달 받은 Parameter Key값을 가져온다. String getName(); // 파일 명을 가져온다. @Nullable String getOriginalFilename(); // 파일의 ContentType을 가져온다. // pdf 파일의 경우 application/pdf, mp4 파일의 경우 video/mp4, png 파일의 경우 image/png @Nullable String getContentType(); // 전달 받은 Parameter Value값이 비어 있는지 확인한다. boolean isEmpty(); // 전달 받은 파일의 크기를 가져온다. // 파일은 byte 단위로 표시된다. long getSize(); byte[] getBytes() throws IOException; // 전달 받은 파일을 읽기 위한 InputStream을 가져온다. @Override InputStream getInputStream() throws IOException; // MultipartFile 객체를 이용해 Resource(MultipartFileResource) 객체를 반환 받는다. default Resource getResource() { return new MultipartFileResource(this); } // MultipartFile 내 데이터를 전달받은 File 객체에 저장한다. // 한번만 호출이 가능한 메소드다. void transferTo(File dest) throws IOException, IllegalStateException; // MultipartFile 내 데이터를 전달받은 Path 객체에 저장한다. default void transferTo(Path dest) throws IOException, IllegalStateException { FileCopyUtils.copy(getInputStream(), Files.newOutputStream(dest)); }} 파일 업로드 구현파일 업로드를 위한 Controller 구현 multipart/form-data 요청은 Form 형식으로 요청이 오기 때문에 RequestBody 어노테이션이 아니라 RequestParam 어노테이션을 이용해 데이터를 받는다.