Oracle 함수는 크게 단일행 함수와 복수행 함수로 구분할 수 있다.

 

단일행 함수 복수형 함수
하나의 행 당 하나의 결과 값을 반환 하는 함수 여러 개의 행 당 하나의 결과값을 반환 하는 함수
문자함수 COUNT
숫자함수 SUM
날짜함수 MIN / MAX
변환함수 AVG

Oracle에는 많은 함수가 존재한다. 함수는 Query가 쉬워지고 응용프로그램의 코딩을 줄여줄 수 있다

따라서 함수는 많이 알고 있으면 좋다.

 

가끔 쓰이는 몇가지 함수를 알아보도록 한다.

 

NVL2 (Column, Express1, Express2)

해당 컬럼이 NULL이면 express-1의 값을, NULL이 아니면 express-2의 값을 리턴해 줍니다. 

 

NULLIF (Express1, Express2)
Express-1과 express-2의 값을 비교하여 그 값이 같으면 NULL을 리턴 하고 다르면 express-1의 값을 리턴해 줍니다.

 

COALESCE(Express1, , , , ExpressN)
Express-1이 NULL이 아니면 express-1을 리턴하고, NULL이면 express-2 를, express-1과 express-2 모두 NULL이면 express-n을 리턴해 줍니다.

 

TRIM ( LEADING [문자열] FROM col1 ) ;

LEADING은 왼쪽 문자열을 절삭 시켜 줍니다.

TRIM ( TRAILING [문자열] FROM col1 ) ;

 TRAILING은 오른쪽 문자열을 절삭 시켜 줍니다. 

TRIM ( BOTH [문자열] FROM col1 ) ;

BOTH는 양쪽 문자열을 동시에 절삭 시켜 줍니다.

 

SELECT 그룹함수([DISTINCT]/all]),
{column [Alias],...}
FROM 테이블명
[WHERE Query 조건(들)]
[GROUP BY 컬럼1, 컬럼2, …n]
[HAVING Group-Conditiona]
[ORDER BY 컬럼1, 컬럼2, …..[ASC/DESC]];

GROUP BY : 결과값을 지정한 컬럼을 기준으로 그룹화
HAVING : GROUP BY에 의한 결과에 대한 조건 절
ORDER BY : 결과값을 분류(Sorting)할 때

 

'DB > Oracle' 카테고리의 다른 글

Index Rebuild  (0) 2020.10.05
자주쓰는 함수 정리 - 문자열 함수  (0) 2020.04.03
ORA-28001: the password has expired  (0) 2018.07.18
TNS/ORA-12631 : 이름 검색에 실패(Username retrieval failed)  (0) 2018.05.10
Oracle Clinent Download  (0) 2018.01.30

replace() 함수

  • 자바스크립트에서 특정문자 또는 특수문자를 제거할때 replace() 함수를 사용하는 경우 , #가 여러번 있는 문자열(주민번호,전화번호)을 단순히 replace('#','')로 하면, 처음 #기호만 삭제되고 나머지는 삭제되지 않습니다.
var testStr = "#1#2#3";
testStr.replace("#","");

//결과값 : 1#2#3



replace()함수와 정규식을 활용하여 Java의 replaceAll() 함수와 동일한 기능을 하도록 만들어 보겠습니다. 

