Spring Boot Elapsed Time 


Spring Boot에서 Elapsed Time (API 처리 시간)을 Json으로 포함하여 리턴하고 싶다.


Result 예시 

{
    "data": null,
    "success": true,
    "elapsedTime": 304
}


이를 위해서 Aspect를 사용한다.


import java.util.Map; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /* * Body의 ElapsedTime을 나타내기 위한 Aspect */ @Aspect @Component public class ElapsedTimeAspect { @Pointcut("within(io.xxxxxx.yyyyy.controller.*)") private void pointcutMethod() { } @Around("pointcutMethod()") public Object elapsedTime(ProceedingJoinPoint joinPoint) throws Throwable { Long startTime = System.nanoTime(); Object object = joinPoint.proceed(); if(object instanceof Map){ Long endTime = System.nanoTime(); Map

resultMap = (Map) object; resultMap.put("elapsedTime", (endTime - startTime)/1000000); return resultMap; } return object; } }

Syntax Highlighter로 위의 코드들이 표현이 되지 않는 경우가 있어서 사진도 추가해 놓았다.




위의 예시를 사용하기 위해서는 Controller에서 Map<String, Object>로 리턴해야 한다. 


먼저 joinPoint.proceed를 실행하기 전에 startTime을 작성하고 joinPoint.proceed를 진행한 후에 elapsedTime을 계산하여 resultMap에 추가한다.


이렇게 Json ResponseBody에 ElapsedTime을 넣어주는 방법 외에 Header을 사용하여 그 안에 elapsed-time을 넣어주는 방법도 있다.

'프로그래밍 > JAVA 프로그래밍' 카테고리의 다른 글

[JAVA] Spring Boot Swagger Header 설정  (0) 2018.03.08
[JAVA] Spring Boot Swagger 설정  (0) 2018.02.26

Spring Boot 전체 API Header 설정


Swagger에서 Access Token과 같이 특정 Header을 일괄적으로 적용하기 위해서는 다음과 같이 작성한다.


물론, 각 API에 Header 정보를 추가해도 상관없다.

@EnableSwagger2
public class SwaggerConfig {

	@Bean
	public Docket api() {
		
		//Authentication header 처리를 위해 사용
		List global = new ArrayList();
		global.add(new ParameterBuilder().name("Authorization").
								  description("Access Token").parameterType("header").
								  required(false).modelRef(new ModelRef("string")).build());
		
		return new Docket(DocumentationType.SWAGGER_2)
				.globalOperationParameters(global)
				.select()
				.apis(RequestHandlerSelectors.any()) //현재 RequestMapping으로 할당된 모든 URL 리스트를 추출
				.paths(PathSelectors.ant("/**")).build(); //그 중에 /**인 URL들만 필터링
	}

}


Syntax Highlighter이 <> 을 태그로 인식해서 이상하게 나오는 부분이 있으므로 사진으로 다시 올린다.


'프로그래밍 > JAVA 프로그래밍' 카테고리의 다른 글

[Java] Spring Boot Elapsed TIme 적용  (0) 2018.03.09
[JAVA] Spring Boot Swagger 설정  (0) 2018.02.26

    Spring Boot Swagger 설정 방법


Spring Boot에서는 설정 하나로 Swagger를 사용 가능함



POM 추가
	
		
		
			io.springfox
			springfox-swagger2
			2.7.0
		

		
			io.springfox
			springfox-swagger-ui
			2.7.0
		
		
		
		
		
		    io.swagger
		    swagger-annotations
		    1.5.17
		

SwaggerConfig 클래스 설정

@Configuration
@EnableSwagger2
public class SwaggerConfig {

	@Bean
	public Docket api() {	
		return new Docket(DocumentationType.SWAGGER_2)
				.globalOperationParameters(global)
				.select()
				.apis(RequestHandlerSelectors.any()) //현재 RequestMapping으로 할당된 모든 URL 리스트를 추출
				.paths(PathSelectors.ant("/hello/**")).build(); //그 중에 /hello/**인 URL들만 필터링
	}

}

만일 API가 보이기 원치 않는 Controller에는 @ApiIgnore을 작성하면 Swagger에 보이지 않게 됨

@ApiIgnore
@RestController
@RestControllerAdvice(basePackages="io.hello")
public class GlobalExceptionHandler {
...
}

