EXCLUDE_URL_REGEXS;
+ private final CorsProperties corsProperties;
+
/**
* MappingJackson2XmlHttpMessageConverter 순서를 가장 후순위로 조정
* @param converters
@@ -100,4 +106,16 @@ public class WebMvcConfig implements WebMvcConfigurer {
bean.addUrlPatterns(Constants.API_URL_PATTERNS);
return bean;
}
+
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/api/**")
+ .allowedOriginPatterns("*")
+ .allowedOrigins(corsProperties.getAllowedOrigins())
+ .allowedMethods(corsProperties.getAllowedMethods())
+ .allowedHeaders(corsProperties.getAllowedHeaders())
+ .allowCredentials(corsProperties.getAllowCredentials())
+ .maxAge(corsProperties.getMaxAge())
+ .exposedHeaders(corsProperties.getExposeHeader());
+ }
}
diff --git a/src/main/java/cokr/xit/adds/core/spring/config/properties/CorsProperties.java b/src/main/java/cokr/xit/adds/core/spring/config/properties/CorsProperties.java
new file mode 100644
index 0000000..75ae85e
--- /dev/null
+++ b/src/main/java/cokr/xit/adds/core/spring/config/properties/CorsProperties.java
@@ -0,0 +1,54 @@
+package cokr.xit.adds.core.spring.config.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ *
+ * description : CORS Properties
+ * - properties : app.cors 항목에 정의
+ * fileName : CorsProperties
+ * author : julim
+ * date : 2023-04-28
+ * ======================================================================
+ * 변경일 변경자 변경 내용
+ * ----------------------------------------------------------------------
+ * 2023-04-28 julim 최초 생성
+ *
+ *
+ */
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "app.cors")
+public class CorsProperties {
+ /**
+ * 헤더에 작성된 출처만 브라우저가 리소스를 접근할 수 있도록 허용함.
+ * * 이면 모든 곳에 공개
+ */
+ private String[] allowedOrigins;
+ /**
+ * 리소스 접근을 허용하는 HTTP 메서드를 지정
+ */
+ private String[] allowedMethods;
+ /**
+ * 요청을 허용하는 해더
+ */
+ private String[] allowedHeaders;
+ /**
+ * 클라이언트에서 preflight 의 요청 결과를 저장할 기간을 지정
+ * 해당 시간 동안 preflight 요청을 캐시하는 설정으로, 첫 요청 이후 60초 동안은 OPTIONS 메소드를 사용하는 예비 요청을 보내지 않는다.
+ */
+ private Long maxAge;
+ /**
+ * 클라이언트 요청이 쿠키를 통해서 자격 증명을 해야 하는 경우에 true.
+ * 자바스크립트 요청에서 credentials가 include일 때 요청에 대한 응답을 할 수 있는지를 나타낸다.
+ */
+ private Boolean allowCredentials;
+ /**
+ * 기본적으로 브라우저에게 노출이 되지 않지만, 브라우저 측에서 접근할 수 있게 허용해주는 헤더를 지정
+ * Content-Length
+ */
+ private String exposeHeader;
+}
diff --git a/src/main/java/cokr/xit/adds/core/util/XingUtils.java b/src/main/java/cokr/xit/adds/core/util/XingUtils.java
index 49ac862..bc840d9 100644
--- a/src/main/java/cokr/xit/adds/core/util/XingUtils.java
+++ b/src/main/java/cokr/xit/adds/core/util/XingUtils.java
@@ -5,6 +5,7 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
@@ -24,9 +25,11 @@ import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import cokr.xit.adds.core.spring.exception.ApiCustomException;
import lombok.val;
/**
@@ -52,39 +55,45 @@ public class XingUtils {
hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
}
- public static String readQrcodeFromPath(final String path) throws IOException, NotFoundException {
- val binaryBitmap =
- new BinaryBitmap(
- new HybridBinarizer(
- new BufferedImageLuminanceSource(
- ImageIO.read(
- new FileInputStream(path)
- )
- )
- )
- );
+ public static String readQrcodeFromPath(final String path) {
+ try {
+ BinaryBitmap binaryBitmap = new BinaryBitmap(
+ new HybridBinarizer(
+ new BufferedImageLuminanceSource(
+ ImageIO.read(
+ new FileInputStream(path)
+ )
+ )
+ )
+ );
+ final Result result = new MultiFormatReader().decode(binaryBitmap);
+
+ return result.getText();
+ } catch (NotFoundException | IOException e) {
+ throw ApiCustomException.create("QR코드 읽기 실패");
+ }
- final Result result = new MultiFormatReader().decode(binaryBitmap);
- return result.getText();
}
- public static String readQrcodeFromFile(final File file) throws IOException, NotFoundException {
- val binaryBitmap =
- new BinaryBitmap(
- new HybridBinarizer(
- new BufferedImageLuminanceSource(
- ImageIO.read(
- file
- )
- )
- )
- );
-
- final Result result =
- new MultiFormatReader().decode(binaryBitmap);
+ public static String readQrcodeFromFile(final File file) {
+ try {
+ BinaryBitmap binaryBitmap = new BinaryBitmap(
+ new HybridBinarizer(
+ new BufferedImageLuminanceSource(
+ ImageIO.read(
+ file
+ )
+ )
+ )
+ );
+ final Result result = new MultiFormatReader().decode(binaryBitmap);
+ return result.getText();
+
+ } catch (NotFoundException | IOException e) {
+ throw ApiCustomException.create("QR코드 읽기 실패");
+ }
- return result.getText();
}
/**
@@ -99,38 +108,47 @@ public class XingUtils {
final String charset,
final Integer height,
final Integer width
- ) throws IOException, WriterException {
- String cs = charset;
- if (StringUtils.isEmpty(charset)) {
- cs = StandardCharsets.UTF_8.name();
- }
- val matrix =
- new MultiFormatWriter().encode(
- new String(data.getBytes(cs), cs),
- format,
- width,
- height
+ ) {
+
+ try {
+ String cs = charset;
+ if (StringUtils.isEmpty(charset)) {
+ cs = StandardCharsets.UTF_8.name();
+ }
+ BitMatrix matrix = new MultiFormatWriter().encode(
+ new String(data.getBytes(cs), cs),
+ format,
+ width,
+ height
+ );
+ val filePath = Paths.get(QR_CODE_PATH, path);
+ MatrixToImageWriter.writeToPath(
+ matrix,
+ path.substring(path.lastIndexOf('.') + 1),
+ filePath
);
- val filePath = Paths.get(QR_CODE_PATH, path);
-
- MatrixToImageWriter.writeToPath(
- matrix,
- path.substring(path.lastIndexOf('.') + 1),
- filePath
- );
- }
+ } catch (WriterException | IOException e) {
+ throw ApiCustomException.create("QR코드 생성 실패");
+ }
+ }
- public static File convert(final MultipartFile mf) throws IOException {
+ public static File convert(final MultipartFile mf) {
val name = mf.getOriginalFilename();
-
assert name != null;
- val ext = name.substring(name.lastIndexOf("."));
- val filename = name.substring(0, name.lastIndexOf("."));
- val path = Files.createTempFile(filename, ext);
- mf.transferTo(path);
- return path.toFile();
+ try {
+ val ext = name.substring(name.lastIndexOf("."));
+ val filename = name.substring(0, name.lastIndexOf("."));
+ Path path = Files.createTempFile(filename, ext);
+ mf.transferTo(path);
+ return path.toFile();
+
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+
}
public static void main(String[] args) throws IOException, WriterException, NotFoundException {
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 2a68d5a..5c88a08 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -126,13 +126,24 @@ spring:
activate:
on-profile: local
- # h2:
- # console:
- # enabled: true
- # path: /h2-console
- # settings:
- # trace: false
- # web-allow-others: true
+ datasource:
+ hikari:
+ driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy #org.mariadb.jdbc.Driver
+ #driver-class-name: org.mariadb.jdbc.Driver
+ #jdbc-url: jdbc:mariadb://211.119.124.9:4407/egov?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
+ # jdbc-url: jdbc:log4jdbc:mariadb://211.119.124.9:4407/adds?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
+ # username: addsweb
+ # password: addsweb1234
+ jdbc-url: ENC(O26qFSqrfqMEjEU6jHUqrboYIPpTnwDIHIYQg2ddL0k7VsGvDbAMd/SwDeXjan17CykVLz3Qe++xW+VqxvQpT7/+Kxhl2ry1hTElOPxRHp6OrN/8GyhaScLCcBZgpxNcEAZ3a5qWJKIyLR/+KFk6YpW77lD10jFJvscNNYvFoWQIs/K5eAa/m3JnktX9Ed2RN8ttGgBET5g=)
+ username: ENC(M4g3XkH/bzupKW2w4WYH3Q==)
+ password: ENC(fzV0zekJQ7t/QHiz75k+xqdsDUWW6+MY)
+ auto-commit: false
+
+ devtools:
+ restart:
+ enabled: false
+ livereload:
+ enabled: true
sql:
init:
@@ -141,6 +152,8 @@ spring:
# data-locations: classpath:database/data.sql
app:
+ cors:
+ allowed-origins: http://localhost:9077
swagger:
url:
desc: 사고마약류폐기지원시스템
@@ -154,3 +167,38 @@ app:
enabled: false
# batch 실행 url 제외 패턴
exclude-patterns: '/api/batch/(.*), /api/batch/v1/*Bulks(.*)'
+
+---
+spring:
+ config:
+ activate:
+ on-profile: prod
+
+ datasource:
+ hikari:
+ driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy #org.mariadb.jdbc.Driver
+ #driver-class-name: org.mariadb.jdbc.Driver
+ #jdbc-url: jdbc:mariadb://211.119.124.9:4407/egov?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
+ # jdbc-url: jdbc:log4jdbc:mariadb://211.119.124.9:4407/adds?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
+ # username: addsweb
+ # password: addsweb1234
+ jdbc-url: ENC(O26qFSqrfqMEjEU6jHUqrboYIPpTnwDIHIYQg2ddL0k7VsGvDbAMd/SwDeXjan17CykVLz3Qe++xW+VqxvQpT7/+Kxhl2ry1hTElOPxRHp6OrN/8GyhaScLCcBZgpxNcEAZ3a5qWJKIyLR/+KFk6YpW77lD10jFJvscNNYvFoWQIs/K5eAa/m3JnktX9Ed2RN8ttGgBET5g=)
+ username: ENC(M4g3XkH/bzupKW2w4WYH3Q==)
+ password: ENC(fzV0zekJQ7t/QHiz75k+xqdsDUWW6+MY)
+ auto-commit: false
+
+springdoc:
+ api-docs:
+ enabled: true
+ swagger-ui:
+ enabled: true
+ path: /swagger-ui.html
+ csrf:
+ enabled: false
+
+app:
+ cors:
+ allowed-origins: http://localhost:9077, http://localhost:8081
+ log:
+ parameter-enabled: true
+ response-enabled: true
diff --git a/src/main/resources/config/application-app.yml b/src/main/resources/config/application-app.yml
index a3ebcbe..ba77a11 100644
--- a/src/main/resources/config/application-app.yml
+++ b/src/main/resources/config/application-app.yml
@@ -10,6 +10,25 @@ app:
secretKey: xit5811807!@
alg: PBEWithMD5AndDES
type: base64
+
+ cors:
+ # 헤더에 작성된 출처만 브라우저가 리소스를 접근할 수 있도록 허용함.
+ # * 이면 모든 곳에 공개
+ #allowed-origins: http://localhost:8080,http:127.0.0.1:8080
+ # 리소스 접근을 허용하는 HTTP 메서드를 지정
+ allowed-methods: GET, POST, PUT, DELETE
+ # 요청을 허용하는 해더
+ allowed-headers: Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, X-Csrftoken, Authorization
+ #allowed-headers: Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, X-Csrftoken, Authorization, Content-Security-Policy
+ # 클라이언트에서 preflight 의 요청 결과를 저장할 기간을 지정
+ # 60초 동안 preflight 요청을 캐시하는 설정으로, 첫 요청 이후 60초 동안은 OPTIONS 메소드를 사용하는 예비 요청을 보내지 않는다.
+ max-Age: 60
+ # 클라이언트 요청이 쿠키를 통해서 자격 증명을 해야 하는 경우에 true.
+ # 자바스크립트 요청에서 credentials가 include일 때 요청에 대한 응답을 할 수 있는지를 나타낸다.
+ allow-Credentials: true
+ # 기본적으로 브라우저에게 노출이 되지 않지만, 브라우저 측에서 접근할 수 있게 허용해주는 헤더를 지정
+ expose-Headers: Content-Length
+
token:
typ: JWT
alg: HS512