'Java'에 해당되는 글 6건

  1. 2015.09.18 Static Import 에 대해
  2. 2015.04.29 captcha를 만들어보자
  3. 2015.04.28 java.security.InvalidKeyException: Illegal key size 오류
  4. 2015.04.21 문자열 패턴 분석 정규식
  5. 2015.04.20 JAVA MessageDigest 클래스
  6. 2015.03.12 에러 콘트롤러를 만들어 로그를 찍어보자

Static Import 에 대해

Java 2015.09.18 11:16

전자정부표준프레임웍을 점점 많은 곳에서 사용하는 것같아서 사용해보려고 설치를 했다. 근데... 내가 현재 사용하는 환경과 좀 다르다... 그래서 구조와 셋팅을 보려고 찾아보니 모르던 코드를 발견했다. 그것은 import static ... 이다.

궁금해서 검색을 해보니 자바 1.5에서 추가된 기능이란다. 난 1.6부터 시작했는데... 왜 몰랐지....


특징은 이렇다. 다른 클래스의 맴버 변수나 맴버 메서드를 경로를 생략하고 사용할 수 있다. Static Import 로 선언하기 위해서는 static으로 정의된 맴버여야한다. 예를 들어

import static java.lang.Math.PI;


이렇게 선언했다고 하자. 위에서 보통은 static 빼고 맨 끝에 PI 도 없을 것이다. 일반적인 import문을 정의하면 아래와같이 사용할 것이다.

double r = Math.cos(Math.PI * theta);


여기서 코드를 더 줄일 수 있게 해주는 것이 Static Import 이다. 사용할 경우에 아래와 같이 정의할 수 있다.

double r = cos(PI * theta);


코드가 좀 더 눈에 잘 들어오기는 하는데 뭔가 맴버로 착각할 듯하다. 실무에서는 클래스 이름이 긴 경우도 있으니 그럴 때 사용하면 좋을 듯하다. 하지만 남용하면 시간이 지나 소스가 가물가물 할 때 다시 열어보면 소스를 파악하기 힘들 것같다. 아니면 다른 사람이 남용한 소스를 분석하게 되면 스트레스가 쌓일 것같다. 분석에 어려움이 있으니 한 클래스에 1~2개 정도만 사용하는게 좋을 것이다.



찾아보다 보니 좋은 정보가 있다. 보통 이클립스를 사용하다보면 Ctrl + Shift + O 단축키를 많이 사용하게 될 것이다.

Static Import 를 사용할 때 모든 맴버를 사용할 경우 간단하게 다음과 같이 선언하면 된다.

import static java.lang.Math.*;


그런데 단축키를 누르면 이게 사라지고 각각의 멤버 이름으로 바뀌게 된다. 예를 들어

package staticTest;


public class StaticClass {

public static int cnt;

public static String name;

public static double point;


}


StaticClass 클래스가 있다. 이걸 import해서 코드를 작성하면

package staticTest;


import static staticTest.StaticClass.*;


public class TestMain {


public static void main(String[] args) {

// TODO Auto-generated method stub

int reCnt = cnt;

String reName = name;

double rePoint = point;

}


}


이렇게 된다. 근데 여기서 Ctrl + Shift + O 단축키를 누르면 아래처럼 된다.

package staticTest;


import static staticTest.StaticClass.cnt;

import static staticTest.StaticClass.name;

import static staticTest.StaticClass.point;


public class TestMain {


public static void main(String[] args) {

// TODO Auto-generated method stub

int reCnt = cnt;

String reName = name;

double rePoint = point;

}


}


import가 1개에서 3개로 바뀌었다. 이게 종종 거슬릴 수도 있을 것이다. 그럼 이클립스에서 설정을 바꿔서 한줄로 나오게 해보자.



Java EE의 경우에는 Java Code Style > Organize imports에 있다. Number of static imports nedded for .* 를 수정하면 된다. 기본값은 99인데 2로 하면 2개 이상인 경우에 *으로 바꿔준다. 


Static Import 는 적당히 사용하면 아주 유용한 코드가 될 것같다.



