브라우저별 CSS 선택자(selector) 지원 여부.


예전 자료라 최신 버전은 없지만 어차피 최신 버전은 거의다 지원을 하니 지원이 안되는 브라우저를


찾아 보는 것에 중점을 두자.


진짜 익스플로러는 진짜 나쁜놈이다.





PatternMeaningS5C8F3.6O11I9bI8I7I6
#idid로 지정된 요소 선택OOOOOOOO
.classclass로 지정된 요소 선택OOOOOOOO
EE 요소를 선택OOOOOOOO
E:link방문하지 않은 E를 선택OOOOOOOO
E:visited방문한 E를 선택OOOOOOOO
E:hover마우스가 올라가 있는 동안 E를 선택OOOOOOOO
E:active마우스 클릭 또는 키보드(enter)가 눌린 동안 E를 선택OOOOOOOX
E:focusfocus가 머물러 있는 동안 E를 선택OOOOOOXX
E:first-lineE 요소의 첫 번째 라인 선택OOOOOOOX
E:first-letterE 요소의 첫 번째 문자 선택OOOOOOOX
*모든 요소 선택OOOOOOOO
E[foo]‘foo’ 속성이 포함된 E를 선택OOOOOOOX
E[foo="bar"]‘foo’ 속성의 값이 ’bar’와 일치하는 E를 선택OOOOOOOX
E[foo~="bar"]‘foo’ 속성의 값에 ’bar’가 포함되는 E를 선택OOOOOOOX
E[foo|="en"]‘foo’ 속성의 값이 ’en’ 또는 ’en-’ 으로 시작되는  E를 선택OOOOOOOX
E:first-child첫 번째 자식 요소가 E라면 선택OOOOOOOX
E:lang(fr)HTML lang 속성의 값이 ’fr’로 지정된 E를 선택OOOOOOXX
E::beforeE 요소 전에 생성된 요소 선택OOOOOOXX
E::afterE 요소 후에 생성된 요소 선택OOOOOOXX
E>FE 요소의 자식인 F 요소 선택OOOOOOOX
E+FE 요소를 뒤의 F 요소 선택OOOOOOOX
E[foo^="bar"]‘foo’ 속성의 값이 ’bar’로 정확하게 시작하는 요소 선택OOOOOOOX
E[foo$="bar"]‘foo’ 속성의 값이 ’bar’로 정확하게 끝나는 요소 선택OOOOOOOX
E[foo*="bar"]‘foo’ 속성의 값에 ’bar’를 포함하는 요소 선택OOOOOOOX
E:root문서의 최상위 루트 요소 선택OOOOOXXX
E:nth-child(n)그 부모의 n번째 자식이 앞으로부터 지정된 순서와 일치하는 E 라면 선택OOOOOXXX
E:nth-last-child(n)n번째 자식이 뒤로부터 지정된 순서와 일치하는 요소가 E 라면 선택OOOOOXXX
E:nth-of-type(n)E 요소 중 앞으로부터 순서가 일치하는 n번째 E 요소 선택OOOOOXXX
E:nth-last-of-type(n)E 요소 중 끝으로부터 순서가 일치하는 n번째 E 요소 선택OOOOOXXX
E:last-childE 요소 중 마지막 자식이라면 E 선택OOOOOXXX
E:first-of-typeE 요소 중 첫번째 E 선택OOOOOXXX
E:last-of-typeE 요소 중 마지막 E 선택OOOOOXXX
E:only-childE 요소가 유일한 자식이면 선택OOOOOXXX
E:only-of-typeE 요소가 같은 타입이면 선택OOOOOXXX
E:empty텍스트 및 공백을 포함하여 빈 자식을 가진 E를 선택OOOOOXXX
E:targetE의 URI의 대상이 되면 선택OOOOOXXX
E:enabled활성화된 폼 컨트롤 E요소 선택OOOOOXXX
E:disabled비활성화된 폼 컨트롤 E요소 선택OOOOOXXX
E:checked선택된 폼 컨트롤(라디오버튼,체크박스)을 선택OOOOOXXX
E:not(s)s가 아닌 E 요소 선택OOOOOXXX
E~FE 요소가 앞에 존재하면 F를 선택OOOOOOOX


켄도 ui 라인차트의 bullet(라인 사이의 동그라미)을 없애는 방법 입니다.