var testStr = "#1#2#3";
testStr.replace(/\#/g,"");

//결과값 : 123

해당 코드를 이용하여 replaceAll() 함수를 생성하여 사용하도록 합니다.

 

 

추가내용

  • 자주쓰는 정규식
    • 특정문자 제거(#제거)   : str.replace(/\#/g,'');
    • 앞의 공백 제거           : str.replace(/^\s+/,'');
    • 뒤 공백 제거              : str.replace(/\s+$/,'');
    • 앞 공백 제거              : str.replace(/^\s+|\s+$/g,'');
    • 문자열 내의 공백 제거 : str.replace(/\s/g,'');
    • 줄바꿈 제거               : str.replace(/\n/g,'');
    • 엔터 제거                  : str.replace(/\r/g,'');
    • 0 제거                      : str.replace(/[^(1-9)]/gi,"");

XSS란?

XSS(cross-site scripting)는 웹페이지에 악의적인 스크립트 코드를 주입할 수 있는 취약점이다.

 

XSS(Cross Site Scripting) 방지를 위해 널리 쓰이는 훌륭한 lucy-xss-servlet-filter는 Servlet Filter 단에서 < 등의 특수 문자를 &lt; 등으로 변환해주며, 여러 가지 관련 설정을 편리하게 지정할 수 있어 정말 좋다.

그런데 그 처리가 form-data에 대해서만 적용되고 Request Raw Body로 넘어가는 JSON에 대해서는 처리해주지 않는다는 단점이 있다. 그래서 JSON을 주고 받는 API 서버의 경우에는 직접 처리를 해줘야 한다.

 

즉, Lucy는 RequestParameter관련한 지원만 해준다.

 

 

그래서 이를 보완하기 위해서 여러가지 방법이 있겠지만, 가장 많이 사용되는 방법인 Request를 Wrapping 하여 적용하도록 한다. (기존에 Lucy XSS Filter를 사용하고 있다는 가정하에 작성)

 

준비물 : 2개의 Java Class, web.xml, Lucy XSS Filter

 

# Lucy XSS Filter는 Maven Central Repository 에 배포되어 있다. pom.xml 에 아래와 같이 의존성을 선언한다.

1
2
3
4
5
<dependency>
    <groupId>com.navercorp.lucy</groupId>
    <artifactId>lucy-xss</artifactId>
    <version>X.X.X</version>
</dependency>
cs

 

 

RequestWrapper.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
 
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
 
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
 
import com.nhncorp.lucy.security.xss.XssFilter;
 
public class RequestWrapper extends HttpServletRequestWrapper {
    private byte[] b;
 
    public RequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        XssFilter filter = XssFilter.getInstance("lucy-xss-sax.xml");
        b = new String(filter.doFilter(getBody(request))).getBytes("UTF-8");
    }
 
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bis = new ByteArrayInputStream(b);
        return new ServletInputStreamImpl(bis);
    }
 
    class ServletInputStreamImpl extends ServletInputStream {
        private InputStream is;
 
        public ServletInputStreamImpl(InputStream bis) {
            is = bis;
        }
 
        public int read() throws IOException {
            return is.read();
        }
 
        public int read(byte[] b) throws IOException {
            return is.read(b);
        }
    }
 
    public static String getBody(HttpServletRequest request) throws IOException {
        String body = null;
       BufferedReader br= null;
       StringBuilder sb= new StringBuilder();
        try {
            InputStream inputStream = request.getInputStream();
            if (inputStream != null) {
               br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = br.read(charBuffer)) > 0) {
                   sb.append(charBuffer, 0, bytesRead);
                }
              
            } else {
               sb.append("");
            }
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (br!= null) {
                try {
                   br.close();
                } catch (IOException ex) {
                    throw ex;
                }
            }
        }
        body = sb.toString();
        return body;
    }
}
 
cs

 

실제 필터링 기능을 수행하는 Java class이다. 

주의할 부분은 해당 작업을 수행할 경우 한글이 깨져서 chain.doFilter(requestWrapper, response);가 수행될 때 Json 오류가 날 수 있다.

그러므로 br= new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); 항목에 인코딩 설정을 명시해서 해당 오류를 피해 가도록 한다.

 

 

 

