U E D R , A S I H C RSS

Spring/탐험스터디/wiki만들기

SimpleWiki

Spring Framework

Spring Security

  • 스프링 시큐리티 사용 준비
  • UserDetail - 스프링 시큐리티가 사용할 수 있는 User 객체 만들기
  • 현재 로그인 한 사용자 정보 가져오기
    1. SecurityContextHolder를 이용하는 법
      Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
      
                      String name;
                      if (principal instanceof UserDetails) {
                        name = ((UserDetails)principal).getUsername();
                      } else {
                        name = principal.toString();
                      }
      
    2. Spring dependency injection을 이용하는 법
      public String write(@RequestParam("title") String title, @RequestParam("contents") String contents, Model model, Principal principal) {
      ...
      page.edit(contents, userRepository.get(principal.getName()));
      ...
      }
      

  • spring security tab library
    • spring security에 관련된 기능들을 html/js에서 쓸 수 있다.

<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
...
        <sec:authorize ifAllGranted="ROLE_USER">
                <input id="contents_edit" type="textarea" class="page_edit" value="${page.contents}" />
                <a href="#" class="page_edit" id="save">save</a>
        </sec:authorize>
...
        <sec:authorize url="/login">
                <a href="logout">Logout</a>
        </sec:authorize>

  • Spring Security의 Role Voter는 "ROLE_" 접두어를 사용한 접근 속성만 처리한다. 단 접두어는 커스터마이징이 가능하다.

Hibernate

  • ORM(Object Relation Mapping) 프레임워크. Java persistence, EJB3.0을 같이 알면 좋다.
  • Lisence : LGPL

JSP

Markdown

  • 위키 문법을 별도로 정의하고 파서를 구현하는 대신 Markdown을 사용하기로 결정했다.
    • Markdown이란 : wiki:Markdown
    • 위키피디아를 참고하여 Java로 구현된 Markdown implementation 중 Pegdown을 선택했다.
      • MarkdownJ, MarkdownPapers는 문서가 부실하고 남은 두 구현체 중 Pegdown이 위키 제목을 통한 페이지 링크를 더 간편하게 지원해서.
      • 아주 간단한 Pegdown 사용 예
        1. pom.xml에 dependency 추가하기
          <dependency>
                  <groupId>org.pegdown</groupId>
                  <artifactId>pegdown</artifactId>
                  <version>1.1.0</version>
          </dependency>
          
        2. markdown text를 html 문자열로 변환
          String html = new PegDownProcessor().markdownToHtml("markdown text");
          

CGLIB

  • CGLIB는 코드 생성 라이브러리로서(Code Generator Library) 런타임에 동적으로 자바 클래스의 프록시를 생성해주는 기능을 제공(펌) 이라고 한다.

후기

