데이터베이스에 값을 입력하는 중 에러가 발생했다...
정확히는 SQL과 파라미터를 조합해 로그를 찍어주는 곳에서... 

처음 보는 에러네?
로그...
### Error updating database.  Cause: java.lang.IndexOutOfBoundsException: No group 2

에러를 발생한 값...
2018-10-14 20:15 [DEBUG] ******* field value : {bcrypt}$2a$10$Rq1GlJlTVLXL/9GQLohX6.YGkn/yAHa.ZSOLekODrY.wVjTDvE1Sy

비밀번호를 암호화 하게되면 $가 문자열에 포함되게 되는데 이 $가 replace 쪽에서 문제를 일으키는 것... 
이럴 땐 좀 복잡하지만 돌아가야 한다...

public class ReplaceTest {
    public static void main(String[] args) {
         String sql = "This is password : ?";
         HashMap<String, String> field = new HashMap<String, String>();
         field.put("passwd", "{bcrypt}$2a$10$2ZnW3nw1AVN1jyKpa3uZJO0EhJ71jXDyahxbHTmlBu5MTsLPN3no2");
         
         String regex = "\\?";
         Pattern pattern = Pattern.compile(regex);
         Matcher matcher = pattern.matcher(sql);
         sql = matcher.replaceFirst(matcher.quoteReplacement("'" + field.get("passwd") + "'"));
         System.out.println(sql);
    }
}
result : This is password : '{bcrypt}$2a$10$2ZnW3nw1AVN1jyKpa3uZJO0EhJ71jXDyahxbHTmlBu5MTsLPN3no2' 






'백엔드 > Java' 카테고리의 다른 글

[Java] java.lang.IndexOutOfBoundsException: No group 2  (0) 2018.10.14
회원가입을 진행하던 중 HTTP 403 에러가 발생하였다.

Spring Security 3.2  이후 버전에서는 적절한 CSRF 토큰을 포함시켜주지 않으면 에러를 발생하게끔 되어있다.

관련 로그
2018-10-14 18:10 [DEBUG] /user/register.do at position 1 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-10-14 18:10 [DEBUG] HttpSession returned null object for SPRING_SECURITY_CONTEXT
2018-10-14 18:10 [DEBUG] No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@4f72f029. A new one will be created.
2018-10-14 18:10 [DEBUG] /user/register.do at position 2 of 14 in additional filter chain; firing Filter: 'ConcurrentSessionFilter'
2018-10-14 18:10 [DEBUG] /user/register.do at position 3 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-10-14 18:10 [DEBUG] /user/register.do at position 4 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-10-14 18:10 [DEBUG] /user/register.do at position 5 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
2018-10-14 18:10 [DEBUG] Invalid CSRF token found for http://localhost:8080/jedu/user/register.do


CSRF 토큰을 (쉽게) 포함시키기 위해 선행되어야 하는 작업으론..
  1. spring security taglib 선언
  2. ajax를 사용하는가?

in jsp....
<%@ taglib  uri="http://www.springframework.org/security/tags"  prefix="sec" %>

위 처럼 jsp에 taglib를 선언한다.



ajax를 사용하지 않고 form을 submit 하는 방식이라면 아래처럼..

<form class="m-0 sky-form" name="regForm" method="post" enctype="multipart/form-data">
    <sec:csrfInput />
    .........
</form>

만약 ajax를 사용한다면 <head> 태그 아래에...

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<sec:csrfMetaTags />

CSRF 정보를 추가하는 방법이 각각 다르므로 유의해야 한다..

ajax 호출시에는 header 정보에 CSRF 정보를 넣어주어야 하는데 아래 코드와 같다.
var csrfParameter = $("meta[name='_csrf_parameter']").attr("content");
var csrfToken = $("meta[name='_csrf']").attr("content");
var csrfHeader = $("meta[name='_csrf_header']").attr("content");
var headers = {};
headers[csrfHeader] = csrfToken;

$.ajax({
    url: '<c:url value="/user/register.do" />',
    type: "POST",
    headers: headers,
    data: formData,
......
});



2018년 6월 30일 오전.. 축구하던 중... 무릎이 뒤틀리는걸 느끼고 119에 실려 갔다.. 


한번도 느껴본 적 없는 고통이라 예삿일이 아니라 생각되었고 결국 당일 MRI까지 촬영을 했다. 

(119를 통해 간 병원은 응급의학과 소견으로 타박상이 아닐까 말하지만 정확한 원인을 알아야 하기에 의뢰서 발급받아 2차 병원으로 이동함)


MRI를 촬영했지만 토요일이다보니 당일 판독이 불가능하여 월요일까지 기다린 후 1차 판독을 받아보니.... 

