반응형

이번 포스팅에서 소개하는  JDK1.6 기반의 SimpleCaptcha 라이브러리를 이용한 CAPTCHA 샘플 프로그램은 이전 샘플과는 달리 Servlet

을 사용하지 않고 단순 Java객체로 구현했으며, 이전 포스팅에서 소개한 바와 같이 음성서비스도 지원한다.


다음은 CaptCha Image를 생성하는 'CaptCha' 클래스의 소스 코드이다.

package captcha;


import static nl.captcha.Captcha.NAME;
import java.awt.Color;
import java.awt.Font;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nl.captcha.Captcha;
import nl.captcha.backgrounds.GradiatedBackgroundProducer;
import nl.captcha.gimpy.DropShadowGimpyRenderer;
import nl.captcha.servlet.CaptchaServletUtil;
import nl.captcha.text.producer.NumbersAnswerProducer;
import nl.captcha.text.renderer.DefaultWordRenderer;


public class CaptCha{

    private static final long serialVersionUID = 1L;
    private static int width = 150; //이미지 가로크기
    private static int height = 50; //이미지 높이


    public void getCaptCha(HttpServletRequest req, HttpServletResponse res) throws IOException {

     // 폰트 설정 부분 =============================================
        List<Font> fontList = new ArrayList<Font>();
        fontList.add(new Font("", Font.HANGING_BASELINE, 40));
        fontList.add(new Font("Courier", Font.ITALIC, 40));
        fontList.add(new Font("", Font.PLAIN, 40));

        List<Color> colorList = new ArrayList<Color>();
        colorList.add(Color.black); //또는  colorList.add(Color.green), colorList.add(Color.blue) 등으로 설정
        //=========================================================


        Captcha captcha = new Captcha.Builder( width, height)
               //.addText() 또는 아래와 같이 정의    
               //6자리 숫자와 폰트를 설정한다.
               .addText(new NumbersAnswerProducer(6), new DefaultWordRenderer(colorList, fontList))
               .gimp(new DropShadowGimpyRenderer()).gimp()
               // BlockGimpyRenderer,FishEyeGimpyRenderer,RippleGimpyRenderer,ShearGimpyRenderer,StretchGimpyRenderer
               .addNoise().addBorder()
               .addBackground(new GradiatedBackgroundProducer())
                // FlatColorBackgroundProducer,SquigglesBackgroundProducer,TransparentBackgroundProducer
                .build();

        

         //JSP에서 Captcha 객체에 접근할 수 있도록 Session에 저장한다.

         req.getSession().setAttribute(NAME, captcha); //NAME = Captcha.NAME = 'simpleCaptcha'
         CaptchaServletUtil.writeImage(res, captcha.getImage());
    }
}



다음은 CaptCha Audio를 생성하는 'AudioCaptCha' 클래스의 소스 코드이다.

package captcha;


import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import nl.captcha.Captcha;
import nl.captcha.audio.AudioCaptcha;
import nl.captcha.servlet.CaptchaServletUtil;


public class AudioCaptCha {

    public void getAudioCaptCha(HttpServletRequest req, HttpServletResponse res, String answer)

      throws IOException{


        HttpSession session = req.getSession();
       
        //Captcha.NAME = 'simpleCaptcha'
        Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME);
        String getAnswer = answer; 

        if ( getAnswer == null || getAnswer.equals("") ) getAnswer = captcha.getAnswer();

 

        AudioCaptcha audiocaptcha = new AudioCaptcha.Builder()
                           //.addAnswer(new DefaultTextProducer(6, getAnswer.toCharArray())) 또는 다음과 같이...
                           .addAnswer(new SetTextProducer(getAnswer))
                           .addNoise() //잡음추가
                           .build();


        CaptchaServletUtil.writeAudio(res, audiocaptcha.getChallenge());

    }
}

 


다음은 User Defined TextProducer 인 'SetTextProducer' 클래스이다. 여기서 'SetTextProducer' 클래스는 전달받은 문자열을 그대로

AudioCaptcha가 사용할 수 있도록 하는 역할을 한다.

package captcha;


import nl.captcha.text.producer.TextProducer;


public class SetTextProducer implements TextProducer {

    private final String srcStr;