8월 30일

  • 김수경
    • 2주? 까지는 아니지만 1.5주만에 스터디를 재개했더니 이전 소스 코드가 잘 기억이 나지 않아 난감했다. 틈틈이 소스 코드를 봤다면 이렇게까지 기억이 안 나지는 않았을텐데 그동안 손을 놓고 있었더니... 다음엔 이러지 말아야지.
    • 처음에 소스 코드 짜면서 일단 돌아가게 만들자!! 는 마음으로 코딩을 했더니 바꿔야 할 부분이 아주 많아졌다. 아무렇게나 짜려는 건 아니고 개발이 너무 지연되다가 흐지부지 되는 게 싫어서 그렇게 한 건데 지속적으로 개발하다가 특정 부분을 고쳐야할 시기에 기민하게 고치지 않으면 답이 없는 코드가 되는 것 같다.
      • 그래서 오늘 느낀 게 이 코드는 데미 무어 코드라고…
    • TODO : write/delete 등 함수 단위로 security 설정 필요함
  • 서지혜
    • 오늘은 위키 문법을 구현하기로 하였다.
      • 위키의 문법을 구현하기로 하였는데 직접 파서를 구현하기보다 Markdown의 파서를 사용하면(Markdown 문법을 사용해야 하지만) 편리할 것 같아(명백해서 증명할 필요가 없다!) Markdown 파서중 pegdown을 쓰기로 경정. Java 언어 기반의 파서중 그나마 문서화(GitHub의 소개페이지)가 잘되어있어서....
      • 아무튼 pegdown은 무지무지 쉬웠는데(new Pegdown().markdownToHTML(/* String 콘텐츠 */) 적용하는데까지 시간이 오래걸렸다. 하나 고치면 다른 에러가 나고 에러랑 스무고개했음ㅋㅋ
      • 당시엔 적절한 결정이라 생각했었을 텐데 이제보니 경악?스러운 부분이 있었다. 결정에 대한 이유를 기록해두자.
    • 스무고개
      • 이전에 돌아가던 것이 안돌아가 코드를 보니 테스트를 위한 Mock 객체를 참조하고 있었다. 실제 객체는 구현이 덜 되어있었음. 테스트를 하기 위한 구현을 했었다는 것을 알게되었다. 테스트용 코드가 Mock 객체를 벗어나 실제 객체에도 묻어있었음. 당시엔 확장과 변화를 위해 정한걸 텐데 지금보니 왜 이럴까?
        • 그건 우리가 이 프로젝트(그리고 코드)에 대해 더 잘 알게 되었다는 뜻. 과거의 결점을 발견하는 것은 좋은 신호다.
    • 사소한 결정이라도 결정을 할 때에는 이유를 적어야겠다.
    • 공부할게 많다.
      • 좀 오래한 Spring, Hibernate도 어려움. CGLib, Spring Security, JSP, Session 찾아봐야겠다.
      • 쓰는건 쉽지만 작동을 모른다.
    • 바퀴 다시만들기
      • 오픈소스인 pegdown과 문법 Markdown을 쓰니까 완전 편함
      • 시간도 얼마 안걸렸다. 구현시간이 많이 단축되어서 위키쓰기질 하게됐음.

9월 13일

  • 김수경
  • 서지혜
    • 오늘 가장 성공적이었던 일은 톰캣 서버를 구동시킨 일이다.
      • 감격, 서버가 돌아감!

9월 19일

  • 김수경
  • 서지혜
    • 되서 화나는 일이 많다. 흐음.....
    • 이전 (리비전 9)에서는 jsp 에서 pageContext.getAttribute("page")로 Response의 page를 불러올 수 있었는데 리비전 10부터 pageContext.getRequst().getAttribute()(또는 request.getAttribute)를 해야 page를 불러올 수 있다. 왜지? 모르겠음. 한참헤멤
      • Scope와 관계가 있을 것 같다.
    • Jasper는 JSP를 java로 변환해 실행시키는 엔진인 것 같다.
      • home.jsp는 home_jsp.java로 변환되는 식

9월 20일

  • 김수경
    • login.jsp 를 만들어서 커스터마이징 한 로그인 페이지를 사용할 수 있게 수정했다.
      • 그런데 Remember me가 제대로 동작 안 함.
    • save를 누르면 저장된 내용이 바로 반영되어야하는데 새로고침 해야 반영된다.
  • 서지혜
    • 로그인을 하면 login, signup등이 안보이게 하고 싶다
      • spring security의 tag library의 ifAllGranted, ifNotGranted등을 사용할 수 있다.
    • 로그인이 되어있는지 view단에서 확인하는 기능이 필요하다
    • 페이지를 타이틀로 검색 할 경우 어떻게 페이지 타이틀을 받아서 검색을 한 뒤 결과를 돌려주고, 없는 페이지는 새로 만들 수 있게 할까?
      • 보통 페이지 타이틀은 GET으로 받는듯.
      • url mapping 어떻게 하지?
      • pagdown의 page 링크는 localhost:8080/simplewiki/를 localhost:8080/타이틀로 바꿔버린다.
        • 원래 localhost:8080/로 나오는거 아닌가?
      • ViewResolver? Intercept Handler?
    • 개인 신상 털기하고 놀았음. 다들 덕이라 별로 재미없었다.
    • mac eclipse에서 tomcat 올리고싶은데 caltalina를 못찾는다

9월 27일

  • 김수경
  • 서지혜
    • PageTitle 받아서 검색하는 거 까지되었다!! 알고보니 어렵지 않은 문제였음, PathVariable로 url의 path 요소를 받을 수 있다.
      • 비슷한 기능으로는 getServletPath()

10월 4일

10월 11일

  • 김수경
  • 서지혜
    • Page또는 User 계정 삭제에 대한 고민. Page는 삭제도 History로 남는다. 삭제했다가 같은 이름으로 다시 만들면 history는 남아있음. 그러나 User는 삭제해도 id는 남아서 history에 존재해야하고 같은 id로 다시 만들면 기존 정보 삭제가 필요. 그래서 User의 속성중 id와 다른 정보(password, e-mail등..)를 분리하였다.

11월 01일

  • 김수경
  • 서지혜
    • User가 탈퇴시에도 userId는 남아 있어야 하며 탈퇴한 id로 가입할 수 있어야 하는 이슈 해결을 위해 User에서 userId(String type)와 password,..(UserInfo.class)를 분리하였다.
      • User는 UserInfo를 가진다.( Composite)
      • User안에서 UserInfo는 Nullable Column이지만 이미 존재하는 UserInfo를 삭제할 때는 ForeignKey Contraint로 인해 에러가 발생된다..
      • User와 UserInfo의 포함 관계를 변경하려 했으나 논리적으로 맞지 않아 버림.
      • 회원탈퇴시 UserInfo를 삭제하는 것이 아니라 안의 field들을 null등으로 초기화 하기로 했음... + 탈퇴한 회원인지 flag
      • 더 좋은 방법이 있을지 고민.
    • 간단한 문제인데 (내게) 우아한 해결방법이 없다. 좌절.
    • 본스치킨 양적은데 너무 비싸. 18000원인데 치킨은 두 손바닥 만큼 왔음.

11월 21일

  • 김수경
  • 서지혜
    • Page의 History 보기 기능 설정
      • url "/"에 Page내용 보기와 Page history의 내용 보기 두가지 기능을 매핑하려 했다.
        • 다른 행위(page content view, page history view)를 하지만 더 큰 행위(page view)의 subset이므로 Request주소는 같게 하고 parameter를 달리해 두 행위를 구분하려 했다.
      • 컨트롤러 함수에 인자를 다르게 해서 OverLoading하려 했으나 ResuestMapping이 같아서 Spring이 Ambiguous Mapping Exception을 발생시켰다.
        • RequestMappingHandlerMapping의 매핑 테이블을 보니 { URL , methods= Method 타입 , params=[],headers=[],consumes=[],produces=[],custom=[]}등으로 Request를 구분하고 있었다.
      • @RequestMapping 어노테이션의 설정값들 중에 params를 이용해 파라메터 등록을 할 수 있다. 이렇게 하면 특정 파라메터가 넘어올 때에만 RequestMapping을 할 수 있다.
        • 이를 이용해 RequestMapping의 value값, Method 타입이 같아도 특정 파라메터의 유무로 리퀘스트 핸들링을 달리할 수 있다.
        • 예를들어 @RequestMapping(value = "/helloworld", method = RequestMethod.GET)@RequestMapping(value = "/helloworld", method = RequestMethod.GET, params="param=param")은 다르다. 각각 다른 함수에 mapping될 수 있다.

    • Login하지 않고 Page를 생성할 수 있는 문제
      • FrontPage가 없을 때에는 Login을 하지 않아도 Page create를 할 수 있었다.
        • spring security에서 "/create" url에 authentication을 설정
        • ui에서 Signup하는 부분을 다른 페이지로 추출
        • RequestMapping의 method 타입을 이용해 signup 페이지 호출과 실제 signup을 구분하여 핸들링
          • 이건... 음.. "signup 폼을 담은 페이지를 호출" 할 때와 "사용자의 ID와 PASSWORD를 전달해 로그인 처리를 하는" 경우가 같은 Request Name을 가지게 되서..
      • 이제 로그인되지 않은 사용자가 페이지 생성을 요청하면 Spring Security에 의해 Signup 페이지로 이동된다. 끗

11월 29일

  • 김수경
  • 서지혜
    • 입을 함부로 놀린 죄로 백링크에 대해 고민중. 생각보다 까다로운 주제여서 당황, 위키페이지의 backlink 설명은 너무 부족하구만..
    • linkback은 뭐지?
      • backlink는 자신을 참조하는 링크들에 대한 참조(역참조)이고, linkback은 backlink하는 방법들이군.

12월 6일

  • 김수경
    • Java에서 Matcher를 사용할 때 matches()는 전체가 완전히 일치하는 것만 찾아주고 find()는 substring일 때도 찾아준다. 예를들어 'abcde'에서 'bcd'를 찾을 때 matches를 사용하면 못 찾고 find를 사용하면 찾음.
  • 서지혜
    • backlink 처리 프로토타이핑 중
    • Java의 Matcher 중 find()와 matches()가 패턴매칭과 관련이 있는걸로 알고있는데 찾아서 다시 쓰겠다.

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2012-12-20 19:42:23
Processing time 0.3879 sec