동그랗게 그린 부분이 전부다 피더라.. 무릎에 피가 고이니 움직이는게 제한되고 아프고 그런 것...

이건 주사기로 빼야됨. 그래야 그나마 움직일 수 있음.


동그라미 친 부분이 반월상 연골 부분인데 파열이다.. 

반대쪽(좌측)과 비교해보면 확연히 구분된다.


위 사진은 전방 십자인대인데... 아래쪽 무릎에서 나오는 검은색이 위쪽 무릎과 연결이 되어야 하는게 맞다.
근데 위쪽에서 떨어져 나간게 보인다... 고로 파열.... 

1차 판독시에도 십자인대가 제자리에 없네? 였다.... 


후방 십자인대는 다행이 잘 붙어 있다. 

저렇게 위아래 연결되어 있어야 하는건데 십자인대는 가출해버린 것... 


수요일 2차 판독 겸 대학병원으로 갔는데 아니나 다를까 수술 결정.

그런데 수술을 바로 하지 않고 대퇴사두근에 힘주는 연습을 한 후에 수술을 해야 한단다.
그 이유는 힘주는 걸 안하게 되면 재활 속도에 차이가 심해서 수술 전 재활을 먼저 하고 수술을 진행..

근데 십자인대를 다치니까 진짜 대퇴사두근에 힘이 안들어감 ㄷㄷ
아침 저녁으로 열심히 하니까 겨우 힘이 들어가긴 하는데 왼쪽 다리와 비교하면 차이가 심한 걸 알 수 있다.


어쨋든.. 최소 9개월은 운동 못함... 젠장


'정보 > 건강' 카테고리의 다른 글

전방십자인대 파열 및 반월상 연골 파열  (0) 2018.07.15
Spring - myBatis 환경에서 트랜잭션이 적용되지 않으면 아래 로그를 볼 수 있다.

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ad7d61e] was not registered for synchronization because synchronization is not active
Fetching JDBC Connection from DataSource
trace com.mchange.v2.resourcepool.BasicResourcePool@723b12e9 [managed: 20, unused: 19, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@6f25ab49)
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@5beadc25] will not be managed by Spring
==>  Preparing: UPDATE iot.user SET user_name = ?, nickname = ?, email = ?, is_admin = ?, update_date = NOW() WHERE seq = ?
==> Parameters: Test46(String), Test?46(String), 12@abc.com(String), 0(String), 346(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ad7d61e]
Returning JDBC Connection to DataSource


-- applicationContext-beans.xml
<!-- Annotation 기반의 Component Scan 필터(service package 만 검색) -->
<context:component-scan base-package="com.iot.pf">
      <context:include-filter type="regex" expression="\.*\.service\.*" />
</context:component-scan>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <!-- DB에 접속 하기 위해서 설정 -->
      <property name="dataSource" ref="dataSource" />   
      
      <!-- myBatis 기본 설정 -->
      <property name="configLocation" value="classpath:mybatis-configuration.xml" />
      
      <!-- query 적힌 xml 위치 -->
      <property name="mapperLocations" value="classpath:sql/SQL.*.xml" />
      <!-- 트랜잭션 관리를 위한 것 -->
      <property name="transactionFactory">
           <bean class="org.mybatis.spring.transaction.SpringManagedTransactionFactory" />
      </property>
</bean>

<!-- DAO(interface) 위치를 basePackage로.. -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      <property name="basePackage" value="com.iot.pf.dao" />
</bean>

<!-- 트랜잭션 관리를 위한 bean  -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
</bean>

-- servlet.xml

<context:component-scan base-package="com.iot.pf" use-default-filters="false" >
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />
</context:component-scan>

<!-- File Upload -->
      <property name="maxUploadSize" value="50000000" />
</bean>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/views/"/>
      <property name="suffix" value=".jsp"/>
</bean>

<mvc:resources mapping="/resources/**" location="/resources/" />

<mvc:annotation-driven />

<!-- transaction annotation -->
<tx:annotation-driven transaction-manager="transactionManager"/>

-- service file
@Service("userService")
@Transactional(rollbackFor = {Exception.class})
public class UserServiceImpl implements UserService{
 
}