라인을 그려줄때 동그란 마커 없이 깔끔하게 그려주고 싶을때 사용 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 $("#chart").kendoChart({
                title: {
                    text: "Gross domestic product growth \n /GDP annual %/"
                },
                legend: {
                    position: "bottom"
                },
                chartArea: {
                    background: ""
                },
                seriesDefaults: {
                    type: "line",
                    style: "smooth",
                   markers:{
                                  size:1
                                  }
                },
                series: [{
                    name"India",
                    data: [3.9077.9437.8489.2849.2639.8013.8908.2389.5526.855],
                  
                },{
                    name"World",
                    data: [1.9882.7333.9943.4644.0013.9391.333-2.2454.3392.727]
                },{
                    name"Russian Federation",
                    data: [4.7437.2957.1756.3768.1538.5355.247-7.8324.34.3]
                },{
                    name"Haiti",
                    data: [-0.2530.362-3.5191.7992.2523.3430.8432.877-5.4165.590]
                }],
                valueAxis: {
                    labels: {
                        format: "{0}%"
                    },
                    line: {
                        visible: false
                    },
                    axisCrossingValue: -10
                },
                categoryAxis: {
                    categories: [2002200320042005200620072008200920102011],
                    majorGridLines: {
                        visible: false
                    },
                    labels: {
                        rotation: "auto"
                    }
                },
                tooltip: {
                    visible: true,
                    format: "{0}%",
                    template: "#= series.name #: #= value #"
                }
            });
cs



이전과 같은 켄도 ui 라인차트 데모페이지의 첫번째 소스 입니다.


저기에서 


seriesDefaults 속성에


 markers:{
           size:1
       }


markers 라는 속성을 추가 하였고 사이즈는 1로 지정 하였습니다.


0으로 지정하면 마우스오버 되었을때 엄청 커다란 동그라미가 생기네요


시리즈 디폴트에 마커스 사이즈를 1로 지정해 놓으면 모든 라인에 bullet가 사라지게 됩니다.


혹은 특정 라인에만 bullet를 없애고 싶을땐




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
series: [{
                    name"India",
                    data: [3.9077.9437.8489.2849.2639.8013.8908.2389.5526.855],
                      markers:{
                              size:1
                           }
                },{
                    name"World",
                    data: [1.9882.7333.9943.4644.0013.9391.333-2.2454.3392.727],
                  markers:{
                           size:1
                         }
                },{
                    name"Russian Federation",
                    data: [4.7437.2957.1756.3768.1538.5355.247-7.8324.34.3]
                },{
                    name"Haiti",
                    data: [-0.2530.362-3.5191.7992.2523.3430.8432.877-5.4165.590]
                }],
cs



시리즈에 들어가는 속성에 마커스를 따로 지정해 주면 됩니다.


켄도 ui의 차트를 그릴때 색상을 지정하는 방법 입니다.


차트를 구현하다 보면 임의로 지정된 색상을 사용해야 하는 경우가 있습니다. 그럴 경우 간단하게 


사용 할 수 있는 방법입니다.


코드는 아래와 같습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 $("#chart").kendoChart({
                title: {
                    text: "Gross domestic product growth \n /GDP annual %/"
                },
                legend: {
                    position: "bottom"
                },
                chartArea: {
                    background: ""
                },
                seriesDefaults: {
                    type: "line",
                    style: "smooth"
                },
                series: [{
                    name"India",
                    data: [3.9077.9437.8489.2849.2639.8013.8908.2389.5526.855]
                },{
                    name"World",
                    data: [1.9882.7333.9943.4644.0013.9391.333-2.2454.3392.727]
                },{
                    name"Russian Federation",
                    data: [4.7437.2957.1756.3768.1538.5355.247-7.8324.34.3]
                },{
                    name"Haiti",
                    data: [-0.2530.362-3.5191.7992.2523.3430.8432.877-5.4165.590]
                }],
                seriesColors: [" #108D25","#48CFAD""#FC6E51",  "#FC6E51""#4FC0E8"
                                 "#009bd7""#26aadd""#4db9e3""#73c8e9""#99d7ef"],
                valueAxis: {
                    labels: {
                        format: "{0}%"
                    },
                    line: {
                        visible: false
                    },
                    axisCrossingValue: -10
                },
                categoryAxis: {
                    categories: [2002200320042005200620072008200920102011],
                    majorGridLines: {
                        visible: false
                    },
                    labels: {
                        rotation: "auto"
                    }
                },
                tooltip: {
                    visible: true,
                    format: "{0}%",
                    template: "#= series.name #: #= value #"
                }
            });