참고

http://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html

http://stylekai.tistory.com/308

http://whiteship.tistory.com/1416

Trackback 0 : Comment 0

captcha를 만들어보자

Java 2015.04.29 16:13

captcha를 공부해보려고 여기저기 기웃거리다가 simple captcha로 한번 테스트 페이지를 만들어보려고 작업했다. 근데 문제가 텍스트는 아주 잘되는데 오디오는 방법을 잘 모르겠다. 그래서 좀 더 여기저기 기웃거리다 텍스트로된 것을 직접 만든 소스를 발견했다. 소스를 보니 생각보다 간단하게 작성이 됬다. 그래서 가져와서 조금 수정해보았다.


출처: http://zetcode.com/tutorials/jeetutorials/captcha/


import java.awt.Color;

import java.awt.Font;

import java.awt.GradientPaint;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.image.BufferedImage;

import java.io.IOException;

import java.io.OutputStream;

import java.util.Random;


import javax.imageio.ImageIO;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public class Captcha {

public static void makeTextImage(HttpServletRequest request, 

HttpServletResponse response) 

throws ServletException, IOException {

int width = 150;

int height = 50;

BufferedImage bufferedImage = new BufferedImage(width, height, 

BufferedImage.TYPE_INT_RGB);

Graphics2D g2d = bufferedImage.createGraphics();

Font font = new Font("Georgia", Font.BOLD, 18);

g2d.setFont(font);

RenderingHints rh = new RenderingHints(

RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

rh.put(RenderingHints.KEY_RENDERING, 

RenderingHints.VALUE_RENDER_QUALITY);

g2d.setRenderingHints(rh);

GradientPaint gp = new GradientPaint(0, 0, 

Color.green, 0, height/2, Color.black, true);

g2d.setPaint(gp);

g2d.fillRect(0, 0, width, height);

g2d.setColor(new Color(255, 153, 0));

char[] data = generateKeyRandomText();

String captcha = String.copyValueOf(data);

request.getSession().setAttribute("captcha", captcha );

int x = 0; 

int y = 0;

Random r = new Random();

for (int i=0; i<data.length; i++) {

x += 10 + (Math.abs(r.nextInt()) % 15);

y = 20 + Math.abs(r.nextInt()) % 20;

g2d.drawChars(data, i, 1, x, y);

}

g2d.dispose();

response.setContentType("image/png");

OutputStream os = response.getOutputStream();

ImageIO.write(bufferedImage, "png", os);

os.close();

}

private static char[] generateKeyText(){

char data[][] = {

{ 'z', 'e', 't', 'c', 'o', 'd', 'e' },

{ 'l', 'i', 'n', 'u', 'x' },

{ 'f', 'r', 'e', 'e', 'b', 's', 'd' },

{ 'u', 'b', 'u', 'n', 't', 'u' },

{ 'j', 'e', 'e' }

};

Random r = new Random();

int index = Math.abs(r.nextInt()) % 5;

return data[index];

}

private static char[] generateKeyRandomText(){

char data[] = {0, 0, 0, 0, 0, 0};

char alphaCnt = ('Z'-'A'+1);

char numCnt = ('9'-'0'+1);

char totalCnt =  (char)((alphaCnt * 2) + numCnt);

char zero = '0';

char lowerA = 'a';

char upperA = 'A';

Random r = new Random();

for(int i=0; i<data.length; i++){

int index = Math.abs(r.nextInt()) % totalCnt;

if(index < numCnt){

data[i] = (char) (zero + index);

}else if(index < (numCnt + alphaCnt)){

data[i] = (char)  (upperA + index - numCnt);

}else{

data[i] = (char) (lowerA + index - numCnt - alphaCnt);

}

}

return data;

}

}



클래스를 따로 만들어보았다. 미리 저장된 문자열을 사용하게 되어 있었는데, 6자리 문자열을 랜덤하게 만들도록 수정했다. generateKeyText메서드가 원본, generateKeyRandomText 메서드가 수정본이다. 사용하는 것은 간단하다. 다음은 이미지 생성 코드이다.

@RequestMapping("/capchaTest")

protected void capchaTest(HttpServletRequest request, 

HttpServletResponse response)

            throws ServletException, IOException {

Captcha.makeTextImage(request, response);

}


확인은 다음 코드로 하면 된다.

String captcha = (String) session.getAttribute("captcha");

String code = (String) request.getParameter("code");


if (captcha != null && code != null) {

if (captcha.equals(code)) {

out.print("<p class='alert'>Correct</p>");

} else {

out.print("<p class='alert'>Incorrect</p>");

}

}


이건 어디서 많이 봤다 싶었는데, simple chaptcha의 예제와 동일하다. 중간에 폼으로 넘기는 부분은 생략하겠다. 출처 사이트에 보면 자세히 나와있으니 출처 사이트도 보기를 권한다.


tags : CAPTCHA, Java
Trackback 0 : Comment 0

java.security.InvalidKeyException: Illegal key size 오류

Java 2015.04.28 14:17

암호화 테스트 중 java.security.InvalidKeyException: Illegal key size 오류가 났다.

SHA256은 그냥 바로 되던데, AES256은 오류가 난다. 오류 코드를 검색해보면 바로 해결방법이 나오지만, 왜그런지 해결이 안됬다. 몇번의 삽질 끝에 원인을 찾았는데, 컴파일하는 jdk버전이 다른 버젼으로 맞춰져있었다... 이런 삽질은 고만 해야할텐데...


해결방법은 간단한데, 미국에서 일정 이상 암호화 기술은 수출금지를 시켰단다. 그래서 필요한 파일만 다운받아 사용하면 되는 것이다. 수출 금지인데 다운받으면 바로 해결되는 것도 좀 이상하긴 한데... 오라클 홈페이지에 가면 jar파일이 있는데 jdk 버전별로 다운 받아서 넣어주자. jdk가 설치된 경로 밑에 jre/lib/security 로 찾아가서 다운받은 파일을 압축풀면 나오는 local_policy.jar, US_export_policy.jar 파일 두개를 덮어써주면 된다.


다운로드 경로

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6

http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html


Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7

http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html


Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8

http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html



'Java' 카테고리의 다른 글

Static Import 에 대해  (0) 2015.09.18
captcha를 만들어보자  (0) 2015.04.29
java.security.InvalidKeyException: Illegal key size 오류  (0) 2015.04.28
문자열 패턴 분석 정규식  (0) 2015.04.21
hadoop - 하둡(Hadoop)이란 무엇인가?  (0) 2012.10.05
자바 7 보안 패치  (0) 2012.08.31
Trackback 0 : Comment 0

문자열 패턴 분석 정규식

Java 2015.04.21 16:36

비밀번호 패턴을 읽어 숫자 알파벳 대소문자 특수 문자를 사용했는지 분석하기 위한 소스가 필요했다. 기존에 만들어 저있는 것은 1바이트씩 비교해서 만든 것이라 좀 더 눈에 잘 들어오게 만들어보기위해 요즘 정규식을 이용해보고 있다.

Pattern, Matcher 클래스를 이용하니까 간단하게 되서 참 편하다.


먼저 알파벳, 숫자, 특수문자를 구분하는 함수를 만들어보자.

public static boolean isAlnumPunct(String str){

boolean bResult = false;

Pattern pt = Pattern.compile("[\\p{Alnum}\\p{Punct}]{1,}");

Matcher mc = pt.matcher(str);

if(mc.matches()){

bResult = true;

}

return bResult;

}


\p{Alnum}는 알파벳과 숫자를 나타내는 패턴이고 \p{Punct}는 특수문자를 나타내는 패턴이다. {1,}은 적어도 1번 이상 나와야 한다는 뜻으로, [\\p{Alnum}\\p{Punct}]{1,} 패턴은 알파벳, 숫자, 특수문자 중에 1자 이상 있어야한다는 뜻이 된다. punct는 punctuation으로 구두법이라는 뜻이다. 글을 쓸 때 문장 부호를 쓰는 법이 이란다. 


여기서 비교구분을 내가 만들본 것과 비교해보자

String pattern = "^[0-9a-zA-Z/`~!_@#$%<>,.;:-=&\\^\\[\\]\\{\\}[*][+][|][?]]+$";

boolean check = Pattern.matches(pattern, str);


일일히 범위를 지정해야하고 가능한 특수문자를 넣어줘야한다. 앞으로 간단하게 사용해야겠다. 다음은 문자열중에 특정 문자가 포함되어있는지 검사하려고 만든 패턴이다.

        String patternNumber = "(.*)[0-9](.*)";

        String patternAlpha = "(.*)[a-zA-Z](.*)";

        String patternSp = "(.*)[/`~!_@#$%()<>,.;:-=&\\^\\[\\]\\{\\}[*][+][|][?]](.*)";

        String patternBlank = "(.*)[\\s](.*)";

        String patternHangul = "(.*)[ㄱ-ㅎㅏ-ㅣ가-힣](.*)";


        boolean checkNum = Pattern.matches(patternNumber, str);

        boolean checkAlpha = Pattern.matches(patternAlpha, str);

        boolean checkSp = Pattern.matches(patternSp, str);

        boolean checkBlank = Pattern.matches(patternBlank, str);

        boolean checkHangul = Pattern.matches(patternHangul, str);


차례대로 숫자, 알파벳, 특수문자, 공백, 한글이 문자열에 포함되는지 알아보기 위한 패턴이다.

그리고 숫자 4개가 붙어있지 검사하는 패턴도 만들어보았다.

Pattern pt = Pattern.compile("(.*)[\\p{Digit}]{4}(.*)");




참고 자료

http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

http://blog.daum.net/dok9red/6

Trackback 0 : Comment 0

JAVA MessageDigest 클래스

encryption 2015.04.20 14:39

SHA-256 암호화를 할 일이 생겨서 찾아보았다. JAVA POJO에서 기본적으로 나와있는 MessageDigest 클래스에서 지원을 한단다. MessageDigest는 MD5D와 SHA-1 그리고 SHA-256 등을 지원하는 듯하다. 사용법이 거의 같기 때문에 한가지만 보면 응용가능하다. 일딴 인터넷에 돌고 있는 셈플을 보자.

public static String getSHA256(String str){

String reCode = null;

try{

//MessageDigest 인스턴스 생성

MessageDigest sha = MessageDigest.getInstance("SHA-256");

//해쉬값 업데이트

sha.update(str.getBytes());

//해쉬값(다이제스트) 얻기

byte byteData[] = sha.digest();

StringBuffer sb = new StringBuffer();

//출력: 해쉬값을 16진수로 표현한 문자로 변환

for(byte byteTmp : byteData) {

sb.append(Integer.toString((byteTmp&0xff) + 0x100, 16).substring(1));

}

reCode = sb.toString();

}catch(Exception e){

logger.info(Sha256Cipher.class.getName() + " getSHA256 Error : " + e);

}

return reCode;

}


대체적으로 이런 소스가 돌고 있다. 여기서 좀더 간단한 표현을 찾았다.

public static String getEncryptSHA256(String str){

String reCode = null;

try{

//MessageDigest 인스턴스 생성

MessageDigest sha = MessageDigest.getInstance("SHA-256");

            

//출력: 해쉬값업데이트 후에 16진수 문자로 변환 

sha.update(str.getBytes(), 0, str.length());

reCode = new BigInteger(1, sha.digest()).toString(16);

}catch(Exception e){

logger.info(Sha256Cipher.class.getName() + " getEncryptSHA256 Error : " + e);

}

return reCode;

}



참고 자료

http://javaking75.blog.me/140212037961

http://docs.oracle.com/javase/8/docs/api/java/security/MessageDigest.html

http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#MessageDigest

'encryption' 카테고리의 다른 글

JAVA MessageDigest 클래스  (0) 2015.04.20
RSA + spring + ehcache + freemarker  (0) 2012.07.20
Trackback 0 : Comment 0

에러 콘트롤러를 만들어 로그를 찍어보자

Java/Spring 2015.03.12 15:50

web.xml에 다음 코드를 추가하면 간단히 에러 페이지로 이동할 수 있다.

 <error-page>

  <error-code>404</error-code>

  <location>/error/error.html</location>

 </error-page>


 <error-page>

  <error-code>500</error-code>

  <location>/error/error.html</location>

 </error-page>


그런데 나는 error.html을 컨트롤러로 구현하여 로그를 찍어보고 싶었다. 에러코드, URI, 에러 메시지등.

가능해보여서 찾다가보니 쉽게 나오지 않는다. 일반적인 방식이 아닌모양이다. 순수 자바로 구현한 예제를 찾았다.

그렇게 해서 구현한 것이 다음과 같다.

Throwable throwable = (Throwable)req.getAttribute("javax.servlet.error.exception");

Integer statusCode = (Integer)req.getAttribute("javax.servlet.error.status_code");

String servletName = (String)req.getAttribute("javax.servlet.error.servlet_name");

if (servletName == null){

servletName = "Unknown";

}

String requestUri = (String)req.getAttribute("javax.servlet.error.request_uri");

if (requestUri == null){

requestUri = "Unknown";

}


LOG.info("!!!!!!!  ##### Error information #####");

LOG.info("!!!!!!!  The status code : " + statusCode);

LOG.info("!!!!!!!  Servlet Name : " + servletName);

LOG.info("!!!!!!!  The request URI: " + requestUri );

LOG.info("!!!!!!!  The exception message: " + throwable.getMessage());

LOG.info("!!!!!!!  Exception Type : " + throwable.getClass().getName() );


request를 이용해서 에러코드인 서버의 상태코드, 서블릿 이름, URI, 에러 메시지, 에러 타입등을 알 수 있다.

그런데 404 코드의 경우에는 throwable 이 오류나기 때문에 다음과 같이 해주면 된다.

LOG.info("!!!!!!!  ##### Error information #####");

LOG.info("!!!!!!!  The status code : " + statusCode);

LOG.info("!!!!!!!  Servlet Name : " + servletName);

LOG.info("!!!!!!!  The request URI: " + requestUri );

if(statusCode == 500){

LOG.info("!!!!!!!  The exception message: " + throwable.getMessage());

LOG.info("!!!!!!!  Exception Type : " + throwable.getClass().getName() );

}


이렇게 하면 문제없이 동작이 된다. 상태코드를 확인하다가 내가 모르는 내용이 더 있다는 것을 알았다. 5XX 상태코드는 서버 오류였다. 그래서 다음과 같이 수정해주면 좋을것 같다.

LOG.info("!!!!!!!  ##### Error information #####");

LOG.info("!!!!!!!  The status code : " + statusCode);

LOG.info("!!!!!!!  Servlet Name : " + servletName);

LOG.info("!!!!!!!  The request URI: " + requestUri );

if( (statusCode/100) == 5 ){

LOG.info("!!!!!!!  The exception message: " + throwable.getMessage());

LOG.info("!!!!!!!  Exception Type : " + throwable.getClass().getName() );

}


아직 다른 오류로 확인된건 없지만 동작은 잘 된다. 역시 훌륭한 사람은 넘처나는 구나. 훌륭해 지자.


참고 URL

http://www.tutorialspoint.com/servlets/servlets-exception-handling.htm

http://www.journaldev.com/1973/servlet-exception-and-error-handling-example-tutorial

http://ko.wikipedia.org/wiki/HTTP_%EC%83%81%ED%83%9C_%EC%BD%94%EB%93%9C


'Java > Spring' 카테고리의 다른 글

Spring4 웹 어플리케이션 생성하기  (0) 2018.01.23
logback library Exception 출력  (0) 2017.12.19
에러 콘트롤러를 만들어 로그를 찍어보자  (0) 2015.03.12
Spring + Maven 프로젝트 만들기  (0) 2014.03.03
dwr 오류  (0) 2012.08.01
스프링 버젼 확인하기  (0) 2012.06.28
Trackback 0 : Comment 0

티스토리 툴바