아...저번 회 때에는 박재성씨가 준비한 세미나를 들어서 그 때에는 스프링에 관한 것 보다 그냥 협업프로세스를 도울 만한 유용한 프로그램이나 작업 방법을 소개하는 자리였습니다. 그래서 스프링에 관해서는 많이 듣지 못했는데요.

오늘 세미나는 우선 2가지 세션을 못들은 것이 좀 아쉽구요. 그래도 백기선씨의 Spring AOP가 도움이 많이 되었구요. 박찬욱씨의 그 괴물같이 손이 보이지 않을 정도로 하는 라이브로 코딩하는 실력을 보면서 감탄사를 내뱉느라 제대로 못 듣기는 했지만, 꽤나 유용한 시간이였습니다. 그리고 스프링 보안인 Spring Security에 관한 설명도 들었는데....마침 이 시간이 졸려서-_- 잤습니다(발표자님께는 죄송하지만ㅠ)

우선 11시에 도착을 했는데, 20분부터 한다고 공지가 되어있더라구요.

1. 박찬욱님의 Refactoring JDBC Programming
우선 기존 JDBC를 접근하는 방식을 스프링 jdbc templete을 라이브로-_-; 만들어 보는 과정을 보게 되었습니다. 이건 뭐 감탄사밖에 안 나오는 군요. 이런 것을 한번도 보지 못한 저로썬 그냥 놀랄 따름입니다-_-; 보통 이클립스의 리펙토리 기능은 잘 쓰기 힘든데, 저걸 저렇게 활용하는 사람도 있구나 라는 생각이 드는군요 ^^
기존에 JDBC는 Try Catch Finally Try Catch의 반복으로 이루어져있죠. 그래서 그걸 템플릿으로 만들어서 중복코드에 대한 제거를 하고, 바뀌는 부분만 비교해서 잘 보여주셔서 이해가 매우 빨랐습니다. (하지만....휙휙~지나가는 화면들..OTL...)
사실 기존에 DB연동 부분은 그냥 항상 사용하기만 해서 내부 구조를 볼 겨를이 없었거든요. 실제 구현체를 보니 신기할 따름이군요. 그냥 queryForObject, queryForList, update, delete, insert 등의 메소드를 가져다가 쓰기만 했지, 어떻게 돌아가는지 몰랐는데, 이제 보니 확실히는 아니지만, 어느정도 알겠네요. 인터페이스를 활용하여 Strategy패턴을 이용해서 하는 것이더군요. 이제부터 디자인패턴을 공부해야겠다는 생각이 좀 드네요-_-; 사실 Head First Design Patterns책이 있는데...왠지 펼치기 싫습니다만, 이제 펼쳐야겠습니다 ㅠ
아....그리고, 저도 이클립스 단축키를 좀 외워야겠습니다-_-; 저도 이제부터 간지코딩을...-_-;

2. 박현준님의 Spring Security
헉.....순간 졸다가 기절했습니다-_-; Spring Security를 사용 안해봐서 인지 모르겠지만, 내용도 너무 어렵고ㅠ 졸리고 해서....ㅠ 자다가 일어나니 그 데모를 좀 보여줬는데, 대충 내용을 보니, 그....로그인 프로세스를 데모로 보여준 것 같습니다. 인증을 한 페이지를 보여주고 막 그랬던 것 같은데.....사실 잘 모르겠군요 ㅠ
얼마전 OAuth를 공부한 적이 있었는데, Spring Security에서도 지원을 한다고 한 것이 생각나는군요. 갑자기 얘기가 또 새네-_-; 암튼 보안쪽도 공부를 해봐야겠습니다 ㅠㅠ