cs



켄도 ui의 라인차트를 그리는 데모페이지의 첫번째 소스에 


seriesColors: [" #108D25","#48CFAD""#FC6E51",  "#FC6E51""#4FC0E8"
                                 "#009bd7""#26aadd""#4db9e3""#73c8e9""#99d7ef"],


이 코드를 추가 하였습니다. seriesColors 라는 속성이 색상을 지정해 주는 속성인데


저 배열 안에 색상코드를 넣으면 차트가 저 순서대로 색상을 넣어주게 됩니다.



두번째 방법은


시리즈에 들어갈 데이터에 직접 색상을 지정해 주는 방법 입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
data: [{
            category: "변속A",
            value: data1Val,
            color: "#9de219"
        },{
            category: "변속C",
            value: data2Val,
            color: "#90cc38"
        },{
            category: "등속B1",
            value: data3Val,
            color: "#006634"
        },{
            category: "등속B2",
            value: data4Val,
            color: "#004d38"
        }]
cs



차트가 그려줄 데이터를 직접 만들어 넣어 줄떄 컬러속성을 함께 넣어 주면 지정된 색상으로 차트를 그려주게 됩니다.

켄도 Chart X축[valueAxis] 이름 원하는 곳에 위치하도록 하는 방법



켄도 ui의 차트를 사용할때 X축의 valueAxes 라벨 위치를 변경 하고 싶은 때가 있다.


물론 포지션이라는 명령어로 간단한 위치 지정은 할 수 있지만 UI를 구성하다보면 라벨의 위치를


정확히 원하는 장소에 위치 하게 하고 싶을때가 있다.


방법을 알아보자




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
 
$("#chart").kendoChart({
    title: {
        text: "Gross domestic product growth \n /GDP annual %/"
    },
    legend: {
        position: "bottom"
    },
    chartArea: {
        background: ""
    },
    seriesDefaults: {
        type: "line",
        style: "smooth"
    },
    series: [{
        name"India",
        data: [3.9077.9437.8489.2849.2639.8013.8908.2389.5526.855]
    },{
        name"World",
        data: [1.9882.7333.9943.4644.0013.9391.333-2.2454.3392.727]
    },{
        name"Russian Federation",
        data: [4.7437.2957.1756.3768.1538.5355.247-7.8324.34.3]
    },{
        name"Haiti",
        data: [-0.2530.362-3.5191.7992.2523.3430.8432.877-5.4165.590]
    }],
    valueAxis: {
        labels: {
            format: "{0}%"
        },
        title: {
            text: unit,
            margin: {
                bottom: 20,
                top:-35,
                right:-20
              },
              position:'top',
              rotation: 0
          },
        line: {
            visible: false
        },
        axisCrossingValue: -10
    },
    categoryAxis: {
        categories: [2002200320042005200620072008200920102011],
        majorGridLines: {
            visible: false
        },
        labels: {
            rotation: "auto"
        }
    },
    tooltip: {
        visible: true,
        format: "{0}%",
        template: "#= series.name #: #= value #"
    }
});
cs



위와 같이 코딩했을때 X축 라벨의 위치를 지정해 주는 곳은 ValueAxis 를 설정하는 곳에 있는


title: {
            text: unit,
            margin: {
                bottom: 20,
                top:-35,
                right:-20
              },
              position:'top',
              rotation: 0
          },



이 부분이다. 포지션으로 탑을 주고 그 상태에서


마진을 이용해 위아래 양옆의 위치를 지정해 줄 수 있다.


위와 같이 하면


켄도 차트의 X축 이름을 원하는 위치에 마음대로 지정 할 수 있게 된다.

켄도 그리드를 생성시에 들어가는 값이 null 일때 '--' 라든가 '값없음' 이라던가 하는 내용을 넣어야 할 때가 있다.


물론 DB에서 쿼리로 뽑아올때 조건을 주어 null 일 경우 대체문자를 사용 할 수 있지만 


