package com.lemon.lifecenter.common; import java.lang.reflect.Field; import java.sql.Statement; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.regex.Matcher; import javax.servlet.http.HttpServletRequest; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.session.ResultHandler; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.lemon.lifecenter.dto.PrivateLogDTO; import com.lemon.lifecenter.service.PrivateLogService; import ch.qos.logback.classic.Logger; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.sql.*; import cubrid.sql.*; //a import cubrid.jdbc.driver.*; /* @Intercepts(@Signature( type=Executor.class, method="query", args= {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})) */ @Intercepts({ @Signature(type = StatementHandler.class, method = "update", args = { Statement.class }), @Signature(type = StatementHandler.class, method = "query", args = { Statement.class, ResultHandler.class }) }) public class LifeCenterQueryLog implements Interceptor { private final Logger logger = (Logger) LoggerFactory.getLogger(this.getClass()); private Connection con; private Statement stmt; @Override public Object intercept(Invocation invocation) throws Throwable { String method = invocation.getMethod().getName(); StatementHandler handler = (StatementHandler) invocation.getTarget(); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder .getRequestAttributes()).getRequest(); String sql = bindSql(handler); // SQL 추출 String param = handler.getParameterHandler().getParameterObject()!=null ? handler.getParameterHandler().getParameterObject().toString() : ""; Object session = request.getSession().getAttribute( "sesId" ); String url = request.getRequestURI().toString(); // 환자관리, 진료관리, 의료진관리 if( url.contains( "/patient/" ) || url.contains( "/clinic/" ) || url.contains( "/staff/" ) ) { if( !url.contains( "/statistics/patient/" ) ) { if( session != null && !url.contains( "/mobile" ) ) { if( !param.contains( "com.lemon.lifecenter.dto.LoginDTO" ) ) { if( !sql.contains( "-- selectNowPathRoleCheckTotal" ) && !sql.contains( "-- selectNowPathRoleCheckData" ) && !sql.contains( "-- insertMenuAccessLog" ) && !sql.contains( "-- selectSideMenuList" ) && !sql.contains( "-- insertPrivateAccessLog" ) ) { //System.err.println("★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"); //System.err.println(sql); try { //application.properties 에서 값을 들고옴 String durl = PropertyUtil.getProperty("spring.datasource.url"); String user = PropertyUtil.getProperty("spring.datasource.username"); String passwd = PropertyUtil.getProperty("spring.datasource.password"); con = DriverManager.getConnection(durl, user, passwd); // System.out.println("DB연결 성공"); stmt = con.createStatement(); // System.out.println("Statement객체 생성 성공"); String sesName = LifeCenterSessionController.getSession( request, "sesName" ); String sesCenterName = LifeCenterSessionController.getSession( request, "sesCenterName" ); String logCenterName = !sesCenterName.equals( "" )? "["+sesCenterName+"] " : ""; String sesId = LifeCenterSessionController.getSession( request, "sesId" ); String insertQuery = "" + "INSERT " + " INTO private_access_log " + " ( id, accessor_detail, ip, create_date, full_url, processing_contents, processing_target ) " + "VALUES ( ?, ?, ?, NOW(), ?, ?, '')"; PreparedStatement stmt = con.prepareStatement( insertQuery ); stmt.setString(1, sesId ); stmt.setString(2, logCenterName + sesName + " (" + sesId + ")" ); stmt.setString(3, LifeCenterFunction.getRemoteAddr( request )); stmt.setString(4, LifeCenterFunction.getFullURL( request ) ); stmt.setString(5, sql); stmt.executeUpdate(); stmt.close(); con.close(); } catch (SQLException e) { System.out.println("DB연결 실패"); System.out.print("사유 : " + e.getMessage()); } //System.err.println("★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★"); } } } } } return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { } /** *
* bindSql * ** * @param boundSql * @param sql * @param param * @return * @throws NoSuchFieldException * @throws IllegalAccessException */ @SuppressWarnings("rawtypes") private String bindSql(StatementHandler handler) throws NoSuchFieldException, IllegalAccessException { BoundSql boundSql = handler.getBoundSql(); // 쿼리실행시 맵핑되는 파라미터를 구한다 Object param = handler.getParameterHandler().getParameterObject(); // 쿼리문을 가져온다(이 상태에서의 쿼리는 값이 들어갈 부분에 ?가 있다) String sql = boundSql.getSql(); // 바인딩 파라미터가 없으면 if (param == null) { sql = sql.replaceFirst("\\?", "''"); return sql; } // 해당 파라미터의 클래스가 Integer, Long, Float, Double 클래스일 경우 if (param instanceof Integer || param instanceof Long || param instanceof Float || param instanceof Double) { sql = sql.replaceFirst("\\?", param.toString()); } // 해당 파라미터의 클래스가 String인 경우 else if (param instanceof String) { sql = sql.replaceFirst("\\?", "'" + param + "'"); } // 해당 파라미터의 클래스가 Map인 경우 else if (param instanceof Map) { ListparamMapping = boundSql.getParameterMappings(); for (ParameterMapping mapping : paramMapping) { String propValue = mapping.getProperty(); Object value = ((Map) param).get(propValue); if (value == null) { continue; } if (value instanceof String) { // sql = sql.replaceFirst("\\?", "'" + value + "'"); sql = sql.replaceFirst("\\?", "'"+Matcher.quoteReplacement(value.toString())+"'"); } else { sql = sql.replaceFirst("\\?", value.toString()); } } } // 해당 파라미터의 클래스가 사용자 정의 클래스인 경우 else { List paramMapping = boundSql.getParameterMappings(); Class extends Object> paramClass = param.getClass(); for (ParameterMapping mapping : paramMapping) { String propValue = mapping.getProperty(); Field field = paramClass.getDeclaredField(propValue); field.setAccessible(true); Class> javaType = mapping.getJavaType(); if (String.class == javaType) { String str = field.get(param) == null ? "" : field.get(param).toString(); sql = sql.replaceFirst("\\?", "'"+Matcher.quoteReplacement(str)+"'"); } else { sql = sql.replaceFirst("\\?", field.get(param).toString()); } } } // return sql return sql; } }