트랜잭션이 적용되면 아래 로그를 볼 수 있다.
Creating new transaction with name [com.iot.pf.service.impl.UserServiceImpl.update]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',-com.iot.pf.exception.AnomalyException,-java.lang.Exception
trace com.mchange.v2.resourcepool.BasicResourcePool@63cfcf47 [managed: 20, unused: 19, excluded: 0] (e.g. com.mchange.v2.c3p0.impl.NewPooledConnection@3f24eec6)
Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759] for JDBC transaction
Switching JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759] to manual commit
Getting transaction for [com.iot.pf.service.impl.UserServiceImpl.update]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5c640a11]
JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759] will be managed by Spring
==>  Preparing: UPDATE iot.user SET user_name = ?, nickname = ?, email = ?, is_admin = ?, update_date = NOW() WHERE seq = ?
==> Parameters: Test46(String), Test46(String), 123@abc.com(String), 0(String), 346(Integer)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5c640a11]
Completing transaction for [com.iot.pf.service.impl.UserServiceImpl.update] after exception: com.iot.pf.exception.AnomalyException: You have an anomaly result value after [INSERT/UPDATE/DELETE] query!!!!
Applying rules to determine whether transaction should rollback on com.iot.pf.exception.AnomalyException: You have an anomaly result value after [INSERT/UPDATE/DELETE] query!!!!
Winning rollback rule is: RollbackRuleAttribute with pattern [com.iot.pf.exception.AnomalyException]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5c640a11]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5c640a11]
Initiating transaction rollback
Rolling back JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759]
Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@19668759] after transaction
Returning JDBC Connection to DataSource




[TMS] $ /bin/sh -xe /tmp/jenkins2697039887893472079.sh + /home/jyeory/app/shell/afterBuildPf.sh rm: cannot remove '/home/jyeory/app/tomcat-instances/tomcatPf/webapps/ROOT': Permission denied cp: failed to access '/home/jyeory/app/tomcat-instances/tomcatPf/webapps/ROOT.war': Permission denied Build step 'Execute shell' marked build as failure

Jenkins에서 빌드 후 스크립트를 실행 할 때 오류가 난다.

권한이 문제인데, 우선 Jenkins를 실행하는 사용자는 jenkins이고, 배포 디렉토리의 사용자는 jyeory로 권한이 없을만 하다.


이를 해결하기 위해 jenkins, jyeory 모두 dev라는 그룹으로 묶어주고.... 

배포 디렉토리의 그룹도 dev로 변경, 마지막으로 배포 디렉토리의 그룹 권한을 rwx(7)로 바꿔주어야 한다.


이후 jenkins를 재시작하면 오류가 발생하지 않는다.


java.lang.AbstractMethodError: Method com/mchange/v2/c3p0/impl/NewProxyPreparedStatement.isClosed()Z is abstract

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.2</version>
</dependency>

위 처럼 mybatis 3.4.6, mybatis-spring 버전을 1.3.2로 사용하고 테스트를 하니 위 에러가 나더라..


<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
    <groupId>com.mchange</groupId>
    <artifactId>c3p0</artifactId>
    <version>0.9.5.2</version>
</dependency>

c3p0 라이브러리 버전이 낮아서 그런거 이므로 최신 버전으로 바꾸어 사용하면 된다.


Maven 빌드 중 아래 오류가 발생함.

[DEBUG] incrementalBuildHelper#beforeRebuildExecution

[INFO] Compiling 47 source files to C:\dev\workspace-class\spring-mybatis-grid\target\classes

[DEBUG] incrementalBuildHelper#afterRebuildExecution

[INFO] /C:/[경로]/java/com/edu/test/NamingReflection.java: C:\dev\workspace-class\spring-mybatis-grid\src\main\java\com\edu\test\NamingReflection.java uses unchecked or unsafe operations.

[INFO] /C:/[경로]/java/com/edu/test/NamingReflection.java: Recompile with -Xlint:unchecked for details.

[INFO] -------------------------------------------------------------

[ERROR] COMPILATION ERROR :

[INFO] -------------------------------------------------------------

[ERROR] /C:/[경로]/java/com/edu/test/DepartmentsServiceTest.java:[12,17] package org.junit does not exist

[ERROR] /C:/[경로]/java/com/edu/test/DepartmentsServiceTest.java:[13,24] package org.junit.runner does not exist

[ERROR] /C:/[경로]/java/com/edu/test/DepartmentsServiceTest.java:[14,40] package org.springframework.test.context does not exist

[ERROR] /C:/[경로]/java/com/edu/test/DepartmentsServiceTest.java:[15,47] package org.springframework.test.context.junit4 does not exist

[ERROR] /C:/[경로]/java/com/edu/test/DepartmentsServiceTest.java:[20,2] cannot find symbol symbol: class RunWith

[ERROR] /C:/[경로]/java/com/edu/test/DepartmentsServiceTest.java:[21,2] cannot find symbol symbol: class ContextConfiguration


오류나는 클래스를 살펴보니 모두 TEST 케이스에서만 에러난다.