뽑아온 데이터 리스트끼리 사칙연산을 해야 하는 경우 중간에 들어가있는 string 문자열이 문제가 될 수도 있다.


혹은 쿼리에 손을 대지 못하는 경우도 있을 수 있다.



방법은 간단하다. 이런 기능이 있는줄 모르기 때문에 못쓰는 거지 있는줄 안다면 쉽게 사용이 가능하다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 

var nullTypeString = '--';

 $("#grid").kendoGrid({
       dataSource: {
           type: "odata",
           transport: {
               read: "데이터 가져올곳"
           },
           pageSize: 20
       },
       height: 550,
       groupable: true,
       sortable: true,
       pageable: {
           refresh: true,
           pageSizes: true,
           buttonCount: 5
       },
       columns: [{
           field: "record_DATE",
           title: msgData.data('elecdata'), //날짜
           locked: true,
           lockable: false,
           width: 120,
           attributes: {
               style: "text-align: left;"
             }
       },{
           field: "tag_NAME",
           title: msgData.data('tagname'), //태그명
           locked: true,
           lockable: false,
           width: 120,
           attributes: {
               style: "text-align: left;"
             }
       }, {
           field: "sum_VAL",
           title: "Sum",
           locked: true,
           format:"{0:n2}",
           template:kendo.template("#if (sum_VAL != null) {# #=sum_VAL# #} else {# #="+nullTypeString+"# #}#"),
           width: 120,
           attributes: {
               style: "text-align: right;"
             }
       }, {
           field: "avg_VAL",
           title: "Avg",
           format:"{0:n2}",
           template:kendo.template("#if (avg_VAL != null) {# #=avg_VAL# #} else {# #="+nullTypeString+"# #}#"),
           locked: true,
           width: 120,
           attributes: {
               style: "text-align: right;"
             }
       },{
           field: "min_VAL",
           title:"Min",
           format:"{0:n2}",
           locked: true,
           width: 120,
           template:kendo.template("#if (min_VAL != null) {# #=min_VAL# #} else {# #="+nullTypeString+"# #}#"),
           attributes: {
               style: "text-align: right;"
             }
       },  {
           field: "max_VAL",
           title: "Max",
           format:"{0:n2}",
           template:kendo.template("#if (max_VAL != null) {# #=max_VAL# #} else {# #="+nullTypeString+"# #}#"),
           locked: true,
           width: 120,
           attributes: {
               style: "text-align: right;"
             }
       }]
   });
cs




위와 같이 코딩하면 된다. 중요한건


columns 의


template:kendo.template("#if (max_VAL != null) {# #=max_VAL# #} else {# #="+nullTypeString+"# #}#")


이 부분이다.



해당 컬럼의 들어오는 필드의 값이 null이 아닐경우 값을 나타내고 그것이 아니라면 nulltypeString 변수값을 넣는다는 설정이다.

제이쿼리에서 foreach문 사용하는 방법


1. 배열 사용


$.each() 함수를 사용하여 배열을 반복문 형태로 사용할 수가 있다.


ex)1


1
2
3
4
5
6
7
8
9
10
11
// 예제1
$.each([0,8,4,10], function(index, value) { 
      console.log(index + ':값 = ' + value); 
    });
 
//예제2
var arr = [0,8,4,10];
 
$.each(arr, function(index, value) { 
      console.log(index + ':값 = ' + value); 
    });
cs



예제 1번과 2번을 실행하면


콘솔창엔 다음과 같은 결과가 동일하게  나온다


1
2
3
4
0:값 = 0
1:값 = 8
2:값 = 4
3:값 = 10
cs





2. 맵 사용


맵형식을 가지고 있는 데이터를 사용할땐 key와 value의 쌍으로 사용한다.


ex)2


1
2
3
4
5
6
7
8
9
10
11
var map = { 
  'name''yamea'
  'age''99' 
}; 
$.each(map, function(key, value) { 
  console.log(key + ': ' + value); 
});
 
// 결과
name: yamea
age: 99
cs




3. json 형식 데이터 사용


조금 더 나아가서 우리가 흔하게 사용하는 여러개의 오브젝트들이 담긴 배열을 사용할땐 조금만 응용을 하면 된다.