3. 백기선님의 Spring AOP
우선 AOP에 대한 개념을 쉽게 설명해주어서 좋았구요. 하지만, 제 친구는 AOP에 대한 개념을 처음 접하는데, 용어가 너무 어렵다고 하더군요. 저도 친구들이랑 AOP스터디를 했을 때 advice, advisor, pointcut, joinpoint 등의 용어가 처음에는 헷깔렸는데, 그런 용어를 통해 친구가 그냥 처음에 들으려니까 어려운 부분이 있었나 봅니다. 암튼, AOP에 대한 EMAIL예제를 보여주시고, 1.X대 방식, 2.0.X방식, 2.5방식(어노테이션)을 보여주시고 ^^ 예전에 최범균님의 스프링2.5프로그래밍이라는 책에서 나온 예제가 있는데, 그것이 생각나더군요. 거기에서도 다 나와있었어요. 1.X대 방식은 어떤 인터페이스를 구현하는 것으로 나오고 ^^ 2.0.X는 POJO로 하고, XML설정파일에서 포인트컷을 정의를 해주는 방식이죠. 2.5의 어노테이션은 마법이죠 ^^
아...그리고 신기했던 것이 저도 @AspectJ 붙이면 컴포넌트 스캔이 안되는데, 그걸 포함시킬 수 있더군요.
저는 그냥
[code]<bean class="~~~~.AnnotMyAop" />[/code]그냥 선언해줬는데-_-; 컴포넌트 스캔에 AspectJ클래스를 넣으면 되는군요.
그리고, Spring AOP와 AspectJ를 비교하셨는데, 역시 AspectJ는 안써봐서 모르겠군요-_-;
또 하이버네이트는 제가 안해봐서 몰르겠는데, 이거 db를 객체랑 매핑해주는 거로 알고 있는데, add를 하면 insert를 하는건데, 이거 지가 필요하면 하는 거군요. 그래서 jdbctemplete이랑 같이 쓰면 데이터를 가져오면 insert가 안되서 문제가 발생하는데, 이걸 AOP로 해결할 수 있더군요. AOP를 예전에 회사에 적용해보려고 하다가 실패를 했던 기억이 있어서-_-; 다시 한번 해봐야겠습니다-_-;

근데, 이번 세미나를 마지막으로 무료세미나를 마친다고 한 것 같더라구요. 이제 돈내고 들어야하는건가....
암튼, 어느 정도 좋은 정보를 얻을 수 있었고, 도움이 많이 되었습니다. 스프링에 대해서 공부를 안한지 쫌 됐는데, 다시 한번 되새기게 만들어주네요. 우선 @MVC관련된 강의를 듣지 못해서 좀 아쉽구요. 저도 열심히 공부를 해야겠다는 생각이 드는군요.

이런 모임이 자주 있어서 좋은 정보를 공유했으면 하는데, 아직도 스프링 자료는 외국에서 많이 찾아야해요 ㅠ


 
Posted by 머드초보
,
 
우선 smtp를 지원하는 메일서비스만 할 수 있습니다.
naver는 지원하긴 하지만, 조낸 써야지 smtp를 사용할 수 있습니다.
저는 일반사용자인데 으뜸사용자가 되야하는 듯 합니다.
그래서 그냥 지원해주는 gmail이랑 daum메일로 테스트를 해봤습니다. 잘 되는군요.

기존에 25포트가 디폴트로 메일을 사용했는데 보안 때문에 SSL을 사용하고, smtps라는 프로토콜로 465번포트로 하는군요.
이건 좀 더 공부를 해봐야할 듯 싶네요. 그냥 기존의 ssl을 사용하지 않는 메일은 host랑 id랑 password만 지정해주면 돼요.

우선 설정파일입니다.
applicationContext.xml
[code]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
      http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-2.5.xsd">
    
    <context:component-scan base-package="mailtest" />
   
    <!-- 일반용 
    <bean id="mailSender"
        class="org.springframework.mail.javamail.JavaMailSenderImpl"
        p:host="STMP서버주소"
        p:username="아이디"
        p:password="비밀번호" />
    -->
   
    <!-- gmail, hanmail 용 -->
    <bean id="mailSender"
        class="org.springframework.mail.javamail.JavaMailSenderImpl"
        p:host="한메일: pop.hanmail.net, 지메일:smtp.gmail.com"
        p:port="465"
        p:protocol="smtps"
        p:username="아이디"
        p:password="비밀번호">
        <property name="javaMailProperties">
            <props>
                <prop key="mail.smtps.auth">true</prop>
                <prop key="mail.smtps.startls.enable">true</prop>
                <prop key="mail.smtps.debug">true</prop>
            </props>
        </property>
    </bean>
   
    <bean id="templateMessage"
        class="org.springframework.mail.SimpleMailMessage"
        p:from="송신자 주소"
        p:to="수신자 주소"
        p:subject="안녕!" />
   
</beans>
[/code]
templateMessage는 임시로 메세지를 지정해주는 것으로 미리 지정할 껀 지정하는 겁니다.
물론, 나중에 java코드에서 수정이 가능합니다.

서비스부분입니다.
MailTestService.java
[code]
package mailtest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;

@Service
public class MailTestService
{
    @Autowired
    private MailSender mailSender;
   