RequestBodyXSSFIleter.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
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class RequestBodyXSSFIleter implements Filter {
    private List<String> extUrl;
 
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
       RequestWrapper reqWrapper = null;
        String path = ((HttpServletRequest) req).getServletPath();
 
        try {
            if (!extUrl.contains(path)) {
              
               reqWrapper = new RequestWrapper(request);
               chain.doFilter(reqWrapper , response);
            } else {
                chain.doFilter(request, response);
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String excludePattern = filterConfig.getInitParameter("extUrls");
       extUrl = Arrays.asList(excludePattern.split(","));
    }
 
    @Override
    public void destroy() {
    }
}
 
cs

 

requestBody에 XSS Filter를 적용할 경우 Multipart(일반적으로 파일 업로드) 일 때 파일이 손상되는 일이 발생한다.

이를 방지하기위해 파일을 송신하는 URL의 경우 web.xml의 init-param을 이용하여 필터링을 제외할 수 있다.

 

RequestBodyXSSFIleter의 init시 filterConfig에서 해당 파라미터에 접근하여 제외할 URL목록을 콤마(,)로 구분하여 작성 후 필터를 적용하지 않는 방법으로 우회할 수 있다.

 

 

web.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
    <!-- Xss Filter Start -->
    <filter>
        <filter-name>xssEscapeServletFilter</filter-name>
        <filter-class>com.navercorp.lucy.security.xss.servletfilter.XssEscapeServletFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>xssEscapeServletFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <filter>
        <filter-name>RequestBodyXSSFilter</filter-name>
        <filter-class>com.your.pkg.path.filter.RequestBodyXSSFIleter</filter-class>
        <init-param>
            <param-name>extUrls</param-name>
            <param-value>/linkUrl1,/linkUrl2,/linkUrl2</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>RequestBodyXSSFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- Xss Filter End -->
cs

 

메모리 설정의 경우, 각 컴퓨터의 메모리 용량에 따라 설정하여야한다. (1~2G : 256m, 2~3G, 512m, 4G~ : 1024m 권장)

  1. Xverify:none
    클래스 검사 생략. eclipse 실행 시간 단축

  2. XX:+UseParallelGC
    Parallel Collector를 사용. 병렬 가비지 컬렉션.

  3. XX:-UseConcMarkSweepGC
    병행 mark-sweepGC 기능을 수행하여 GUI 응답 속도 처리

  4. XX:PermSize=32M
    eclipse 클래스 로딩 기본 메모리

  5. XX:MaxPermSize=128M
    eclipse 클래스 로딩 최대 메모리

  6. Xms256m
    eclipse 실행시 잡는 최소 메모리

  7. Xmx256m
    eclipse 실행시 잡는 최대 메모리

서버 정보 노출 및 에러코드의 노출을 방지하기 위해 대부분의 사이트가 HTTP 403, 404 등 HTTP 에러 발생 시 별도의 에러 페이지로 리다이렉트 시키고 있다.

 

하지만 헤더정보를 통해 에러정보를 노출 시키고 있다. 

 

따라서 Error Page에서 Http Status를 강제로 고정시키는 처리가 필요하다. 

 

리다이렉트 되는 에러페이지에 <%response.setStatus(200);%> 입력 시 에러 페이지로 리다이렉트와 동시에 헤더 정보내 노출되는 에러코드 노출을 방지할 수 있다.



1
2
3
4
5
6
7
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<% response.setStatus(200); %>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
cs

 

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

 

 

톰켓 실행할때 해당 오류를 만날 수 있습니다. 

 

이유는 간단합니다. 라이브러리에 runtime 라이브러리가 추가되지 않아서 발생한 Exception 입니다.

 

 

 

 

 

 

 

관리자로 로그인 되어있는 상태를 기준으로 작성되었습니다.

1. 사용할 데이터베이스를 선택하기 위해서 현재 생성되어 있는 데이터베이스 목록을 확인합니다.

 mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| home_db            |

| mysql              |

| performance_schema |

| sntechdb           |

| test               |

+--------------------+

6 rows in set (0.00 sec)



2. 사용할 데이터 베이스를 지정합니다. 

 mysql> use home_db

Database changed


3. 사용자 생성 및 해당 데이터베이스르 사용할 수 있는 권한을 부여합니다.

mysql> GRANT ALL PRIVILEGES ON home_db.* TO home_user IDENTIFIED BY '1234';

Query OK, 0 rows affected (0.00 sec)


4. 권한 및 계정정보를 서버에 재적용합니다.


mysql> FLUSH PRIVILEGES;

Query OK, 0 rows affected (0.00 sec)




End. 생성된 계정으로 로그인하여 지정한 데이터베이스에 접속이 되는지 확인합니다.

'DB > MariaDB(MySql)' 카테고리의 다른 글

[MYSQL 5.6] ROOT 비밀번호 초기화  (0) 2019.01.24
mysql myisam을 innodb로 바꾸는 방법  (0) 2015.11.10

환경 : windows 7 / MySQL 5.6 에서 테스트 되었습니다. 


1. MySQL 서비스를 종료합니다.

2. 관리자 권한으로 Cmd를 실행합니다.

3. 다음의 명령어 입력 ( --skip-grant-tables 는 주석이 아닙니다.)

mysqld -P3306 --skip-grant-tables


4. 새로운 CMD 창을 관리자로 실행합니다. (관리자 패스워드 없이 루트권한으로 로그인 됩니다.)

mysql -P3306 mysql

5. 아래의 쿼리로 패스워드를 변경합니다.

update mysql.user set authentication_string=password('new_password') where user='root';


'DB > MariaDB(MySql)' 카테고리의 다른 글

[MySQL 5.6]사용자 생성 및 권한 추가  (0) 2019.01.24
mysql myisam을 innodb로 바꾸는 방법  (0) 2015.11.10

JSP include시 다른 include되는 파일에서 선언된 변수에 대해서, 참조하지 못해서, eclipse에서 에러로 처리되는 현상이 눈에 거슬린다.(매우!!)


해결방법은 다음과 같습니다.




Window → Preferences → Web → JSP Files → Validation → Expression Language → EL Syntax problem → [Ignore] 로 변경




'Tools > Eclipse' 카테고리의 다른 글

DBeaver Eclipse Plug-in 설정  (0) 2020.03.16
Eclipce 설정 (eclipce.ini)  (0) 2019.12.26
Ctrl + F 혹은 Ctrl +H 로 주석 찾기  (0) 2017.04.26
Eclipse Tomcat SSL 인증서 파일 위치  (0) 2016.12.21
Preferences 설정  (0) 2016.10.12

일반적으로 이미지 타입이 RGB가 아닌 CMYK인 경우 


ImageIO.read() 를 이용하여 읽을 경우  Unsupported Image Type 가 발생한다.


일반적으로 CMYK타입 이미지는  ImageIO 로 read 하기 불가능하다




ImageIO.read(file); 를 이용해서 Exception이 발생할 경우 컨버터를 이용하여 처리하는 방식을 이용하여 오류를 줄일 수 있다. 



converter_Lib.zip



converter_Lib.zip의 icc 파일은 Cmyk2RgbConverter와 동일한 경로에 위치하면 된다. 



< Cmyk2RgbConverter.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
public class Cmyk2RgbConverter {
 
    public static final int TYPE_RGB = 1;
    public static final int TYPE_CMYK = 2;
    public static final int TYPE_YCCK = 3;
 
    private static int colorTp = TYPE_RGB;
    private static boolean markerFlag = false;
 
 
 
    public static BufferedImage readImage(File file) throws IOException, ImageReadException {
        colorTp = TYPE_RGB;
        markerFlag = false;
 
        ImageInputStream stream = ImageIO.createImageInputStream(file);
        Iterator < itor_imgReader > iter = ImageIO.getitor_imgReaders(stream);
        while (iter.hasNext()) {
            itor_imgReader reader = iter.next();
            reader.setInput(stream);
 
            BufferedImage image;
 
            ICC_pf pf = null;
            try {
                image = reader.read(0);
                
                reader.reset();
            } catch (IIOException e) {
                colorTp = TYPE_CMYK;
                checkMarker(file);
                pf = Sanselan.getICCpf(file);
                Writablewr wr = (Writablewr) reader.readwr(0null);
 
                
                reader.reset();
 
                if (colorTp == TYPE_YCCK) {
                    convertYcck2Cmyk(wr);
                }
 
                if (markerFlag) {
                    convInvColors(wr);
                }
                image = convertCmykToRgb(wr, pf);
                image.flush();
            } finally {
                stream.close(); 
            }
 
            return image;
        }
 
        return null;
    }
 
    public static void checkMarker(File file) throws IOException, ImageReadException {
        JpegImageParser parser = new JpegImageParser();
        ByteSource byteSource = new ByteSourceFile(file);
        @SuppressWarnings("rawtypes")
        ArrayList segments = parser.readSegments(byteSource, new int[] {
            0xffee
        }, true);
        if (segments != null && segments.size() >= 1) {
            UnknownSegment app14Segment = (UnknownSegment) segments.get(0);
            byte[] data = app14Segment.bytes;
            if (data.length >= 12 && data[0== 'A' && data[1== 'd' && data[2== 'o' && data[3== 'b' && data[4== 'e') {
                markerFlag = true;
                int transform = app14Segment.bytes[11& 0xff;
                if (transform == 2)
                    colorTp = TYPE_YCCK;
            }
        }
    }
 
    public static void convertYcck2Cmyk(Writablewr wr) {
        int height = wr.getHeight();
        int width = wr.getWidth();
        int stride = width * 4;
        int[] rowData = new int[stride];
        for (int h = 0; h < height; h++) {
            wr.getPixels(0, h, width, 1, rowData);
 
            for (int x = 0; x < stride; x += 4) {
                int y = rowData[x];
                int cb = rowData[x + 1];
                int cr = rowData[x + 2];
 
                int c = (int)(y + 1.402 * cr - 178.956);
                int m = (int)(y - 0.34414 * cb - 0.71414 * cr + 135.95984);
                y = (int)(y + 1.772 * cb - 226.316);
 
                if (c < 0)
                    c = 0;
                else if (c > 255)
                    c = 255;
                if (m < 0)
                    m = 0;
                else if (m > 255)
                    m = 255;
                if (y < 0)
                    y = 0;
                else if (y > 255)
                    y = 255;
 
                rowData[x] = 255 - c;
                rowData[x + 1= 255 - m;
                rowData[x + 2= 255 - y;
            }
 
            wr.setPixels(0, h, width, 1, rowData);
        }
    }
 
    public static void convInvColors(Writablewr wr) {
        int height = wr.getHeight();
        int width = wr.getWidth();
        int stride = width * 4;
        int[] rowData = new int[stride];
        for (int h = 0; h < height; h++) {
            wr.getPixels(0, h, width, 1, rowData);
            for (int x = 0; x < stride; x++)
                rowData[x] = 255 - rowData[x];
            wr.setPixels(0, h, width, 1, rowData);
        }
    }
 
    public static BufferedImage convertCmykToRgb(wr cmykwr, ICC_pf cmykpf) throws IOException {
 
        if (cmykpf == null) {
            cmykpf = ICC_pf.getInstance(CMYKConverter.class.getResourceAsStream("ISOcoated_v2_300_eci.icc"));
        }
 
        ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykpf);
        BufferedImage rgbImage = new BufferedImage(cmykwr.getWidth(), cmykwr.getHeight(), BufferedImage.TYPE_INT_RGB);
        Writablewr rgbwr = rgbImage.getwr();
        ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace();
        ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);
        cmykToRgb.filter(cmykwr, rgbwr);
        return rgbImage;
    }
 
    public static void intToBigEndian(int value, byte[] array, int index) {
        array[index] = (byte)(value >> 24);
        array[index + 1= (byte)(value >> 16);
        array[index + 2= (byte)(value >> 8);
        array[index + 3= (byte)(value);
    }
 
}
 
cs


+ Recent posts