ex)3


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var map1 = { 
          'name''yamea'
          'age''10' 
        };
var map2 = { 
          'name''yamea2'
          'age''20' 
        };
var map3 = { 
          'name''yamea3'
          'age''30' 
        };
var arr = [map1, map2, map3];
 
        $.each(map, function(key, value) { 
          console.log("이름 = "+ value.name); 
        });
        
        // 결과값
        
        이름 = yamea
        이름 = yamea2
        이름 = yamea3
cs


위와 같은 방식으로 사용을 할 수 있다.


아주 간단한 방법으로 긴 for문을 사용하지 않고도 간단하게 사용할 수 있는 방법이다.

 다른 테이블과 조인 걸고 삭제[delete] 하기


가끔씩 delete 구문 조건문에 다른 테이블에서 가져온 정보를 넣고 싶을때가 있다.


외래키가 적용이 되어있기 때문에 A라는 테이블의 로우를 삭제 하기 전에  B라는 테이블에 있는


A와 외래키 관계에 있는 정보를 먼저 삭제 한 후 A테이블의 데이터를 삭제 해야 하는 경우가 


그런 경우일 것이다.


다른 테이블과 조인하여 조건을 걸고 데이터를 삭제 하는 방법을 알아보자


1. 일단 삭제 하고자 하는 delete문을 만들어 보자



1
2
3
DELETE FROM
    테이블AA
 
cs



2. 삭제 하고자 하는 내용을 뽑아오는 selete문을 만들어 보자

1
2
3
4
5
6
7
8
9
10
SELECT
    aa.*
FROM
    테이블AA aa
INNER JOIN 
    테이블BB bb
ON
    bb.MENU_ID = aa.MENU_ID
WHERE 
    bb.MENU_ID= '조건'
cs


3. 1번과 2번을 합체!

1
2
3
4
5
6
7
8
9
10
DELTE FROM
    테이블AA
FROM 
    테이블AA aa
INNER JOIN
    테이블BB bb
ON 
    bb.MENU_ID = aa.MENU_ID
WHERE 
    bb.MENU_ID = '조건'
cs



from 이 두번 나와서 이상해 보이지만 저게 맞다.


이렇게 하면 delete문에 다른 테이블과 조인을 걸어서 만든 조건으로 삭제 할 수가 있게 된다.

흔하게 실수 할 수 있는 spring mybatis 에러

Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener



만약 당신이 전자정부 프레임워크를 사용하거나 spring 프레임워크 mybatis를 사용하고 있으며


typealias를 매핑형식으로 sql-map-config.xml에서 관리를 하는데 새로운 쿼리를 추가 하거나

 

typealias를 추가 했는데 서버를 구동시키자 저런 흉악한 에러메세지를 뿜어낸다면 그리고 분명히


경로를 제대로 복사 하였는데도 해당 VO클래스를 찾지 못한다는 에러 메세지가 나타난다면 1개만 더 확인 해 보자.


<typeAlias type="egovframework.easyplatform.common.tree.TreeDataVO" alias="treeDataVO" /> 


<typeAlias type="egovframework.easyplatform.commonvo.tag.vo.ExtendTagDicVO " alias="extendTagDicVO" />





위의 두 vo설정 코드에서 이름과 경로가 다르다는 것 외의 또하나의 차이점을 발견 하였는가?


저기서 둘중 하나의 코드때문에 vo를 찾지 못하는 에러가 나타나게 된다.


아직 모르겠다면 아래쪽의 코드를 잘 살펴 보도록 하자


그것은 경로가 들어가야 하는 부분에 포함되어 있는 공백 때문이다.

<typeAlias type="egovframework.easyplatform.commonvo.tag.vo.ExtendTagDicVO " alias="extendTagDicVO" />

<typeAlias type="egovframework.easyplatform.commonvo.tag.vo.ExtendTagDicVO" alias="extendTagDicVO" />


이렇게 보면 좀더 확인 하기 쉬울 것이다.


vo클래스의 경로를 넣어 주는 부분에 복사 붙여넣기를 하다보면 공백이 들어가는 경우가 종종 생긴다.


그럴때 분명히 경로는 맞는데 왜 클래스를 찾지 못하는지 모르겠다면 공백이 들어가있는지를 확인해 보도록 하자.






