자바스크립트 match 함수를 자바로?

자바스크립트 match 함수는 String에 있는데 정규식에 대응하는 문자열 배열을 리턴해 주는 함수입니다. 매우 편하죠.

http://www.w3schools.com/jsref/jsref_match.asp

그런데 자바에는 그런게 없어요. String 클래스에 비슷해 보이는 메서드가 split이랑 match가 있는데 다 원하던게 아니에요. 자바스크립트 match랑 비슷한걸 만들려면 Patttern이랑 Matcher를 써야하는데… 그 둘을 써도 코드가 간단하질 않아요. 그래서 유틸을 만들었는데.. 자바 String이나 Matcher에 기본으로 들어갔으면 좋겠습니다.

아 귀찮게 이게 뭔짓인지… 제 모든 감정은 gist 제목에 써놨습니다.

테스트도 했어요.

[Servlet 3.0 Asynchronous Support] 비동기 서블릿

쉽지 않다. 일단 배경 자체가 매우 긴데…

http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html

이 글에서 배경을 잘 설명하고 있다.

HTTP 1.0과 HTTP 1.1의 차이점부터 시작해서, Thread per connection을 설명하고, page-by-page 방식에서 커넥션 쓰레드가 지연상태로 있기 마련인지라, JDK 1.4에 추가된 NIO를 사용해서 놀아도 되는 커넥션 쓰레드를 회수하여 새로운 요청을 처리할 용도로 사용하도록 되었다고 한다. 그러다, Ajax의 등장으로 page 당 요청수가 급증하게되고, 그 중에서도 느리고 제한적인 자원에 접근하는 요청일 경우에는 처리용 쓰레드가 대기하는 상황이 자주 발생하게 됐다. 그래서 등장한 것이 바로 Servlet 3.0의 비동기 기능이다. 대기해야 하는 리소스를 요청한 상태에서 처리용 쓰레드를 계속 대기 상태로 유지(동기)하는게 아니라, 처리용 쓰레드는 대기해야 하는 리소스를 요청하고 회수했다가, 리소스가 다시 가용해졌을 때 처리를 이어가게 해주는 것이다. 이렇게되면, 가만히 기다리느라 멍때리고 있던 리소스를 다른 작업 처리하는데 사용할 수 있으니 훨씬 효율적이라서, 잘하면 처리량이 올라갈 수도 있겠다.

결국 DB로 쏠릴것이다. 지금도 성능의 대부분은 DB에서 먹히는 거라고 하지만, 그걸 뭘 어째겠는가. 그 앞에 캐시를 둬서 잘 운영하거나, DB 자체를 좀 더 효율적으로 활용하는 방법을 찾거나, 그건 또 다른 문제니까 논외로 패스.

어쨌거나, 지금까지 배경을 살펴보면 대충 이런것 같다.

  • 일단 두 종류의 자원이 있다. 하나는 커넥션용. 하나는 처리용.
  • 커넥션용 자원은 이미 여러 서블릿 컨테이너가 NIO를 사용해서 효율적으로 작업해 뒀기 때문에 개발자가 신경쓰지 않아도 됨. – “Today, popular Web servers — including Tomcat, Jetty, GlassFish (Grizzly), WebLogic, and WebSphere — all use thread per request through Java NIO.”
  • 처리용 쓰레드는 DB 요청이나, 웹 서비스 요청을 했을 때 대기하게 되는데, 이건 서블릿 3.0의 비동기 기능을 활용해서 절약할 방법이 생김. (어느정도 효과가 있을지는 모르겠음.)

하지만, 이 글에서 보여주는 예제는 ServletContextListener와 조합하고 있는데, 그리 깔끔해 보이는 예제는 아니었다.

http://blogs.oracle.com/enterprisetechtips/entry/asynchronous_support_in_servlet_3

다음으로 읽은 글인데, 비교적 깔끔한 예제와 설명을 제공한다. 그런데 저기 있는 예제 코드처럼 요청이 올때마다 new ThreadPoolExecutor(10)를 생성하는 건 매우 위험해보이고, 쓰레드 풀을 스프링에 빈으로 등록해두고 쓰는게 좋겠다. 스프링 @Async 기능 관련해서 무슨 클래스 이름이 있었는데 잊어버렸다. @_@; 머더라.. 뭔 Factory였는데.. 또 패스.

그치만 저 글로는 AsyncContext, AsyncListener의 주요 기능을 파악하기는 어려웠다. API를 읽어본다고 크게 도움이 되지도 않고, 언제 이 메서드를 사용해야 하는 것인지 알아야 할텐데..

http://jcp.org/en/jsr/detail?id=315

그래서 스펙을 열어봤다. 스펙 문서는 서블릿의 모든것이 설명되어 있는 필독 문서인데, 난 아직 전부다 읽어본적은 없다. 이번 기회에 한번 다 읽어볼까 싶기도 하고… 어쨋든 이 문서에서 비동기 관련 내용이 잘 설명되어 있다. 2.3.3.3을 보면 된다. 사실 나도 아직 다 읽은건 아니라서.. @_@ 일단 링크 정리하면서 요약하려고 적기 시작한거라. 나중에 레퍼런스를 요약해서 정리해야겠다. 서블릿 3.0 부셔버리겠어!!