    @Autowired
    private SimpleMailMessage simpleMailMessage;
   
    public void sendEmail()
    {
        SimpleMailMessage msg = new SimpleMailMessage(this.simpleMailMessage);
        msg.setText("난 종천이라고해!");
        this.mailSender.send(msg);
    }
}
[/code]
저기서 simpleMailMessage를 받아와서 text만 설정해줍니다. 저기서 msg.setTo하면 수신자도 설정할 수 있죠. 그리고 그냥 send메소드만 호출해주면 메일이 전송됩니다.

[code]
package mailtest;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MailTest
{
    public static void main(String[] args)
    {
        String configLocation = "applicationContext.xml";
        ApplicationContext context =
            new ClassPathXmlApplicationContext(configLocation);
       
        MailTestService mailTestService =
            (MailTestService) context.getBean("mailTestService");
       
        mailTestService.sendEmail();
    }
}
[/code]
더욱 심화된 기능은 reference를 참조하세요
http://static.springframework.org/spring/docs/2.5.x/reference/mail.html
 
Posted by 머드초보
,
 

넷빈즈는 초보자들이 쉽게 적응할 수 있도록 QuickStart를 제공합니다.
일종의 튜토리얼 같은 건데 참 잘 되어 있습니다.
스프링프레임워크에 관해서도 QuickStart가 있는데 어노테이션을 사용해서 더욱 쉽게 접근할 수 있도록 바꿔봤습니다.

http://www.netbeans.org/kb/61/web/quickstart-webapps-spring.html
요게 원문입니다. 영어지만, 그냥 코드만 보고 따라하셔도 스프링의 기초를 이해하실 수 있을껍니다.
이 예제를 조금 변경해봤습니다. 어노테이션을 이용한 HelloSpring으로-_-;(똑같이 하면 왠지 안될것같아서-_-)

우선 NetBeans6.1, JDK 5 or 6, GlassFish or Tomcat이 필요해요.

우선 처음에 프로젝트를 만듭니다.
New Project(Ctrl-Shift-N)을 선택해서 Web -> Web Application을 선택합니다.

프로젝트이름은 HelloSpring이라고 하고, Steps 4단계에서 Spring Web MVC 2.5를 선택하세요.
그리고 Finish를 클릭하세요.

그리고 F6을 누르면 GlassFish가 실행이 되고, 웹페이지가 뜨면서 아래와 같은 화면이 나올껍니다.

사용자 삽입 이미지


저 페이지는 index.jsp파일인데요. web.xml파일에 보면 welcome-file이 redirect.jsp로 되어있습니다. redirect.jsp파일을 열어보게 되면, index.htm을 요청하게 되어있습니다.
또 web.xml에서 servlet태그를 보면 *.htm요청으로 들어오는 놈들은 DispatcherServlet으로 넘기게 되어있습니다.
이 놈은 서블릿이름-servlet.xml파일을 설정파일을 사용합니다.
그러면 dispatcher-servlet.xml파일을 보게 되면, urlMapping이라는 bean이 있는데, 이 놈에서 mappings를 보면 index.htm이 요청일 경우 indexController를 실행하게 되어있습니다.
indexController는 아래에 bean으로 정의가 되어있죠.
indexController는 ParameterizableViewController클래스인데 이 클래스는 p:viewName값이 index인 것을 보여주는것이죠. index는 viewResolver bean에 의해서 /WEB-INF/jsp/index.jsp파일이죠.
그래서 index.jsp파일이 보여지는 것이죠.

초간단 설명을 마치고-_-; 폼에다가 이름을 입력하고, 전송하면 "Hello 이름!"을 리턴하는 프로그램을 만들어봅시다.