심각: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'alarmService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private egovframework.경로.GenericDao egovframework.easyplatform.common.alarm.service.impl.AlarmServiceImpl.genericDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'genericDao': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSession' defined in file [C:\eGovFrameDev-3.5.1-64bit\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp2\wtpwebapps\easy-common\WEB-INF\classes\egovframework\spring\context-sqlMap.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [egovframework/sqlmap/example/sql-map-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error registering typeAlias for 'extendTagDicVO'. Cause: java.lang.ClassNotFoundException: Cannot find class:  egovframework.경로.tag.vo.ExtendTagDicVO

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)

at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)

at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)

at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)

at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)

at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)

at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)

at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5068)

at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5584)

at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1572)

at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1562)

at java.util.concurrent.FutureTask.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private egovframework.경로.generic.GenericDao egovframework.easyplatform.common.alarm.service.impl.AlarmServiceImpl.genericDao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'genericDao': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSession' defined in file [C:\eGovFrameDev-3.5.1-64bit\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp2\wtpwebapps\easy-common\WEB-INF\classes\egovframework\spring\context-sqlMap.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [egovframework/sqlmap/example/sql-map-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error registering typeAlias for 'extendTagDicVO'. Cause: java.lang.ClassNotFoundException: Cannot find class:  egovframework경로.tag.vo.ExtendTagDicVO

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:522)

at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298)

... 22 more

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'genericDao': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSession' defined in file [C:\eGovFrameDev-3.5.1-64bit\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp2\wtpwebapps\easy-common\WEB-INF\classes\egovframework\spring\context-sqlMap.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [egovframework/sqlmap/example/sql-map-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error registering typeAlias for 'extendTagDicVO'. Cause: java.lang.ClassNotFoundException: Cannot find class:  egovframework경로.tag.vo.ExtendTagDicVO

at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:308)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)

at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1021)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:964)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:494)

... 24 more

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSession' defined in file [C:\eGovFrameDev-3.5.1-64bit\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp2\wtpwebapps\easy-common\WEB-INF\classes\egovframework\spring\context-sqlMap.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [egovframework/sqlmap/example/sql-map-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error registering typeAlias for 'extendTagDicVO'. Cause: java.lang.ClassNotFoundException: Cannot find class:  egovframework.경로.tag.vo.ExtendTagDicVO

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1554)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)

at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)

at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)

at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)

at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:450)

at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:424)

at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:549)

at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:178)

at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)

at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:305)

... 35 more

Caused by: org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [egovframework/sqlmap/example/sql-map-config.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error registering typeAlias for 'extendTagDicVO'. Cause: java.lang.ClassNotFoundException: Cannot find class:  egovframework경로.tag.vo.ExtendTagDicVO

at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:430)

at org.mybatis.spring.SqlSessionFactoryBean.afterPropertiesSet(SqlSessionFactoryBean.java:336)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)

... 47 more

Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error registering typeAlias for 'extendTagDicVO'. Cause: java.lang.ClassNotFoundException: Cannot find class:  egovframework.경로.tag.vo.ExtendTagDicVO

at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:106)

at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:89)

at org.mybatis.spring.SqlSessionFactoryBean.buildSqlSessionFactory(SqlSessionFactoryBean.java:424)

... 50 more

Caused by: org.apache.ibatis.builder.BuilderException: Error registering typeAlias for 'extendTagDicVO'. Cause: java.lang.ClassNotFoundException: Cannot find class:  egovframework.경로.tag.vo.ExtendTagDicVO

at org.apache.ibatis.builder.xml.XMLConfigBuilder.typeAliasesElement(XMLConfigBuilder.java:127)

at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:96)

... 52 more

Caused by: java.lang.ClassNotFoundException: Cannot find class:  egovframework.경로.tag.vo.ExtendTagDicVO

at org.apache.ibatis.io.ClassLoaderWrapper.classForName(ClassLoaderWrapper.java:188)

at org.apache.ibatis.io.ClassLoaderWrapper.classForName(ClassLoaderWrapper.java:87)

at org.apache.ibatis.io.Resources.classForName(Resources.java:254)

at org.apache.ibatis.builder.xml.XMLConfigBuilder.typeAliasesElement(XMLConfigBuilder.java:120)

... 53 more

