fix: Barcode 처리 fix

dev
Jonguk. Lim 6 months ago
parent 4261c5e2b9
commit 9f8d649b58

@ -1,6 +1,5 @@
package cokr.xit.adds.biz.nims.web; package cokr.xit.adds.biz.nims.web;
import java.io.IOException;
import java.util.List; import java.util.List;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@ -12,8 +11,6 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.google.zxing.NotFoundException;
import cokr.xit.adds.biz.nims.model.BizNimsRequest; import cokr.xit.adds.biz.nims.model.BizNimsRequest;
import cokr.xit.adds.biz.nims.model.BizNimsResponse; import cokr.xit.adds.biz.nims.model.BizNimsResponse;
import cokr.xit.adds.biz.nims.service.BizNimsService; import cokr.xit.adds.biz.nims.service.BizNimsService;
@ -164,21 +161,13 @@ public class BizNimsController {
@Operation(summary = "barcode 이미지 제품 제조 정보 조회", description = "barcode 이미지 제품 제조 정보 조회<br><br>barcode 이미지를 통한 제품 제조 정보 조회") @Operation(summary = "barcode 이미지 제품 제조 정보 조회", description = "barcode 이미지 제품 제조 정보 조회<br><br>barcode 이미지를 통한 제품 제조 정보 조회")
@PostMapping(value = "/getProductInfoByQrcodeImg", consumes = { "multipart/form-data" }) @PostMapping(value = "/getProductInfoByQrcodeImg", consumes = { "multipart/form-data" })
//@PostMapping(value = "/api/biz/nims/v1/getQrcode") //@PostMapping(value = "/api/biz/nims/v1/getQrcode")
public ApiBaseResponse<List<NimsApiDto.ProductInfoKd>> getProductInfoByQrcodeImg( public ApiBaseResponse<NimsApiDto.ProductInfoKd> getProductInfoByQrcodeImg(
@RequestParam("uploadFiles") @RequestParam("uploadFiles")
final List<MultipartFile> multipartFiles final MultipartFile mf
) { ) {
List<NimsApiDto.ProductInfoKd> list = multipartFiles.stream().map(mf -> { return ApiBaseResponse.of(
//System.out.println(mf.getOriginalFilename()); bizNimsService.getPrdMnfSeqInfoOfBarcode(XingUtils.readQrcodeFromFile(XingUtils.convert(mf)))
//System.out.println(mf.getSize()); );
try {
return bizNimsService.getPrdMnfSeqInfoOfBarcode(XingUtils.readQrcodeFromFile(XingUtils.convert(mf)));
} catch (IOException | NotFoundException e) {
throw new RuntimeException(e);
}
}).toList();
return ApiBaseResponse.of(list);
} }

@ -18,14 +18,18 @@ import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter; import org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter;
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter; import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
import org.springframework.web.filter.CommonsRequestLoggingFilter; import org.springframework.web.filter.CommonsRequestLoggingFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import cokr.xit.adds.core.Constants; import cokr.xit.adds.core.Constants;
import cokr.xit.adds.core.spring.config.properties.CorsProperties;
import cokr.xit.adds.core.spring.filter.ReadableRequestWrapperFilter; import cokr.xit.adds.core.spring.filter.ReadableRequestWrapperFilter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@Configuration @Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer { public class WebMvcConfig implements WebMvcConfigurer {
/** /**
* logging exclude path * logging exclude path
@ -33,6 +37,8 @@ public class WebMvcConfig implements WebMvcConfigurer {
@Value("${app.log.request.exclude-patterns:}") @Value("${app.log.request.exclude-patterns:}")
private List<String> EXCLUDE_URL_REGEXS; private List<String> EXCLUDE_URL_REGEXS;
private final CorsProperties corsProperties;
/** /**
* MappingJackson2XmlHttpMessageConverter * MappingJackson2XmlHttpMessageConverter
* @param converters * @param converters
@ -100,4 +106,16 @@ public class WebMvcConfig implements WebMvcConfigurer {
bean.addUrlPatterns(Constants.API_URL_PATTERNS); bean.addUrlPatterns(Constants.API_URL_PATTERNS);
return bean; 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());
}
} }

@ -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;
/**
* <pre>
* description : CORS Properties
* - properties : app.cors
* fileName : CorsProperties
* author : julim
* date : 2023-04-28
* ======================================================================
*
* ----------------------------------------------------------------------
* 2023-04-28 julim
*
* </pre>
*/
@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;
}

@ -5,6 +5,7 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -24,9 +25,11 @@ import com.google.zxing.Result;
import com.google.zxing.WriterException; import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer; import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import cokr.xit.adds.core.spring.exception.ApiCustomException;
import lombok.val; import lombok.val;
/** /**
@ -52,39 +55,45 @@ public class XingUtils {
hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
} }
public static String readQrcodeFromPath(final String path) throws IOException, NotFoundException { public static String readQrcodeFromPath(final String path) {
val binaryBitmap = try {
new BinaryBitmap( BinaryBitmap binaryBitmap = new BinaryBitmap(
new HybridBinarizer( new HybridBinarizer(
new BufferedImageLuminanceSource( new BufferedImageLuminanceSource(
ImageIO.read( ImageIO.read(
new FileInputStream(path) 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 { public static String readQrcodeFromFile(final File file) {
val binaryBitmap = try {
new BinaryBitmap( BinaryBitmap binaryBitmap = new BinaryBitmap(
new HybridBinarizer( new HybridBinarizer(
new BufferedImageLuminanceSource( new BufferedImageLuminanceSource(
ImageIO.read( ImageIO.read(
file file
) )
) )
) )
); );
final Result result = new MultiFormatReader().decode(binaryBitmap);
final Result result = return result.getText();
new MultiFormatReader().decode(binaryBitmap);
} catch (NotFoundException | IOException e) {
throw ApiCustomException.create("QR코드 읽기 실패");
}
return result.getText();
} }
/** /**
@ -99,38 +108,47 @@ public class XingUtils {
final String charset, final String charset,
final Integer height, final Integer height,
final Integer width final Integer width
) throws IOException, WriterException { ) {
String cs = charset;
if (StringUtils.isEmpty(charset)) { try {
cs = StandardCharsets.UTF_8.name(); String cs = charset;
} if (StringUtils.isEmpty(charset)) {
val matrix = cs = StandardCharsets.UTF_8.name();
new MultiFormatWriter().encode( }
new String(data.getBytes(cs), cs), BitMatrix matrix = new MultiFormatWriter().encode(
format, new String(data.getBytes(cs), cs),
width, format,
height 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); } catch (WriterException | IOException e) {
throw ApiCustomException.create("QR코드 생성 실패");
MatrixToImageWriter.writeToPath( }
matrix, }
path.substring(path.lastIndexOf('.') + 1),
filePath
);
}
public static File convert(final MultipartFile mf) throws IOException { public static File convert(final MultipartFile mf) {
val name = mf.getOriginalFilename(); val name = mf.getOriginalFilename();
assert name != null; 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); try {
return path.toFile(); 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 { public static void main(String[] args) throws IOException, WriterException, NotFoundException {

@ -126,13 +126,24 @@ spring:
activate: activate:
on-profile: local on-profile: local
# h2: datasource:
# console: hikari:
# enabled: true driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy #org.mariadb.jdbc.Driver
# path: /h2-console #driver-class-name: org.mariadb.jdbc.Driver
# settings: #jdbc-url: jdbc:mariadb://211.119.124.9:4407/egov?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
# trace: false # jdbc-url: jdbc:log4jdbc:mariadb://211.119.124.9:4407/adds?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
# web-allow-others: 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: sql:
init: init:
@ -141,6 +152,8 @@ spring:
# data-locations: classpath:database/data.sql # data-locations: classpath:database/data.sql
app: app:
cors:
allowed-origins: http://localhost:9077
swagger: swagger:
url: url:
desc: 사고마약류폐기지원시스템 desc: 사고마약류폐기지원시스템
@ -154,3 +167,38 @@ app:
enabled: false enabled: false
# batch 실행 url 제외 패턴 # batch 실행 url 제외 패턴
exclude-patterns: '/api/batch/(.*), /api/batch/v1/*Bulks(.*)' 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

@ -10,6 +10,25 @@ app:
secretKey: xit5811807!@ secretKey: xit5811807!@
alg: PBEWithMD5AndDES alg: PBEWithMD5AndDES
type: base64 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: token:
typ: JWT typ: JWT
alg: HS512 alg: HS512

Loading…
Cancel
Save