설정파일을 조금 변경해야합니다.
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
요런 bean이 있는데, 이건 Controller의 클래스명으로 url매핑을 하는 겁니다. 즉 HelloController로 선언을 시켰으면 hello.htm요청으로 해당 컨트롤러를 호출할 수 있게 하는겁니다.
근데 이건 어노테이션을 사용하면 안 먹힙니다-_-; 걍 지워버립시다.
그리고, beans에 xmlns:context="http://www.springframework.org/schema/context"를 추가합니다.
그리고, xsi:schemaLocation에도
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
이렇게 추가합니다. 이는 <context: 를 사용하기 위함입니다.
그리고, 이 아래에 이걸 추가합니다.
<context:component-scan base-package="hellospring" />
이건 객체를 스캔하는 건데 @Service, @Controller, @Component 등의 어노테이션이 base--package아래있는 클래스들 전부 적용하게 합니다. 빈이름은 클래스명에 따라서 정해집니다. 예를 들어 HelloController이면 helloController라고 자동으로 등록됩니다.
그리고, urlMapping bean에다가 우리가 만들 HelloController를 등록합니다.
<prop key="/hello.htm">helloController</prop> 이렇게 한줄을 추가하면 됩니다.
바뀐 dispatcher-servlet.xml 파일입니다.
[code]<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd">
   
    <context:component-scan base-package="hellospring" />
   
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/index.htm">indexController</prop>
                <prop key="/hello.htm">helloController</prop>
            </props>
        </property>
    </bean>
   
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />
   
    <bean name="indexController"
          class="org.springframework.web.servlet.mvc.ParameterizableViewController"
          p:viewName="index" />
   
</beans>
[/code]

우선 Service를 만들어봅시다.
Source Package에 오른쪽 버튼을 클릭하고, New -> Java Class를 선택합시다.
Class Name에는 HelloService라고 하고, Package에다가 hellospring.service라고 합시다.
[code]package hellospring.service;

@Service
public class HelloService {

    public String sayHello(String name) {
        return "Hello " + name + "!";
    }
}
[/code]
초간단 메소드입니다. name을 넣으면 Hello name! 을 리턴하게 하는 서비스입니다.

그 전에 폼으로 부터 데이터를 가져오는 bean을 하나 만들어봅시다.
Source Package에 오른쪽 버튼을 클릭하고, New -> Java Class를 선택합시다.
Class Name에는 Name이라고 하고, Package에다가 hellospring.domain라고 합시다.
[code]package hellospring.domain;

public class Name {
   
    private String value;
}
[/code]
여기서 getter, setter만드는 방법이 2가지가 있어요.

첫번째 방법은 Alt + Insert키를 누르면 Getter and Setter를 선택하면 해당 멤버변수에 대해서 나오는데 체크를 하고 Generate하면 됩니다.
두번째 방법은 소스에디터의 value에다가 마우스 오른쪽버튼을 클릭하고, Refactor -> Encapsulate선택하면 얘는 좀 더 상세하게 설정할 수 있습니다. 접근자를 수정할 수 있어요.
getter, setter가 완성이 되었습니다.

그 다음은 컨트롤러를 만들어봅시다.
Source Package에 오른쪽 버튼을 클릭하고, New -> Java Class를 선택합시다.
Class Name에는 HelloController라고 하고, Package에다가 hellospring.controller라고 합시다.
[code]@Controller
public class HelloController {

    @Autowired
    private HelloService helloService;
   
    private String formView = "nameView";
    private String successView = "helloView";
   
    @RequestMapping(method = RequestMethod.GET)
    public String hello() {
        return formView;
    }
   
    @RequestMapping(method = RequestMethod.POST)
    public String onSubmit(Name name, ModelMap model) {
        model.addAttribute("helloMessage", helloService.sayHello(name.getValue()));
        return successView;
    }
}
[/code]
여기서 보면 HelloService는 @Service라는 어노테이션을 사용해서 객체스캔으로 helloService라는 bean이름으로 등록이 되어있습니다. 그래서 @Autowired해버리면 helloService랑 자동으로 연결이 되죠.
그래서 helloService를 사용할 수 있습니다.

여기서 신기한 점은 @RequestMapping어노테이션이 있는데, GET방식이면 hello메소드를 호출하라는 겁니다.
그래서 처음에 form action을 하지 않은 상태에서는 hello메소드가 호출이 됩니다.
Controller어노테이션의 신기한점은 메소드의 리턴값이 String인데 이 값이 view이름이 됩니다.
formView는 nameView라고 적어놨는데, 이것은 viewResolver에 의해 nameView.jsp파일을 호출하게 됩니다.

더욱 신기한 점은 onSubmit메소드입니다. 값을 받아서 알아서 맞는 곳에다가 넣는 것 같습니다.
그리고 view에다가 값을 던져줄 때는 ModepMap이라는 클래스로 메소드파라메터에 넣고, 여기에 addAttribute를 해서 helloMessage값을 넣으면 됩니다.

이제 View를 만들어봅시다.
Web Page -> WEB-INF -> jsp를 선택하고 오른쪽 버튼 클릭, New해서 jsp선택.
formView이름을 nameView로 지었기 때문에 JSP File Name에 nameView라고 합니다.
[code]<body>
        <h2>Enter your name</h2>
        <form action="hello.htm" method="post">
            Name:
            <input type="text" name="value" />
            <input type="submit" value="OK" />
        </form>
    </body>