스프링 관련해서 여기저기 코드를 끌어다 쓰다보면 프로퍼티를 추가 해 주어야 하는 경우가 있다.


기본적으로 전자정부 프레임워크의 기본 샘플 프로젝트에서는 메세지 프로퍼티가 있지만


그건 메세지 소스에 추가 되어 있고 (사실 나도 잘 모름)


그냥 노멀하게 프로퍼티를 추가 하고 싶다 라고 하면 생각보다 굉장히 간단하니 아래 코드를 참고 하여 배워보자




1. 프로퍼티 생성


일단 main 폴더 아래에 resources 폴더 밑에 프로퍼티를 넣어놓을 폴더를 생성하고 그 안에


프로퍼티를 넣는다.


간략히 resources 폴더 밑에 property 라는 폴더를 만들어 file.properties 라는 프로퍼티를 넣어 놓았다.


(이름이 똑같은 필요는 없으니 알아서 하시길)



2. 프로퍼티 추가 등록


전자정부프레임워크의 spring 폴더 밑에 


context-common.xml 이라는 파일이 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
 
    <context:component-scan base-package="egovframework">
       <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
 
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>classpath:/egovframework/message/message-common</value>
                <value>classpath:/egovframework/rte/fdl/idgnr/messages/idgnr</value>
                <value>classpath:/egovframework/rte/fdl/property/messages/properties</value>
            </list>
        </property>
        <property name="cacheSeconds">
            <value>60</value>
        </property>
    </bean>
    
    <bean id="leaveaTrace" class="egovframework.rte.fdl.cmmn.trace.LeaveaTrace">
        <property name="traceHandlerServices">
            <list>
                <ref bean="traceHandlerService" />
            </list>
        </property>
    </bean>
 
    <bean id="traceHandlerService" class="egovframework.rte.fdl.cmmn.trace.manager.DefaultTraceHandleManager">
        <property name="reqExpMatcher">
            <ref bean="antPathMater" />
        </property>
        <property name="patterns">
            <list>
                <value>*</value>
            </list>
        </property>
        <property name="handlers">
            <list>
                <ref bean="defaultTraceHandler" />
            </list>
        </property>
    </bean>
    
    <bean id="antPathMater" class="org.springframework.util.AntPathMatcher" />
    <bean id="defaultTraceHandler" class="egovframework.rte.fdl.cmmn.trace.handler.DefaultTraceHandler" />
</beans>
 

cs


기본적으로 이런 모양새 인데 


 

먼저 가장 위에 beans 설정하는 schemaLocation 부분에 


 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd


이 주소를 추가해주자


1
2
3
4
5
6
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
cs



이렇게 되도록



그리고 


<util:properties id="fileProperties" location="classpath:/프로티 경로" />


를 beans 안에 추가 해 주도록 한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
 
    <context:component-scan base-package="egovframework">
       <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
 
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>classpath:/egovframework/message/message-common</value>
                <value>classpath:/egovframework/rte/fdl/idgnr/messages/idgnr</value>
                <value>classpath:/egovframework/rte/fdl/property/messages/properties</value>
            </list>
        </property>
        <property name="cacheSeconds">
            <value>60</value>
        </property>
    </bean>
    
    <bean id="leaveaTrace" class="egovframework.rte.fdl.cmmn.trace.LeaveaTrace">
        <property name="traceHandlerServices">
            <list>
                <ref bean="traceHandlerService" />
            </list>
        </property>
    </bean>
 
    <bean id="traceHandlerService" class="egovframework.rte.fdl.cmmn.trace.manager.DefaultTraceHandleManager">
        <property name="reqExpMatcher">
            <ref bean="antPathMater" />
        </property>
        <property name="patterns">
            <list>
                <value>*</value>
            </list>
        </property>
        <property name="handlers">
            <list>
                <ref bean="defaultTraceHandler" />
            </list>
        </property>
    </bean>
    
    <bean id="antPathMater" class="org.springframework.util.AntPathMatcher" />
    <bean id="defaultTraceHandler" class="egovframework.rte.fdl.cmmn.trace.handler.DefaultTraceHandler" />
     
 
    <util:properties id="fileProperties" location="classpath:/property/file.properties" />
</beans>
 
cs



이렇게 추가를 하면 된다.



3. JAVA에서 사용 하기.



사용할 클래스에 