    public SetTextProducer(String answer) {   
        srcStr = answer; 
   }

   

    //@Override
   public String getText() {        
        return srcStr;
   }

}

 


다음은 본 예제의 메인 페이지에 해당하는 'index.jsp'의 소스 코드이다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
  String ctx = request.getContextPath(); //콘텍스트명 얻어오기.
  response.setHeader("Pragma-directive", "no-cache");
  response.setHeader("Cache-directive", "no-cache");
  response.setHeader("Pragma", "no-cache");
  response.setHeader("Cache-Control", "no-cache");
  response.setDateHeader("Expires",0);
%>
<!DOCTYPE  html>
<html>
<head>
<title>CaptCha Exam None Servlet</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, target-densitydpi=medium-dpi" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Imagetoolbar" content="no" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>


<script type="text/javascript">

 /*
  * Captcha Image 요청
  * [주의] IE의 경우 CaptChaImg.jsp 호출시 매번 변하는 임의의 값(의미없는 값)을 파라미터로 전달하지 않으면
  * '새로고침'버튼을 클릭해도 CaptChaImg.jsp가 호출되지 않는다. 즉, 이미지가 변경되지 않는 문제가 발생한다.
  *  그러나 크롭의 경우에는 파라미터 전달 없이도 정상 호출된다.
  */
 function changeCaptcha() {
  //IE에서 '새로고침'버튼을 클릭시 CaptChaImg.jsp가 호출되지 않는 문제를 해결하기 위해 "?rand='+ Math.random()" 추가
  $('#catpcha').html('<img src="<%=ctx%>/captcha_mod/CaptChaImg.jsp?rand='+ Math.random() + '"/>');
 }


 function winPlayer(objUrl) {
  $('#audiocatpch').html(' <bgsound src="' + objUrl + '">');
 }

 
 /*
  * Captcha Audio 요청
  * [주의] IE의 경우 CaptChaAudio.jsp 호출시 매번 매번 변하는 임의의 값(의미없는 값)을 파라미터로 전달하지 않으면
  * '새로고침'된 이미지의 문자열을 읽지 못하고 최초 화면 로드시 로딩된 이미지의 문자열만 읽는 문제가 발생한다.
  * 이 문제의 원인도 결국 매번 변하는 파라미터 없이는 CaptChaAudio.jsp가 호출되지 않기 때문이다.
  * 그러나 크롭의 경우에는 파라미터 전달 없이도 정상 호출된다. 
  */
 function audioCaptcha() {

   var uAgent = navigator.userAgent;
   var soundUrl = 'CaptChaAudio.jsp';
   if (uAgent.indexOf('Trident') > -1 || uAgent.indexOf('MSIE') > -1) {
       //IE일 경우 호출
       winPlayer(soundUrl+'?agent=msie&rand='+ Math.random());
   } else if (!!document.createElement('audio').canPlayType) {
       //Chrome일 경우 호출
       try { new Audio(soundUrl).play(); } catch(e) { winPlayer(soundUrl); }
   } else window.open(soundUrl, '', 'width=1,height=1');
 }

 
 //화면 호출시 가장 먼저 호출되는 부분
 $(document).ready(function() {

  
  changeCaptcha(); //Captcha Image 요청
  
  $('#reLoad').click(function(){ changeCaptcha(); }); //'새로고침'버튼의 Click 이벤트 발생시 'changeCaptcha()'호출
  $('#soundOn').click(function(){ audioCaptcha(); }); //'음성듣기'버튼의 Click 이벤트 발생시 'audioCaptcha()'호출
  
  //'확인' 버튼 클릭시
  $('#frmSubmit').click(function(){
      if ( !$('#answer').val() ) {
           alert('이미지에 보이는 숫자 또는 스피커를 통해 들리는 숫자를 입력해 주세요.');
      } else {
           $.ajax({
               url: 'CaptchaSubmit.jsp',
               type: 'POST',
               dataType: 'text',
               data: 'answer=' + $('#answer').val(),
               async: false,  
               success: function(resp) {
                    alert(resp);
                    $('#reLoad').click();
                    $('#answer').val('');
              }
         });
      }
  });

 });
