瀏覽代碼

websocket cors

shjung 3 年之前
父節點
當前提交
d49b12a480

+ 2 - 2
pom.xml

@@ -47,12 +47,12 @@
         <dependency>
             <groupId>org.fusesource.jansi</groupId>
             <artifactId>jansi</artifactId>
-            <version>2.4.0</version>
+            <version>1.8</version>
         </dependency>
         <dependency>
             <groupId>com.jcabi</groupId>
             <artifactId>jcabi-log</artifactId>
-            <version>0.20.1</version>
+            <version>LATEST</version>
             <optional>true</optional>
         </dependency>
 

+ 5 - 3
src/main/java/com/its/api/aop/LoggingAspect.java

@@ -12,18 +12,20 @@ import org.springframework.util.StopWatch;
 @Component
 public class LoggingAspect {
 
-    @Around("execution( public * com.its.op.controller..*.*(..) )")
+    @Around("execution( public * com.its.api.its.controller..*.*(..) )")
     public Object loadingElapsedTime(ProceedingJoinPoint joinPoint) throws Throwable {
 
         String proceedName = String.format("%50s", joinPoint.getTarget().getClass().getSimpleName() + "." + joinPoint.getSignature().getName());
-        log.info("[LOADING...] {}: START.", proceedName);
+        //log.info("[LOADING...] {}: START.", proceedName);
         StopWatch stopWatch = new StopWatch();
         stopWatch.start(proceedName);
 
         Object proceed = joinPoint.proceed();
 
         stopWatch.stop();
-        log.info("[LOADING...] {}: ..END. {} ms. Completed.", proceedName, stopWatch.getTotalTimeMillis());
+        if (stopWatch.getTotalTimeMillis() > 500) {
+            log.warn("[LOADING...] {}: ..END. {} ms. Completed.", proceedName, stopWatch.getTotalTimeMillis());
+        }
 
         return proceed;
     }

+ 0 - 14
src/main/java/com/its/api/its/exception/ApiException.java

@@ -1,14 +0,0 @@
-package com.its.api.its.exception;
-
-public class ApiException extends RuntimeException {
-
-    private ErrorCode tscSsipErrorCode;
-
-    public ApiException(ErrorCode tscSsipErrorCode) {
-        this.tscSsipErrorCode = tscSsipErrorCode;
-    }
-
-    public ErrorCode getErrorCode() {
-        return this.tscSsipErrorCode;
-    }
-}

+ 0 - 8
src/main/java/com/its/api/its/exception/ApiExceptionService.java

@@ -1,8 +0,0 @@
-package com.its.api.its.exception;
-
-public class ApiExceptionService extends ApiException {
-
-    public ApiExceptionService(ErrorCode tscSsipErrorCode) {
-        super(tscSsipErrorCode);
-    }
-}

+ 4 - 5
src/main/java/com/its/api/its/exception/ErrorCode.java

@@ -14,8 +14,8 @@ public enum ErrorCode {
     NOTFOUND_BROKER_INFO (4,"접속 가능한 브로커 정보가 없음"),
     NOTFOUND_URL         (5,"잘못된 URL 경로"),
     ERROR_INTERNAL_DATA  (6,"내부 데이터 오류"),
-    NOT_AVAILABLE        (7,"현재 사용할수 없음"),       // useyn='N'
-    PENDING_REGISTRATION (8,"등록 대기 중");             // Navi Device, 등록 대기중 useyn='Y', state='R'
+    NOT_AVAILABLE        (7,"현재 사용할수 없음"),
+    PENDING_REGISTRATION (8,"등록 대기 중");
 
     private final int code;
     private final String message;
@@ -29,11 +29,10 @@ public enum ErrorCode {
     static {
         map = new HashMap<>();
         for (ErrorCode e : values())
-            map.put(Integer.valueOf(e.code), e);
+            map.put(e.code, e);
     }
 
     public static ErrorCode getValue(int code) {
-
-        return map.get(Integer.valueOf(code));
+        return map.get(code);
     }
 }

+ 12 - 20
src/main/java/com/its/api/its/exception/ErrorResponse.java

@@ -2,39 +2,31 @@ package com.its.api.its.exception;
 
 import lombok.Builder;
 import lombok.Getter;
+import lombok.ToString;
 
 import java.time.LocalDateTime;
-import java.util.ArrayList;
 import java.util.List;
 
 @Getter
+@ToString
 public class ErrorResponse {
-    private LocalDateTime timestamp;
+    private final LocalDateTime timestamp;
     private final int status;
-    private String title;
+    private final String title;
     private final String message;
-    private List<String> errors;
+    private final String path;
+    private final List<String> errors;
 
     @Builder
-    public ErrorResponse(LocalDateTime timestamp, int status, String title, String message, List<String> errors) {
-        this.timestamp    = timestamp;
+    public ErrorResponse(LocalDateTime timestamp, int status, String title, String message, String path, List<String> errors) {
+        this.timestamp = timestamp;
         this.status    = status;
-        this.title = title;
-        this.message = message;
-        this.errors  = errors;//initErrors(errors);
+        this.title     = title;
+        this.message   = message;
+        this.path      = path;
+        this.errors    = errors;
     }
 
-    private List<FieldError> initErrors(List<FieldError> errors) {
-        return (errors == null) ? new ArrayList<>() : errors;
-    }
-/*
-    public static ErrorResponse buildError(ErrorCode errorCode) {
-        return ErrorResponse.builder()
-                .code(errorCode.getCode())
-                .message(errorCode.getMessage())
-                .build();
-    }*/
-
     @Getter
     public static class FieldError {
         private final String field;

+ 88 - 69
src/main/java/com/its/api/its/exception/ExceptionControllerAdvisor.java

@@ -1,91 +1,110 @@
 package com.its.api.its.exception;
 
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.support.DefaultMessageSourceResolvable;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
 import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 
 import javax.servlet.http.HttpServletRequest;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import java.util.stream.Collectors;
+import java.util.NoSuchElementException;
 
 @Slf4j
 @ControllerAdvice
 public class ExceptionControllerAdvisor {//} extends ResponseEntityExceptionHandler {
 
-    /*@Override
-    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
-
-        List<String> errorList = ex
-                .getBindingResult()
-                .getFieldErrors()
-                .stream()
-                .map(DefaultMessageSourceResolvable::getDefaultMessage)
-                .collect(Collectors.toList());
-
-        return new ResponseEntity<>(
-                NotValidExceptionResponse.builder()
-                        .timestamp(LocalDateTime.now())
-                        .status(HttpStatus.BAD_REQUEST.value())
-                        .title("Arguments Not Valid")
-                        .developerMessage(ex.getClass().getName())
-                        .err(errorList)
-                        .build(), HttpStatus.BAD_REQUEST
-        );
-    }*/
-
+    /**
+     * Validation error
+     * @param ex
+     * @param request
+     * @return
+     */
     @ExceptionHandler(MethodArgumentNotValidException.class)
-    public ResponseEntity<ErrorResponse> methodValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
-        log.warn("MethodArgumentNotValidException 발생!!! url:{}, trace:{}",request.getRequestURI(), ex.getStackTrace());
-        List<String> errorList = ex
-                .getBindingResult()
-                .getFieldErrors()
-                .stream()
-                .map(DefaultMessageSourceResolvable::getDefaultMessage)
-                .collect(Collectors.toList());
-        //ErrorResponse errorResponse = makeErrorResponse(e.getBindingResult());
-        //return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.BAD_REQUEST);
-        return new ResponseEntity<>(
-                ErrorResponse.builder()
-                        .timestamp(LocalDateTime.now())
-                        .status(HttpStatus.BAD_REQUEST.value())
-                        .title("Arguments Not Valid")
-                        .message(ex.getClass().getName())
-                        .errors(errorList)
-                        .build(), HttpStatus.BAD_REQUEST);
-    }
-/*
-
-    private ErrorResponse makeErrorResponse(BindingResult bindingResult) {
-        String code = "";
-        String description = "";
-        String detail = "";
-
-        //에러가 있다면
-        if (bindingResult.hasErrors()) {
-            //DTO에 설정한 meaasge값을 가져온다
-            detail = bindingResult.getFieldError().getDefaultMessage();
-
-            //DTO에 유효성체크를 걸어놓은 어노테이션명을 가져온다.
-            String bindResultCode = bindingResult.getFieldError().getCode();
-
-            switch (bindResultCode){
-                case "NotNull":
-                    //code = ErrorCode.NOT_NULL.getCode();
-                    //description = ErrorCode.NOT_NULL.getDescription();
-                    break;
-                case "Min":
-                    //code = ErrorCode.MIN_VALUE.getCode();
-                    //description = ErrorCode.MIN_VALUE.getDescription();
-                    break;
-            }
+    public ResponseEntity<ErrorResponse> methodValidException(HttpServletRequest request, MethodArgumentNotValidException ex) {
+        List<String> errorList = new ArrayList<>();
+        BindingResult bindingResult = ex.getBindingResult();
+        for (FieldError fieldError : bindingResult.getFieldErrors()) {
+            StringBuilder builder = new StringBuilder();
+            builder.append("[");
+            builder.append(fieldError.getField());
+            builder.append("](은)는 ");
+            builder.append(fieldError.getDefaultMessage());
+            builder.append(" 입력된 값: [");
+            builder.append(fieldError.getRejectedValue());
+            builder.append("]");
+            errorList.add(builder.toString());
         }
-        return new ErrorResponse(0, code, null);
+//        List<String> errorList = ex
+//                .getBindingResult()
+//                .getFieldErrors()
+//                .stream()
+//                .map(DefaultMessageSourceResolvable::getDefaultMessage)
+//                .collect(Collectors.toList());
+        ErrorResponse response = ErrorResponse.builder()
+                .timestamp(LocalDateTime.now())
+                .status(HttpStatus.BAD_REQUEST.value())
+                .title("Arguments Not Valid(Bad Request)")
+                .message("요청 데이터가 유효하지 않습니다.")
+                .errors(errorList)
+                .path(request.getRequestURI())
+                .build();
+        log.error("{}", response.toString());
+        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
     }
-*/
 
+    /**
+     * Data not found
+     * @param request
+     * @param ex
+     * @return
+     */
+    @ExceptionHandler({NoSuchElementException.class})
+    public ResponseEntity<ErrorResponse> exceptionHandler(HttpServletRequest request, final NoSuchElementException ex) {
+        List<String> errorList = new ArrayList<>(Collections.singletonList(ex.getMessage()));
+        ErrorResponse response = ErrorResponse.builder()
+                .timestamp(LocalDateTime.now())
+                .status(HttpStatus.NOT_FOUND.value())
+                .title("Data Not Found")
+                .message(ex.getMessage())
+                .path(request.getRequestURI())
+                .errors(errorList)
+                .build();
+        log.error("{}", response.toString());
+        return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
+    }
+    @ExceptionHandler({RuntimeException.class})
+    public ResponseEntity<ErrorResponse> exceptionHandler(HttpServletRequest request, final RuntimeException ex) {
+        List<String> errorList = new ArrayList<>(Collections.singletonList(ex.getMessage()));
+        ErrorResponse response = ErrorResponse.builder()
+                .timestamp(LocalDateTime.now())
+                .status(HttpStatus.EXPECTATION_FAILED.value())
+                .title("RuntimeException")
+                .message(ex.getMessage())
+                .path(request.getRequestURI())
+                .errors(errorList)
+                .build();
+        log.error("{}", response.toString());
+        return new ResponseEntity<>(response, HttpStatus.EXPECTATION_FAILED);
+    }
+    @ExceptionHandler({Exception.class})
+    public ResponseEntity<ErrorResponse> exceptionHandler(HttpServletRequest request, final Exception ex) {
+        List<String> errorList = new ArrayList<>(Collections.singletonList(ex.getMessage()));
+        ErrorResponse response = ErrorResponse.builder()
+                .timestamp(LocalDateTime.now())
+                .status(HttpStatus.EXPECTATION_FAILED.value())
+                .title("Exception")
+                .message(ex.getMessage())
+                .path(request.getRequestURI())
+                .errors(errorList)
+                .build();
+        log.error("{}", response.toString());
+        return new ResponseEntity<>(response, HttpStatus.EXPECTATION_FAILED);
+    }
 }

+ 2 - 0
src/main/java/com/its/api/webapp/config/WebConfig.java

@@ -10,6 +10,8 @@ public class WebConfig implements WebMvcConfigurer {
     @Override
     public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/**")
+                //.allowCredentials(true)
+                //.allowedOriginPatterns("*")
                 .allowedOrigins("*")                            //허용할 Origin(요청 url) : "*" 의 경우 모두 허용
                 .allowedMethods("GET", "POST", "PUT", "DELETE") //허용할 request http METHOD : POST, GET, DELETE, PUT
                 .maxAge(3600)                                   //브라우저 캐시 시간(단위: 초) : "3600" 이면 최소 1시간 안에는 서버로 재요청 되지 않음

+ 10 - 5
src/main/java/com/its/api/websocket/ItsWebSocketConfig.java

@@ -16,14 +16,19 @@ public class ItsWebSocketConfig implements WebSocketConfigurer {
     private final ItsWebSocketHandler itsWebsocketHandler;
 
     @Override
-    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
+    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
 
-        webSocketHandlerRegistry.addHandler(this.itsWebsocketHandler, "/ws/messages.do")
+        registry.addHandler(this.itsWebsocketHandler, "/ws/messages.do")
+                //.setAllowedOrigins("*")
                 .setAllowedOriginPatterns("*")
-                .withSockJS();  // sockjs
+                .withSockJS()
+                //.setSessionCookieNeeded(false)
+        ;  // sockjs
 
-       webSocketHandlerRegistry.addHandler(this.itsWebsocketHandler, "/ws/messages.do")
-                .setAllowedOriginPatterns("*"); // 그냥 websocket 지원
+        registry.addHandler(this.itsWebsocketHandler, "/ws/messages.do")
+                .setAllowedOriginPatterns("*")
+                //.setAllowedOrigins("*")
+        ; // 그냥 websocket 지원
     }
 
 }

+ 3 - 0
src/main/resources/application.yml

@@ -29,6 +29,9 @@ server:
       timeout: 300
 
 spring:
+  output:
+    ansi:
+      enabled: always
   profiles:
     active: dev
   main:

+ 4 - 0
src/main/resources/logback-spring.xmlxx → src/main/resources/logback-spring.xml

@@ -2,6 +2,10 @@
 <configuration scan="true" scanPeriod="60 seconds">
     <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>
 
+<!--    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />-->
+<!--    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />-->
+<!--    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />-->
+
     <property name="PROJECT_NAME"    value="its-op-server"/>
     <property name="ROOT_LOG_LEVEL"  value="INFO"/>
     <property name="LOG_CHARSET"     value="UTF-8" />