@Resource(name = "fileProperties")

private Properties fileProperties;


이런 코드를 추가 하여 준다. 어노테이션을 사용 하여 빈즈에서 끌어다 쓰는 것 같은데


저 위에 추가한 부분 id 를 이름으로 가져 오는 듯 하다.



그리고 메소드 내부에서 사용 할땐 아래 코드를 추가 하여 사용하고


String uploadPath = fileProperties.getProperty("가져올 데이터 이름");


간략히 코드를 구현하자면 아래와 같은 코드로 사용 하면 된다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
@Service("commonFileService")
public class CommonFileServiceImpl implements CommonFileService {
    // 이렇게 어노테이션을 이용하여 불러오도록 준비하고
    @Resource(name = "fileProperties")
    private Properties fileProperties;
 
    @Override
    public 반환 fileUpload(MultipartHttpServletRequest mRequest) {
        // 저장되는 파일 리스트
        List<String> fileNameArray = new ArrayList<String>();
        
        // 이렇게 사용 한다.
        String uploadPath = fileProperties.getProperty("file.image.winPath");
 
 
        return 반환;
    }
    
 
}
 
cs



웹개발을 하다보면 많은 페이지마다 반복되어야 하는 것들이 있다


예를들어 페이지를 이동할때마다 권한 검사를 한다던가 로그를 기록해야 한다던가 하는 것들


또한 URL을 요청해 컨트롤러가 구동되기 전 혹은 구동된 후에 실행시키고 싶은 것들도 있다


그런 인터셉터 기능을 설정하는 방법을 알아 보자



1. dispatcher-servlet.xml 설정


1
2
3
4
5
6
7
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="localeChangeInterceptor" />
            </list>
        </property>
    </bean>
cs


이렇게 생겨먹은 부분이 있는데 이 List 사이에

<ref bean="localeChangeInterceptor" /> 얘는 건들이지 말고 그 밑에

<ref bean="id값" />을 넣어 준다


그리고 아래와 같은 코드를 추가 시켜 준다


1
2
3
4
5
6
7
8
<bean id="위에 추가한 id값" class="인터셉터 기능을 수행할 패키지경로.클래스명">
          <!-- 인증 체크가 필요 없는 URL 리스트  -->
      <property name="urls">
       <list>
            제외시킬 url 목록
       </list>
      </property>
  </bean
cs



다음은 실행시킬 java 클래스를 만든다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 
package 패키지 경로;
 
import java.util.List;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
/**
* @패키지명 : 블로그용
* @파일명 : PlatformInterceptor.java
* @작성일 : 2016. 5. 23.
* @작성자 : "In Chee su"
* @설명 : 인터셉트
*/
public class 클래스명 extends HandlerInterceptorAdapter {
     
//  인증 체크가 필요 없는 URL 리스트  
 
List<String> urls;
 
 public void setUrls(List urls) {
  this.urls = urls;
 }
 
 
/* (non-Javadoc)
 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
 */
@Override
 public boolean preHandle(HttpServletRequest request,
   HttpServletResponse response, Object handler) throws Exception {
   // 기능을 수행하고 Controller를 실행 하려면
 
   // return true;
 
  
 
   // 특정 체크에서 일치하지 않는다면
 
   // response.sendRedirect("특정 에러 페이지로 보낸다");
 
   // return false;
 
    
    // 인증 체크가 필요 없는 URL 체크
 
          for(int i=0; i < urls.size(); i++){
         
                if (request.getRequestURI().matches(urls.get(i))) {
                System.out.println("== 인증 체크가 필요 없는 URL ============================");
                System.out.println("== URL : "+ urls.get(i) +" ============================");
                System.out.println("== return true ============================");
                System.out.println("== 인터셉터 종료 ============================");
                return true;
               }
         
         
               // 첫페이지가 로그인 페이지일 경우
             
               // 첫페이지 jsession때문에 request.getRequestURI().indexOf("/login/login.do") != -1 사용
             
               if(request.getRequestURI().indexOf(urls.get(i)) != -1){
             
                 return true;
         
           }
 
  
  }
 
 
// 세션이 있는지 체크
 
// 세션에 로그인한 정보가 있는지 체크
 
 
return true;
 }
 
 
}
 
 
cs



이렇게 만들면 된다.

+ Recent posts