</script>
</head>
<body>
  <div id="catpcha">Wait...</div>
  <div id="audiocatpch" style="display: none;"></div>

  <input id="reLoad" type="button" value="새로고침" />
  <input id="soundOn" type="button" value="음성듣기" />

  <br />
  <input type="text" id="answer" name="answer" value="" />
  <input type="button" id="frmSubmit" value="확인" />
</body>
</html>

 


다음은 'CaptCha' 클래스의 호출해서 CaptCha Image를 생성하는 'CaptChaImg.jsp' 의 소스 코드이다.

 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="captcha.CaptCha"%>
<%
    new CaptCha().getCaptCha(request, response); 
%>

 


다음은 'AudioCaptCha' 클래스를 호출하여 CaptCha Audio를 생성하는 'CaptChaAudio.jsp'의 소스 코드이다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="captcha.AudioCaptCha, nl.captcha.Captcha"%>
<%
   //Captcha.NAME = 'simpleCaptcha'
   Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME);
   String getAnswer = captcha.getAnswer();
//CaptsCha Image에 사용된 문자열을 반환한다.
   new AudioCaptCha().getAudioCaptCha(request, response, getAnswer);
%>

 


다음은 사용자가 입력한 문자열과 CaptCha 클래스가 생성한 문자열이 일치하는지 확인하는 'CaptchaSubmit.jsp'의 소스 코드이다.

<%@ page session="true" language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="nl.captcha.Captcha" %>
<%
   response.setHeader("Pragma-directive", "no-cache");
   response.setHeader("Cache-directive", "no-cache");
   response.setHeader("Pragma", "no-cache");
   response.setHeader("Cache-Control", "no-cache");
   response.setDateHeader("Expires",0);
  
   //Captcha.NAME = 'simpleCaptcha'
   Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME);
   String answer = request.getParameter("answer"); //사용자가 입력한 문자열
   if ( answer != null && !"".equals(answer) ) {


       if (captcha.isCorrect(answer)) { //사용자가 입력한 문자열과 CaptCha 클래스가 생성한 문자열
           session.removeAttribute(Captcha.NAME);
           out.print("입력값이 일치합니다.");
       } else {
           out.print("입력값이 일치하지 않습니다.");
       }

 

   }
%>

 


다음은 본 예제를 실행한 화면이다.


- IE11에서 실행한 화면

 


- Chrome 에서 실행한 화면


IE11, Chrome 모두 동일하게 동작한다!


[개발후기]

코드를 좀더 간결히 할 수 있었는데, 망할놈의 IE에서 제대로 동작하지 않아서 Chrome과 IE 양쪽 모두에서 정상 동작해야 한다는 요건을

충족시키려다 보니 잡코드(= 잡스런 코드)가 다소 포함됐다... IE때매 포함시킨 잡코드들은 소스 코드에 주석으로 달아놨다.

덧붙여, 본 예제와 관련된 SimpleCaptcha 라이브러들은 이전 포스팅에서 소개한 SimpleCaptcha 홈에서 다운받을 수 있다.

[원본] [JAVA] SimpleCaptcha 를 이용한 자동가입방지 문자 생성하기 - JDK1.6(JAVA6) 기반|작성자 황철연

 

[출처]http://gnujava.com/board/article_view.jsp?article_no=7121&menu_cd=16&board_no=3&table_cd=EPAR01&table_no=01

반응형



Posted by 궁극의 java개발자
,





반응형

FTPSClient 는 sftp접속을 할 수 없다는... 그래서 jsch라이브러리 이용.


jsch-0.1.49.jar 파일은 첨부함.

jsch-0.1.49.jar

