Clean Code that Works.

Spring-Secury 버전이 3.1.4가 되면서 부터 org.springframework.security.authentication.encoding.PasswordEncoder@Deprecate 됬다.
이를 교체하기 위해서 org.springframework.security.cryptho.password.PasswordEncoder 사용을 유도하고 있다.

기존 PasswordEncoder에서는 별도의 SaltSource를 만들어서 사용하도록 하고 있었는데, 신규 PasswordEncoder에서는 이를 구현한 클래스(BCryptPasswordEncoder) 같은 친구들이 자동으로 만들어 준다.

국내에 출간된 스프링 시큐리티 3 책에는 이전 PasswordEncoder를 사용하는 예제가 들어있는데, Spring-Security 버전을 3.1.4 이상으로 사용할 려면 새로운 PasswordEncoder 인터페이스를 사용 하도록 하자.

생활 코딩 하면서 만들고 있는 사이트에 encoding.PasswordEncoder를 사용하고 있어서 @Deprecate 된게 거슬렸었는데, 이번 기회에 password.PasswordEncoder로 변경 하였다

아래 링크를 참조 하면 손쉽게 바꿀 수 있다.
http://stackoverflow.com/questions/17444258/how-to-use-new-passwordencoder-from-spring-security
(그냥 빈 패키지를 변경해주고 메서드를 .encode로 변경하고, 두번째 파라미터를 삭제 하면 됨)

SaltSource를 PasswordEncoder가 직접 만들어 주기(랜덤) 때문에 별도로 관리할 필요가 없다. 고로 SaltSoure로 사용한 값이 노출 될 가능성이 없다.





프로퍼티 에디터 등등...

화면에서 값을 변경해서 보여줄 때는 <form:input>으로 사용하던지,
아니면 <spring:bind> 로 해서 보여줘야 한다. 웁스.

이게 폼에서 보여줄 때 이렇게 하면 되는데,

나는 뷰.... 목록으로 보여줄때 컨버팅을 하고 싶었다.
이렇게 저렇게도 해보고 고민해봤는데 도무지 이해가 안되서 KSUG에 질문을 올렸다.

http://groups.google.com/group/ksug/browse_thread/thread/6f4a94d4485de366

토비님 글에도 설명이 되어 있는데.
http://toby.epril.com/?p=989

<spring:eval> 태그를 사용하면 된다고 한다..conversionService를 사용해서
전체적인 설명은 토비님 블로그에 잘 설명이 되어 있고,
사용하는 방법은 아래와 같이 설정 해 주면된다.

<mvc:annotation-driven conversion-service="conversionService"/>


<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="springsprout.common.conversion.converter.TimeToWebStringConverter" />
            </list>
        </property>
</bean>

이렇게 설정 해 주면 화면 <spring:eval>은 ConversionServiceExposingInterceptor이녀석이 가로체서 컨버터를 적용 해 준다.

토비님 책 보면서 이쪽 부분은 아직 안 읽었었는데, Type-Conversion 부분이 폼에서 하는 부분과 리스트등 뷰에서 하는 부분이 햇갈려서 시간을 많이 잡아 먹었다. -_-;;;
그래도 덕분에 컨버터에 대해서 좀 볼 수 있었다. ..;;

참 jsp에서는 <spring:eval expression="meeting.openTime?:''"/>
이렇게 적어 주어야 한다.
spring el 에 대해서 잘 몰라서 .. The Elvis Operator라는 방식이라는데..
뭐 널이면 "" 공백 출력하라는거 같은데.. 이부분은 좀 더 살펴봐야겠다.

저 ConversionServiceExposingInterceptor 이게 어떻게 값 변환하는지 궁금하네.


파일 업로드가 안되네 -_-;;

=_=..

일단 소스라도.



서블릿 맵핑 설정


어쩌다 보니 간단한 XML 에디터 까지 개발해야 해서...
완전 삽질중. -_-;;
작년 9월부터 시작한걸 아직까지 잡고 있다.
뭐 중간에 캐나다고 갔다오고.. 하기 싫어서 다른 책도 보고 했지만..
이제 슬슬 끝이 보인듯 싶다. 역시 GUI는 번거롭다.

여튼 각설하고 XPATH로 원하는 노드를 찾은 후 XML 문서에 저장 하는 방법을 알아보자.

일단 처음엔 XPATH를 사용해야하기 때문에 XPathFactory 로 새 인스턴스를 만든 후, XPath도 새로 만들어 준다.

XPathFactory xpathFactory = XPathFactory.newInstance();
xpath = xpathFactory.newXPath();
xmlSource = new InputSource(Main.TESTSOURCE);
// 인풋 소스는 해당 xml 파일.

이렇게 해서 각각 인스턴스들을 만든후.
xpath 검색을 해서 엘리먼트에 할당한 다음에
이 엘리먼트에서 수정을 한 후.

Element element = (Element) xpath.evaluate(path, xmlSource, XPathConstants.NODE);
//xpath를 사용해서 검색.
Element root = (Element) element.getParentNode().getParentNode()
    .getParentNode().getParentNode();
//루트는 새로 문서를 저장할 때 필요하기 때문에 필요하다. 나 같은 경우에는 xpath를 사용해서 검색한 깊이가 4단계 이기 때문에 4번째 위의 부모 노드가 루트 노드이다.
Element feature = (Element) element.getChildNodes().item(3);
feature.setTextContent("원하는 데이터");
//해당 노드를 얻어 와서 setTextContent를 사용해서 값을 할당


이렇게 하면 일단 메모리에 올라와 있는 element 들은 다 수정이 되어 있다.
그 다음에는 TransformerFactory 를 사용해서 문서를 다시 저장해 주어야 한다.

TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
DOMSource source = new DOMSource(root);
StreamResult result = new StreamResult(new File(Main.TESTSOURCE));
transformer.transform(source, result);


DOM 객체를 수정, 추가, 제거하는 것은 모두 메모리상에서 이루어지고 이것을 영구 보본하기 위해서는 파일의 형태로 XML 문서로 저장해야 한다.

다양한 방법으로 문서를 저장 할 수 있지만 위의 방법은 XSLT변환기를 사용하여 파일로 저장한다.




import java.util.Scanner;

public class CheckPrimeNumber {
 private int input;
 private Scanner scan = new Scanner(System.in);
 private boolean prime;
 
 public CheckPrimeNumber() {
  putInfo();
 }
 
 public void setInputNumber(int input) {
  this.input = input;
 }
 
 public void putInfo() {
  System.out.println("소수 계산 프로그램 입니다.");
 
  System.out.print("계산 하고자 하는 수를 입력 하세요 : ");
  setInputNumber(scan.nextInt());
 
  System.out.println("계산중...");
 
  putNumber(input);
 }
 
 public boolean calculation(int num) {
  prime = true;
     int limit = (int) Math.sqrt ( num ); 

     for ( int i = 2; i <= limit; i++ )
     {
      if ( num % i == 0 )
      {
       prime = false;
       break;
      }
     }
     return prime;
 }
 
 public void putNumber(int num) {
  int j = 0;
  for (int i = 2; i <= num; i++){
   if (calculation(i)) {
    System.out.println(i);
    j++;
   }
  }
  System.out.println("입력한 숫자 "+input+"의 소수의 갯수는 "+j+"개입니다.");
 }
 
 public static void main(String[] args) {
  new CheckPrimeNumber();
 }
}