[/code]
action에서 hello.htm을 요청하는데 input필드는 한개입니다. 이름은 value입니다.
근데 신기하게도 우리가 만든 Controller를 보면 onSubmit에서 파라메터로 Name클래스로 받는 곳이 있습니다. 여기에 value멤버변수가 있는데 이름을 똑같이하면 그냥 Name클래스의 value값에 들어가버립니다-_-;

그럼 successView를 생성해봅시다.
Web Page -> WEB-INF -> jsp를 선택하고 오른쪽 버튼 클릭, New해서 jsp선택.
successView는 "helloView"라고 했기때문에 helloView라고 합니다.
[code]<h2>${helloMessage}</h2>
[/code]
라고 합니다. onSubmit메소드에서 넘겨주는 helloMessage값입니다.

그럼 이제 실행을 해봅시다.
http://localhost:8080/HelloSpring/hello.htm 라고 요청을 해봅시다.
그러면 Enter your name에다가 이름을 입력합시다.
이름이 나올껍니다.

사용자 삽입 이미지
사용자 삽입 이미지

아....자꾸 딴짓하네-_-; 일해야하는데-_-;

 
Posted by 머드초보
,
 

사용법은 초간단합니다.
주로 성능 측정할 때 사용될 것이라고 생각되는데요.

예전에 "자바 성능을 결정짓는 코딩습관과 튜닝이야기"라는 책에서도 StopWatch클래스가 나오는데요. 왠지 이놈이 저놈인 것 같네요.

어쨌든 사용법은 간단합니다.

[code]
StopWatch stopWatch = new StopWatch();
stopWatch.start();

// 처리할 내용~~~

stopWatch.stop();
System.out.println("걸린시간 : " + stopWatch.getTotalTimeMillis());
[/code]
이렇게 하면 저 사이에 처리하는데 걸리는 시간이 나옵니다.

 
Posted by 머드초보
,
 

저는 이클립스보다 넷빈즈를 더 좋아합니다-_-;
그 이유는 간단합니다. 이클립스는 IBM에서 지원하고, 넷빈즈는 SUN에서 지원합니다.
저는 IBM을 싫어합니다-_-; 미친 현대차 DB2가 말썽을 일으켜서-_-; 그래서 넷빈즈가 더 좋아요-_-;

회사에서 C를 주로 하는데 넷빈즈에서 C도 잘 돼서 그걸 이용해서 테스트를 하고 있어요 ^^
이클립스는 플러그인으로 C를 설치해야하는데 넷빈즈는 올인원을 제공해요.
게다가 Ruby도 지원하고, EJB, Struts, SOA, UML도 되네-_-; Swing도 마우스로 그릴 수 있는 인터페이스를 제공하고, 최근에는 php까지 지원하는 걸로 알고 있는데...
아....프로파일링인가? 그런 것도 되가지고, 그 성능체크같은 것을 할 수 있어요. 메모리가 얼마나 잡아먹고 뭐 그런거요 ^^ 무료툴 치고는 미친듯이 좋습니다.
또 좋은 것은 tutorial과 충분한 sample을 제공하죠. 그래서 좋긴 한데....
가장 중요한 것은 아직 스프링을 하기에는 이클립스가 더 좋은 것 같습니다-_-;

이번 6.1에서 springframework MVC를 지원하게 되었는데요. beans을 정의하는 xml을 validate를 해주는 것 같군요. class라고 하면 정의한 클래스명이 나오는군요. 하지만, 이클립스 플러그인으로 있는 Spring IDE보다는 좀 안좋아요. Spring IDE는 aop도 체크해주고, 그래프로도 자동으로 그려주는 기능이 있죠 ^^ Validate기능은 말할 것도 없구요 ^^ 그래서 넷빈즈에서 이정도로 지원하는 걸보니 스프링이 대세인가봅니다.

이번에 우리회사에서도 스프링으로 프레임워크를 바꿔서 시도해보고 있던데-_-;

뭐어쨌든, 넷빈즈는 계속 진화하는 모양입니다. 최근 진행하고 있는 듯한 자바원이라는 행사에서도 sun에서 넷빈즈를 그렇게 홍보를 했다죠. 어쨌든 더 진화했으면 좋겠네요 ^^

사용자 삽입 이미지

 
Posted by 머드초보
,