패키지를 못 읽어 오는 것이기에 pom.xml 을 수정해야 한다.

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency>

에서 scope 를 삭제한다. 아래처럼  

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency>


숫자 입력 시 콤마(,) 또는 %나 특정 기호를 붙여줘야 할 때가 있다.



$( object ).keyup(function(e){
      // 현재 입력값에서 공백 떼고, % 떼고 , if) 1 %5 > 15
      var oldValue = $(this).val().replace(/\s/g, '').replace(/\%/g, '');
      var rate;
      
      // back space
      if(e.which == 8){
           // if) 15 > 1
           rate = oldValue.substr(0, oldValue.length - 1);
      }
      else {
           rate = oldValue;
      }
      
      rate = (rate == '')         // if) 5 %에서 백스페이스 누른 경우 rate 값은 빈 string
                 ? ''             // 화면에 공백 보여주고
                 : rate + ' %';   // if) 15 %에서 백스페이스 누른 경우 rate 값은 1이므로 % 붙여준다.
      
      $(this).val(rate);
});

'프론트엔드 > 스크립트 일반' 카테고리의 다른 글

숫자 뒤 % 붙이기.  (1) 2017.11.30
숫자 외 몇몇 키 만 입력받기  (0) 2017.11.30
String to Date  (0) 2017.11.29
Object to XML  (0) 2013.11.07
자바스크립트 Array remove  (0) 2013.08.28
  1. 2018.09.30 01:09

    비밀댓글입니다

numbers, -, home, end, left arrow, right arrow, backspace 등 특정 키만 입력받기..



$( object ).keypress(function(e){
      var key = e.which;              // 누른 key code 
      if((key >= 48 && key <= 57) ||  // 숫자열 0 ~ 9 : 48 ~ 57    
           key == 45 ||               // -
           key == 8 ||                // BackSpace
           key == 46 ||               // Delete
           key == 37 ||               // 좌 화살표
           key == 39 ||               // 우 화살표
           key == 35 ||               // End 키
           key == 36 ||               // Home 키
           key == 9 ){                // Tab 키
           
      }else {
           return false;
      }      
});

'프론트엔드 > 스크립트 일반' 카테고리의 다른 글

숫자 뒤 % 붙이기.  (1) 2017.11.30
숫자 외 몇몇 키 만 입력받기  (0) 2017.11.30
String to Date  (0) 2017.11.29
Object to XML  (0) 2013.11.07
자바스크립트 Array remove  (0) 2013.08.28

자바스크립트에서 String을 Date로 바꾸는 코드는 크게 2가지가 있다.

1번

var src = '2018-11-29'; var values = src.split('-'); var date1 = new Date(values[0], Number(values[1])-1, values[2]); console.log( date1.toISOString() ); // 2018-11-28T15:00:00.000Z console.log( date1 ); // Sat Nov 29 2018 00:00:00 GMT+0900


2번
var src = '2018-11-29';
var date2 = new Date(Date.parse(src));
console.log( date2.toISOString() );         // 2018-11-29T00:00:00.000Z
console.log( date2 );                       // Thu Nov 29 2018 09:00:00 GMT+0900

위 두가지 모두 Date 객체로 변환되는데 얼핏 보면 두 값 모두 같을 것 같다.
하지만 밀리세컨드로 값을 표시하면?

date1.getTime();        // 1543417200000
date2.getTime();        // 1543449600000

값이 다르다.

1번의 경우 GMT 기준으로 변환(parse) 한다. 
그래서 GMT 기준으로 출력하게 되면 값이 제대로 나오는데 ISO표준으로 출력하게 되면 GMT를 무시한 값을 출력한다. 
그래서 출력값이 29일이 아닌 28일이 되어버린다. (GMT 9시간 빼버림)

2번의 경우 GMT 기준이 아닌 애초에 UTC (GMT + 0) 기준으로 변환 해버린다.
그래서 ISO표준으로 출력하게 되면 애초에 GMT 무시한 값이기 때문에 29일이라고 나온다.

date1과 date2의 차이는 32400000인데 이 값은 (60 * 60 * 9 * 1000) 와 같다.


국가간 시스템에서 GMT 계산하느냐 안하냐느냐는 큰 문제이므로 통일해서 사용한다.


'프론트엔드 > 스크립트 일반' 카테고리의 다른 글

숫자 뒤 % 붙이기.  (1) 2017.11.30
숫자 외 몇몇 키 만 입력받기  (0) 2017.11.30
String to Date  (0) 2017.11.29
Object to XML  (0) 2013.11.07
자바스크립트 Array remove  (0) 2013.08.28

+ Recent posts