@Controller
public class Test{

 
 @RequestMapping(value="/test", method=RequestMethod.GET)
 public void test(HttpServletRequest request, HttpServletResponse response) throws Exception {
  

    connect();//아래의 메소드 실행
   
 }
 
 
    @SuppressWarnings("unchecked")
 private void connect() throws Exception {
      
         Session session = null; //com.jcraft.jsch.Session 참조함

        // 1. JSch 객체를 생성한다.
        JSch jsch = new JSch();


        // 2. 세션 객체를 생성한다 (사용자 이름, 접속할 호스트, 포트를 인자로 준다.)
//        session = jsch.getSession(username, host, port);
        session = jsch.getSession("유저", "아이피", 포트);


        // 3. 패스워드를 설정한다.
        session.setPassword("test");

        
        // 4. 세션과 관련된 정보를 설정한다.
        java.util.Properties config = new java.util.Properties(); 


        // 4-1. 호스트 정보를 검사하지 않는다.
        config.put("StrictHostKeyChecking", "no"); 
        session.setConfig(config);

        try{
         
         //5. 접속한다.       
         session.connect();
        
         // 6. sftp 채널을 연다.
         Channel channel = session.openChannel("sftp");
         ChannelSftp channelSftp = (ChannelSftp) channel;
         channelSftp.connect();

        
         StringBuffer sb = new StringBuffer();
         String ftpDir = "/test/info/";
         
         //디렉토리 접근
         channelSftp.cd(ftpDir);
                  
         //디렉토리 안의 목록 조회
         Vector flist = channelSftp.ls(ftpDir);
         
         for(ChannelSftp.LsEntry entry : flist){
         
          if(!entry.getFilename().equals(".") 

              ​&& !entry.getFilename().equals("..") 

              && entry.getFilename().indexOf(".") != 0){
           log.info("파일명 :"+entry.getFilename());
           

           //​버퍼로 읽기
           BufferedReader reader = new BufferedReader(new InputStreamReader(channelSftp.get(entry.getFilename())));
           

​/*

버퍼로 읽은 파일의 내용 ex, 

[{"id":"test","client_ip":"127.0.0.1"}]​

[{"id":"test","client_ip":"127.0.0.1"}]​

[{"id":"test","client_ip":"127.0.0.1"}]​​

*/​
  

         String readStr = "";

                 //한줄씩 읽으면서 json파서로 담는다
                 while((readStr = reader.readLine()) != null) {
                  log.info("################# readStr:"+readStr);
                  
                  Gson gson = new Gson();
            JsonParser parser=new JsonParser();
            JsonArray jsonArray = (JsonArray)parser.parse (readStr);
            

            //json 객체를 구글json인 gson을 이용하여 내가 원하는 VO객체에 자동으로 담는다. 이게 대봑임 ㅋㅋ. ​ VO객체에는 변수들이 getter, setter로 선언되어 있음.
            for (int i = 0; i < jsonArray.size(); i ++){
             FtpData fdVO = (FtpData) gson.fromJson(jsonArray.get(i), FtpData.class);
             log.info("################# fdVO:"+fdVO.toString());
            }
                 }
                 
                 reader.close();//버퍼 종료
          }
         }
         
         channelSftp.disconnect();//ftp종료
        
        }catch(SftpException e){
         e.printStackTrace();
        }

    }  

} 
반응형



Posted by 궁극의 java개발자
,





반응형
구글링을 통해 JAVA를 활용한 한글 인코딩 처리에 대해 자료를 찾아봤는데 정확하고 좋은 자료가 많지 않았다.


위 블로그에서는 자바에서 String은 UTF-8로 취급된다..고 언급하고 있다.

그러나 내가 해보니 JAVA 프로그램 소스 파일의 인코딩을 따라가는 것 같다.
소스파일이 MS949 방식이면 파일 입출력에서도 MS949 방식을 따른다.

따라서 인코딩 형식이 UTF-8 포맷의 소스파일에서 파일 입력과 출력을 MS949 형식으로 된 것을 하려면 이렇게 해야한다.

//파일 입력
FileInputStream fileInputStream = new FileInputStream(filePath);
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "MS949");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);


//파일 출력
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
OutputStreamWriter OutputStreamWriter = new OutputStreamWriter(fileOutputStream, "MS949");
BufferedWriter bufferedWriter = new BufferedWriter(OutputStreamWriter);




따라서 MS949 인코딩으로 된 텍스트 파일을 읽어서 UTF-8 로 저장하고 싶다면, 위에는 MS949, 아래엔 UTF-8로 입력부와 출력부를 잡아주면 된다.

반응형



Posted by 궁극의 java개발자
,





반응형

JAVA에서 파일 삭제

 

import java.io.File; 

//파일삭제처리 
File delFile= null;
delFile= new File(saveFileName);
delFile.delete(); 
// -> saveFileName 은 실제 업로드 된 파일경로와 파일명 변수이다. 
반응형



Posted by 궁극의 java개발자
,