결과 화면 (localhost:8080/swagger-ui.html)



  만일 def __init__(self)을 쓰지 않는다면?

  • 다른 객체를 만들어도 전역변수인 self가 초기화가 되지 않아서 새로운 객체에도 값이 중복됨

  • 따라서 def __init__(self)을 꼭 사용하여야 함


def __init__(self)란?

  • 클래스의 인스턴스가 만들어진 직후 호출되는 초기화 함수


#초기화함수가 없다!

class CRbot_init: 
 ItBuf=[]
 def add(self, szIBuf):
  self.ItBuf.append(szIBuf)

 def prt_dis(self):
  print(self.ItBuf)

if __name__=='__main__':
 ObjRA = CRbot_init() #ObjRA 객체를 생성
 ObjRA.add('Morning')
 ObjRA.prt_dis()

 ObjRB = CRbot_init()  # ObjRB 객체를 생성
 ObjRB.add('After')
 ObjRB.prt_dis()


결과 화면

- ObjRB에 'Morning'이 추가적으로 보임! 값이 중복됨




이를 해결하기 위해서는? 


class CRbot_init:
 def __init__(self): #클래스의 인스턴스가 만들어진 직후 호출되는 초기화 함수이므로, 이를 추가함
  self.ItBuf=[]

 def add(self, szIBuf):
  self.ItBuf.append(szIBuf)

 def prt_dis(self):
  print(self.ItBuf)

if __name__=='__main__':
 ObjRA = CRbot_init()
 ObjRA.add('Morning')
 ObjRA.prt_dis()

 ObjRB = CRbot_init()
 ObjRB.add('After')
 ObjRB.prt_dis()


결과 화면

- 초기화가 되어 ObjRB에 'Morning'이 추가적으로 보이지 않음



[JAVA][ERROR] java.lang.NoSuchFieldError: _param_


문제 상황


로컬 환경에서 서버를 가동시키면 에러가 발생하지 않았다.

하지만 WAR 파일을 만들어 개발 서버에 배포를 하고 만들어진 API를 호출하니 다음과 같은 에러 메시지가 발생했다.


18:34:23,690 ERROR [org.springframework.boot.web.support.ErrorPageFilter] (ajp-/10.0.10.128:8109-4) Forwarding to error page from request [/safety/1.0/cases] due to exception [_param_]: java.lang.NoSuchFieldError: _param_
        at org.mariadb.jdbc.MariaDbServerPreparedStatement.(MariaDbServerPreparedStatement.java:97) [mariadb-java-client-1.5.7.jar:]
        at org.mariadb.jdbc.MariaDbConnection.internalPrepareStatement(MariaDbConnection.java:423) [mariadb-java-client-1.5.7.jar:]
        at org.mariadb.jdbc.MariaDbConnection.prepareStatement(MariaDbConnection.java:262) [mariadb-java-client-1.5.7.jar:]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_131]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_131]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_131]
        at java.lang.reflect.Method.invoke(Method.java:498) [rt.jar:1.8.0_131]
        at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) [tomcat-jdbc-8.5.11.jar:]
        at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:108) [tomcat-jdbc-8.5.11.jar:]
        at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:81) [tomcat-jdbc-8.5.11.jar:]
        at com.sun.proxy.$Proxy120.prepareStatement(Unknown Source)
        at scouter.jdbc.DetectConnection.prepareStatement(DetectConnection.java:181) [scouter.agent.jar:]
        at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:87) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:88) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:59) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:85) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148) [mybatis-3.4.4.jar:3.4.4]
        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141) [mybatis-3.4.4.jar:3.4.4]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_131]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_131]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_131]
        at java.lang.reflect.Method.invoke(Method.java:498) [rt.jar:1.8.0_131]
        at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433) [mybatis-spring-1.3.1.jar:1.3.1]
        at com.sun.proxy.$Proxy94.selectList(Unknown Source)
        at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:230) [mybatis-spring-1.3.1.jar:1.3.1] 
        at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:137) [mybatis-3.4.4.jar:3.4.4]


해결책


이는 MariaDB JAVA Client 버전 문제였다.

mariadb-java-client-1.5.7.jar -> mariadb-java-client-1.6.1.jar 로 변경하여 해결했다.


즉, POM 파일을 업데이트하면 된다.




    org.mariadb.jdbc
    mariadb-java-client
    1.6.1
 



+ Recent posts