diff --git a/src/main/java/com/interplug/qcast/biz/MainController.java b/src/main/java/com/interplug/qcast/biz/MainController.java index c092c112..70bdec4b 100644 --- a/src/main/java/com/interplug/qcast/biz/MainController.java +++ b/src/main/java/com/interplug/qcast/biz/MainController.java @@ -1,6 +1,8 @@ package com.interplug.qcast.biz; +import com.interplug.qcast.config.message.Messages; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -10,11 +12,11 @@ import org.springframework.web.bind.annotation.RestController; @RequestMapping("/api/main") public class MainController { - @GetMapping("/v1.0") - public String main() { - if (log.isDebugEnabled()) { - log.debug("MainController"); - } - return "Main"; + @Autowired + Messages message; + + @GetMapping + public String Main() { + return message.getMessage("example.msg.001"); } } diff --git a/src/main/java/com/interplug/qcast/config/Exception/BaseException.java b/src/main/java/com/interplug/qcast/config/Exception/BaseException.java new file mode 100644 index 00000000..71d9d07a --- /dev/null +++ b/src/main/java/com/interplug/qcast/config/Exception/BaseException.java @@ -0,0 +1,21 @@ +package com.interplug.qcast.config.Exception; + +import java.io.Serial; + +public class BaseException extends Exception{ + + @Serial + private static final long serialVersionUID = 6263785244527827114L; + + public BaseException() { + super(); + } + + public BaseException(String message) { + super(message); + } + + public BaseException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/interplug/qcast/config/message/MessageConfig.java b/src/main/java/com/interplug/qcast/config/message/MessageConfig.java new file mode 100644 index 00000000..85308f18 --- /dev/null +++ b/src/main/java/com/interplug/qcast/config/message/MessageConfig.java @@ -0,0 +1,21 @@ +package com.interplug.qcast.config.message; + +import java.io.IOException; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ResourceBundleMessageSource; + +@Configuration +public class MessageConfig { + + @Bean + public MessageSource messageSource() throws IOException { + ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); + messageSource.setBasename("message/message"); + messageSource.setDefaultEncoding("UTF-8"); + messageSource.setFallbackToSystemLocale(false); + + return messageSource; + } +} diff --git a/src/main/java/com/interplug/qcast/config/message/Messages.java b/src/main/java/com/interplug/qcast/config/message/Messages.java new file mode 100644 index 00000000..0ddf70ad --- /dev/null +++ b/src/main/java/com/interplug/qcast/config/message/Messages.java @@ -0,0 +1,23 @@ +package com.interplug.qcast.config.message; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.lang.Nullable; +import org.springframework.stereotype.Component; + +@Component +public class Messages { + + @Autowired + private MessageSource messageSource; + + public String getMessage(String code) { + return messageSource.getMessage(code, null, LocaleContextHolder.getLocale()); + } + + public String getMessage(String code, @Nullable Object... args) { + return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); + } + +} diff --git a/src/main/java/com/interplug/qcast/config/security/WebConfig.java b/src/main/java/com/interplug/qcast/config/security/WebConfig.java index 4d2ad7d4..265cb94c 100644 --- a/src/main/java/com/interplug/qcast/config/security/WebConfig.java +++ b/src/main/java/com/interplug/qcast/config/security/WebConfig.java @@ -2,12 +2,19 @@ package com.interplug.qcast.config.security; import com.fasterxml.jackson.databind.ObjectMapper; import com.interplug.qcast.config.json.HtmlCharacterEscapes; +import io.micrometer.common.lang.NonNullApi; +import jakarta.servlet.http.HttpServletRequest; +import java.util.Locale; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; +import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; /** *
@@ -43,4 +50,49 @@ public class WebConfig implements WebMvcConfigurer {
 		return new MappingJackson2HttpMessageConverter(copy);
 	}
 
+	/**
+	 * 기본 로케일 설정
+	 * @return LocaleResolver
+	 */
+	@Bean
+	public LocaleResolver localeResolver() {
+		HeaderLocaleResolver localeResolver = new HeaderLocaleResolver();
+		localeResolver.setDefaultLocale(Locale.KOREA);
+		return localeResolver;
+	}
+
+	/**
+	 * 로케일 변경 인터셉터
+	 * @return LocaleChangeInterceptor
+	 */
+	@Bean
+	public LocaleChangeInterceptor localeChangeInterceptor() {
+		LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
+		localeChangeInterceptor.setParamName("lang");
+		return localeChangeInterceptor;
+	}
+
+	/**
+	 * 인터셉터 등록
+	 * @param registry InterceptorRegistry
+	 */
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		registry.addInterceptor(localeChangeInterceptor());
+	}
+
+	/**
+	 * locale 변경을 위한 HeaderLocaleResolver
+	 */
+	@NonNullApi
+	private static class HeaderLocaleResolver extends AcceptHeaderLocaleResolver {
+		@Override
+		public Locale resolveLocale(HttpServletRequest request) {
+			String lang = request.getHeader("lang");
+			if (lang == null || lang.isEmpty()) {
+				return super.resolveLocale(request);
+			}
+			return new Locale(lang);
+		}
+	}
 }
diff --git a/src/main/java/com/interplug/qcast/config/swagger/SwaggerConfig.java b/src/main/java/com/interplug/qcast/config/swagger/SwaggerConfig.java
index fcd7bf32..f83f1d0d 100644
--- a/src/main/java/com/interplug/qcast/config/swagger/SwaggerConfig.java
+++ b/src/main/java/com/interplug/qcast/config/swagger/SwaggerConfig.java
@@ -2,8 +2,11 @@ package com.interplug.qcast.config.swagger;
 
 import io.swagger.v3.oas.models.OpenAPI;
 import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.media.StringSchema;
+import io.swagger.v3.oas.models.parameters.Parameter;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springdoc.core.customizers.OpenApiCustomizer;
 import org.springdoc.core.models.GroupedOpenApi;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
@@ -31,6 +34,16 @@ public class SwaggerConfig {
 
   @Bean
   public GroupedOpenApi allApi() {
-    return GroupedOpenApi.builder().group("ALL").packagesToScan("com.interplug.qcast.biz").build();
+    return GroupedOpenApi.builder().group("ALL").packagesToScan("com.interplug.qcast.biz").addOpenApiCustomizer(openApiCustomizer()).build();
+  }
+  
+  @Bean
+  public OpenApiCustomizer openApiCustomizer() {
+    Parameter lang = new Parameter().name("lang").description("Language").in("header").schema(new StringSchema());
+    return openApi -> openApi.getPaths().values().forEach(
+        pathItem -> pathItem.readOperations().forEach(
+            operation -> operation.addParametersItem(lang)
+        )
+    );
   }
 }
diff --git a/src/main/resources/message/message_ja.properties b/src/main/resources/message/message_ja.properties
new file mode 100644
index 00000000..5fd8a129
--- /dev/null
+++ b/src/main/resources/message/message_ja.properties
@@ -0,0 +1 @@
+example.msg.001=一般メッセージ
\ No newline at end of file
diff --git a/src/main/resources/message/message_ko.properties b/src/main/resources/message/message_ko.properties
new file mode 100644
index 00000000..dc5676d9
--- /dev/null
+++ b/src/main/resources/message/message_ko.properties
@@ -0,0 +1 @@
+example.msg.001=일반메시지
\ No newline at end of file