http://weblogs.java.net/blog/mode/servlet3.0/servlet3.0-javaone09.pdf

마지막으로 전체적으로 훑어보기 좋은 PDF 문서가 있다. 여기 그림과 코드가 주옥같다. 발표 영상도 구할 수 있으면 좋겠지만, 귀찮아서 찾아보진 않았다.

예제를 하나 만들어 보고 슬슬 자야겠다. 벌써 12시 30분을 향해가는구나. 간단한 웹 서비스 요청을 한다고 가정해보자. 야후 주식 API를 호출해서 여러 주가 정보를 받아와야 한다고 가정해보자.

여기서 사용한 야후 주시 정보는 스프링 RestTemplate응 이용했다.

이렇게 짜봤는데… 흠.. 뭔가 좀… 응답이 한방에 오는게 어째 좀 찝찝하다. 응답이 조각 조각 와야 하는거 아닌가. 크롬 인스펙터로 보면 응답 Transper-Encoding: chuncked 이긴한데.. 내가 원한건, Start가 먼저 응답으로 오고, 그 다음에 주식 정보가 다시 응답 조각으로 와서 완료되는 것인데.. 흠.. 디스패치를 이용해야되나.. 아. 찝찝한데 시간은 벌써 1시 반이 넘었고… 자야겠다. 젠장.. OTL…

서블릿 레퍼런스랑 자바 컨커런시 프로그래밍 좀 잘 봐야겠다.

출근길에 Dispatch를 사용하도록 코드를 변경해봤다.

이번에도 내가 원하는대로 되진 않았다. 일단 브라우저에는 Start만 보내고, 그 다음 리모트 호출이 완료된 다음 주가 정보를 출력하는 것이 내가 원하는 결과였는데.. 흠.. 화면단에서 자바스크립트로 코딩이 들어가야 하는걸까? 화면단 코딩을 하지 않더라도, 적어도 크롭 인스펙터에 두줄로 나와야 하는거 아닐까나.. 흠;; 모르겠군;

[Servlet 3.0 @WebServlet]스프링 DispatcherServlet을 서블릿 3.0 @WebServlet으로 올려볼까?

서블릿 3.0에 web.xml없이 애노테이션만 추가하면 서블릿으로 자동 등록되는 기능이 생겼다.

http://www.servletworld.com/servlet-tutorials/servlet3/webservlet-annotation-example.html

자세한 내용은 여기 있고..

우선, pom.xml에 의존성을 추가해야한다.

이렇게 두개가 필요하고, 이런류의 의존성은 보통 provided 스코프로 사용하게 좋은 습관이다. 왜그런지는 생략;

이렇게 간단하게 자바 코드만 추가하고, web.xml을 전혀 만들지 않아도, 브라우저에서 /test를 요청하면 Hello를 볼 수 있다.

난 사실 처음에 스프링 3.1에서 서블릿 3.0을 지원한다길래 이런 모습을 상상했었다.

서블릿 3.0부터는 web.xml을 사용할 필요가 없고, DisaptcherServlet도 HttpServlet을 (매우 깊게) 상속해서 만든 클래스니까 이런식으로 등록할 수 있지 않을까? 싶었다.

해보니까 잘 된다.

그래도 저렇게 쓰진 않겠지;;; ㅋ

[GAE 시리즈] 2. 구글 로그인

http://code.google.com/intl/ko-KR/appengine/docs/java/gettingstarted/usingusers.html

        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        if(user != null) {
            resp.setContentType(“text/plain”);
            resp.getWriter().println(“Hello, ” + user.getNickname());
        } else {
            resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
        }
이 코드가 핵심인데.. 많은 것들을 해준다.
1. 우선 무척이나 간단하다. 이렇게 쉽게 구글 로그인을 연동할 수 있다니… API도 직관적이라 어떤 일을 하는지 쉽게 알 수 있다. 마지막 줄의 코드가 로그인 한 다음 바로 로그인을 요청한 페이지로 이동하기 위한 API 인데 흠.. 괜찮은 것 같다. 권한 관리는 어떻게 하는지..  실제론 스프링 시큐리티랑 연동해서 쓰는지 아님 구글에서 제공하는 인증/권한 관리 API가 있는 것인지.. 있다면 권한 관리 설정은 편리한지 궁금하다.
2. 로그인 화면 자동생성. 로그인이 필요할 때 guestbook 예제에서 봤던 로그인 화면이 등장하는데 나는 그런 JSP 파일을 만든적도 없는데 알아서 만들어줬다. 편리하다.
3. 간편할 뿐 아니라 이 코드는 개발 환경과 배포 환경에 따라 동작 방식이 바뀐다. 오.. 놀라워라; 즉 개발환경에서는 아무런 아이디만 넣어도 로그인이 되고, 관리로 로그인하기 체크 박스가 존재한다. 하지만 GAE에 배포하는 순간 실제 구글 계정으로 로그인 한단다. 아직 GAE에 배포는 안해봤다. 그런데.. 개발할 때 실제 구글 계정으로 테스트해보고 싶으면 어쩌지?? 
4. 로그아웃 URL로 제공한다. userService.createLogoutURL()을 사용하면 된다.