오늘도 삽질삽질을 하다가 드디어-_-;
저도 테스트라는 것을 하게 되었습니다.

우선 Junit4를 스프링에서 하기 위해서는 spring-framework-2.5.1.zip파일에서 lib/junit 폴더에 있는 junit-4.4.jar파일을 lib에 추가합니다.
참고로 이클립스에서 있는 놈은 4.3인데 최신버전을 좋아하는 저로썬 그냥 4.4를 /WEB-INF/lib에 추가해서 써요. 이거 이렇게 추가안하고 이클립스에서 제공하는 junit을 사용하면 뭐 이상한 워닝이 떠요-_-;
원래 기존에는 프로젝트의 properties에 Java Build Path에서 Libraries에서 Add Library에서 junit을 추가하는 식으로 했는데 이렇게 하면 워닝막 뜨던데-_-;

Classpath entry org.eclipse.jdt.junit.JUNIT_CONTAINER/4 will not be exported or published. Runtime ClassNotFoundExceptions may result. 

이런거 ^^ 아마 무슨 실행할 때에 클래스가 없다고 뜰 것 같다고 말하는 것 같아요-_-;
저렇게 하지말고 그냥 lib에다가 처박아넣으니 그냥 워닝도 안 뜨더라구요.

뭐어쨌든 테스트클래스를 만들어봅시다.

Project에다가 대고 New -> Source Folder 를 클릭해서 test라는 소스폴더를 만듭시다.
그리고 원하는 테스트를 만들고 싶은 클래스에 대고 오른쪽마우스를 클릭하고
New -> Other -> JUnit Test Case선택
맨위에 source folder만 프로젝트명/src를 /test로 바꿔주고 넥스트를 클릭합시다.
원하는 메소드를 선택할 수 있는데 원하는 메소드를 선택합시다.
그럼 이렇게 작성이 되네요.
[code]
@Test
 public void testUserDeptSearch() {
  fail("Not yet implemented");
 }
[/code]
코드를 작성해봅시다.
[code]
package com.mudchobo.searchbatch.service;

import static org.junit.Assert.assertTrue;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.mudchobo.searchbatch.dao.UsersDao;
import com.mudchobo.searchbatch.domain.Users;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
  "file:WebContent/WEB-INF/applicationContext.xml",
  "file:WebContent/WEB-INF/applicationContext-ibatis.xml" })
@TransactionConfiguration(transactionManager = "transactionManager",
       defaultRollback = true)
@Transactional
public class UsersManagerImplTest {

 @Autowired
 private UsersDao usersDao;
 
 @Test
 public void testUserDeptSearch() {
  System.out.println("UserDeptSearch");
  String dept = "김치";
  List<Users> usersList = usersDao.searchUsersDept(dept);
  Users users = usersList.get(0);
  System.out.println(users.getDept());
  assertTrue(users.getDept() != null);
 }
}
[/code]
저렇게 RunWith를 사용하면 되는 듯.
그리고 applicationContext파일은 여러개 일 때에는 저렇게 설정하면 돼요.
여기서 또 주의할 점은!
applicationContext.xml파일에 properties파일, sqlMapConfig.xml파일 같은 것을 표시할 때
보통 /WEB-INF/~~ 경로에다가 두시는 경우가 많은데요.
저기다가 두고,
[code]
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
  p:location="WEB-INF/jdbc.properties" />
[/code]
이렇게 작성해버리면 이 JUnit4는 저 jdbc.properties파일을 못찾습니다.
class path resource [WEB-INF/jdbc.properties] cannot be opened because it does not exist
이딴식으로 뜨는데요.
그래서 저런 파일들은 classpath인 classes폴더 아래에다가 두면 됩니다.
그냥 src폴더에 package하나 만들어서 설정파일은 다 때려박으세요-_-;
jdbc.properties, SqlMapConfig.xml파일 같은 것은(즉 applicationContext.xml파일에 써진 파일경로 같은거) classes경로 아래에 두도록 합시다. 그런다음에 파일경로 적는 부분에다가는
classpath:<package명>/SqlMapConfig.xml 이렇게 쓰면 돼요^^
그러면 JUnit도 잘 찾아요 ^^

실행할 때는 테스트자바파일에 대고 오른쪽버튼 누르면 JUnit Test가 나와요~

 
Posted by 머드초보
,
 

Controller를 만들어봅시다.
우선 com.phpschool.guestbook.controller 패키지를 만듭시다.
New -> Java Class를 선택해서 ListController클래스를 만듭시다.

이 ListController는 Controller라는 인터페이스를 상속받습니다.
Controller는 org.springframework.web.servlet.mvc.Controller를 선택합시다.





ListController.java
[code]package com.phpschool.guestbook.controller;

import com.phpschool.guestbook.service.GuestbookManager;
import com.phpschool.guestbook.vo.GuestbookVo;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class ListController implements Controller {

    private GuestbookManager guestbookManager;

    public void setGuestbookManager(GuestbookManager guestbookManager) {
        this.guestbookManager = guestbookManager;
    }

    public ModelAndView handleRequest
      (HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
        List<GuestbookVo> contentslist = guestbookManager.getContents();

        return new ModelAndView("list", "contentslist", contentslist);
    }
}[/code]
Manager를 멤버변수로 선언하고 setter를 만듭시다. Manager를 통해 db에서 데이터를 가져와서 ModelAndView를 리턴하는데 contentslist라는 객체를 list.jsp로 넘겨주게 됩니다.

이제 서블릿에 해당요청이 들어올 때 처리하는 부분을 추가해봅시다.
dispatcher-servlet.xml파일을 열어봅시다.
[code]
<props>
<prop key="/index.htm">indexController</prop>
    <prop key="/list.htm">listController</prop>
</props>[/code]
list.htm 요청을 추가하고 저 요청이 들어오면 listController라는 컨트롤러에게 넘겨준다는 얘기입니다.
listController부분을 추가해줍시다.
[code]   
<bean name="listController"
          class="com.phpschool.guestbook.controller.ListController">
        <property name="guestbookManager" ref="guestbookManager" />
</bean>
[/code]
listController는 좀전에 구현한 ListController클래스입니다.

이제 jsp부분을 보도록 합시다.

index.jsp
[code]<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/jsp/taglibs.jsp" %>
<%@ include file="/WEB-INF/jsp/header.jsp" %>

<h5><a href="list.htm">스프링 + iBATIS 예제</a></h5>

<%@ include file="/WEB-INF/jsp/footer.jsp" %>
[/code]
상단에 UTF-8페이지임을 추가하고 중간에 list.htm을 요청하는 링크를 추가합니다.

list.jsp
[code]<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/jsp/taglibs.jsp" %>
<%@ include file="/WEB-INF/jsp/header.jsp" %>

<c:forEach var="contentslist" items="${contentslist}">
    <div>
        <p>이름 : ${contentslist.name}</p>
        <p>제목 : ${contentslist.subject}</p>
        <p>내용 : ${contentslist.content}</p>
        <p>아이피 : ${contentslist.ip}</p>
        <p>날짜 : ${contentslist.datetime}</p>
    </div>
    <hr />
</c:forEach>

<%@ include file="/WEB-INF/jsp/footer.jsp" %>[/code]
jstl문법을 이용해서 해당 객체를 출력하면 됩니다.
결과를 보도록 합시다.

사용자 삽입 이미지

음.....잘 나오네요.....-_-; 저걸 보려고 저렇게 많은 코드를.....-_-;
 
Posted by 머드초보
,
 

이제 db부분을 만들어봅시다.
Source Packages에서 New -> Java Packages해서 com.phpschool.guestbook.db를 추가합시다.
New -> Other해서 Java -> Java Interface를 선택하고 GuestbookDao라는 Interface를 추가합시다.








GuestbookDao.java
[code]package com.phpschool.guestbook.db;

import com.phpschool.guestbook.vo.GuestbookVo;
import java.util.List;

public interface GuestbookDao {

    public List<GuestbookVo> getContents();
}[/code]

이 인터페이스를 구현해봅시다.
db Package에 New -> Java Class를 선택하고 GuestbookDaoImpl 클래스를 추가합시다.

GuestbookDaoImpl.java
[code]package com.phpschool.guestbook.db;

import com.phpschool.guestbook.vo.GuestbookVo;
import java.util.List;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class GuestbookDaoImpl extends SqlMapClientDaoSupport
                 implements GuestbookDao {

    @SuppressWarnings("unchecked")
    @Override
    public List<GuestbookVo> getContents() {
        return (List<GuestbookVo>)
             getSqlMapClientTemplate().queryForList("getContents");
    }
}[/code]
우선 SqlMapClientDaoSupport클래스를 상속받습니다. 이게 sqlMapClient를 가져오게 하는 것 같습니다. getSqlMapClientTemplate()라는 메소드로 sqlMapClient를 가져오는군요. 이걸로 이제 queryForList메소드를 호출해서 getContents라는 sql을 실행합니다.
그럼 SQL작성을 하는 MYSQLGuestbook.xml파일을 생성해봅시다.
db Package에 new -> xml Document를 선택하고, MYSQLGuestbook.xml을 생성합시다.

MySQLGuestbook.xml
[code]<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap     
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     
"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="Guestbook">
    <resultMap id="resultGuestbook" class="GuestbookVO">
        <result property="no" column="no" />
        <result property="name" column="name" />
        <result property="subject" column="subject" />
        <result property="content" column="content" />
        <result property="ip" column="ip" />
        <result property="datetime" column="datetime" />
    </resultMap>
   
    <select id="getContents" resultMap="resultGuestbook">
        SELECT no, name, subject, content, ip, datetime
        FROM guestbook ORDER BY no DESC
    </select>
</sqlMap>[/code]
iBATIS에서 사용하는 방식입니다. 우선 resultMap을 만드는데 db에 있는 column을 java에 있는 bean에 매핑하기 위해서 만듭니다. 아래는 getContents는 Dao에서 호출하는 이름과 같아야 합니다.

Dao를 만들었으니 Manager클래스를 만들어봅시다.
com.phpschool.guestbook.service 패키지를 만듭시다.
New -> Java Interface를 선택 후 GuestbookManager라는 interface를 만듭시다.

GuestbookManager.java
[code]package com.phpschool.guestbook.service;

import com.phpschool.guestbook.vo.GuestbookVo;
import java.util.List;

public interface GuestbookManager {

    public List<GuestbookVo> getContents();
}
[/code]
getContents부분을 구현해봅시다.
New -> Java Class를 선택 후 GuestbookManagerImpl라는 class를 만듭시다.

GuestbookManagerImpl.java
[code]package com.phpschool.guestbook.service;

import com.phpschool.guestbook.db.GuestbookDao;
import com.phpschool.guestbook.vo.GuestbookVo;
import java.util.List;

public class GuestbookManagerImpl implements GuestbookManager{

    GuestbookDao guestbookDao;

    public void setGuestbookDao(GuestbookDao guestbookDao) {
        this.guestbookDao = guestbookDao;
    }
   
    public List<GuestbookVo> getContents() {
        return guestbookDao.getContents();
    }
}[/code]
Dao인터페이스를 하나 선언해주고 setter를 만들어줍니다. 이게 스프링에서 말하는 DI입니다. 저기에 값을 셋팅하는 건 applicationContext.xml이 해줍니다.
그리고 getContents메소드는 특별한 로직이 없어서 그냥 Contents만 리턴합니다.

Controller는 다음시간에-_-;

 
Posted by 머드초보
,
 

간단하게 DB에 있는 방명록 정보를 가져오는 정도를 해보겠습니다.

개발환경 : NetBeans6.0 + JDK6u3 + NetBeans내장Tomcat6.0 + iBATIS 2.3.0.677 + MySQL(버전모름-_-) + Spring Framework 2.5

우선 NetBeans6.0이 있어야겠고, Plugin으로 SpringFramework Support를 설치해야합니다.
메뉴에서 Tools -> Plugins클릭하면 Available Plugins를 선택하면 Spring Framework Support가 있는데 체크해서 설치를 하도록 합시다.

그런다음 프로젝트를 생성해봅시다.
File -> New Project선택 후 Web -> Web Application을 선택하고 Server는 Tomcat밖에 사용할 줄 모르니 Tomcat을 선택합니다(GlassFish사용할 줄 아는사람은 고거 선택하고^^)Next를 클릭하고
Project Name은 SpringIbatisExample 이라고 해봅시다. Next를 하면
Framework를 선택하라고 나옵니다. Spring Framework 2.5를 선택하고 Finish를 클릭합시다.

lib를 추가해야합니다. 따로 사용할 것은 iBATIS와 MySQL Connector입니다.
iBATIS는 www.ibatis.com 에서 받으면 되구요. MySQL Connector는 NetBeans에 내장되어있습니다.
프로젝트이름에 대고 오른쪽버튼 클릭 -> Properties -> Libraries -> Add Library 선택 후
MySQL JDBC Driver를 선택해서 추가합니다.
iBATIS는 아무 폴더에 설치 후에 Add JAR로 추가합시다.
넷빈즈에 Manage Libraries에 추가해서 사용하고 싶을 때 추가하게 할 수도 있습니다.

DB URL과 ID, PW를 설정해봅시다.
WEB-INF폴더 아래 jdbc.properties파일이 있는데 보면 어떤걸 설정해야할지 알껍니다.
driverClassName에는 com.mysql.jdbc.Driver를 넣고, url, id, pw를 넣으면 됩니다.

※DB구조입니다.
[code]CREATE TABLE `guestbook` (
  `no` int(11) NOT NULL auto_increment,
  `password` varchar(20) default NULL,
  `name` varchar(250) default NULL,
  `subject` varchar(2000) default NULL,
  `content` text,
  `ip` varchar(15) default NULL,
  `datetime` datetime default NULL,
  PRIMARY KEY  (`no`)
)[/code]

간단하게 F6을 눌러서 실행되는지 확인해봅시다.
this is the /WEB-INF/jsp/index.jsp 라고 뜨면 된 것입니다.

이제 설정을 해봅시다.
Configuration Files 밑에 applicationContext.xml파일을 열어봅시다.

applicationContext.xml
<!-- ADD PERSISTENCE SUPPORT HERE (jpa, hibernate, etc) --> 요고 밑에다가 작성해봅시다.
[code]<bean id="sqlMapClient"
       class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="/WEB-INF/SqlMapConfig.xml"/>
</bean>

<bean id="guestbookDao" class="com.phpschool.guestbook.db.GuestbookDaoImpl">
    <property name="sqlMapClient" ref="sqlMapClient" />
</bean>
   
<bean name="guestbookManager"
      class="com.phpschool.guestbook.service.GuestbookManagerImpl">
    <property name="guestbookDao" ref="guestbookDao" />
</bean>[/code]
iBATIS에서 sqlMap을 생성하는 부분입니다. 오...3줄이면 끝나는군요.
아래는 Dao를 하나 선언해줍니다. 이 Dao는 sqlMapClient를 받습니다. 그래서 이 sqlMapClient를 통해
sql문에 접근할 수 있습니다. 그리고 그 아래에 있는 bean은 Manager입니다. Dao를 이용해서 service로직을 구현하는 부분입니다.

그러면 저기 sqlMapClient property에 있는 configLocation에 SqlMapConfig.xml파일을 만들어봅시다.
Web Pages -> WEB-INF에 대고 New -> Other하고 XML Document를 선택하고 SqlMapConfig.xml파일을 생성한 뒤 다음과 같이 씁시다.

SqlMapConfig.xml

[code]<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMapConfig     
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <typeAlias alias="GuestbookVO" type="com.phpschool.guestbook.vo.GuestbookVO"/>
   
    <sqlMap resource="com/phpschool/guestbook/db/MySQLGuestbook.xml" />
</sqlMapConfig>
[/code]
다음과 같이 sqlMapConfig를 생성합니다. alias는 아래 resource에서 사용할 클래스 이름의 별명을 사용하게 하는 것입니다. 예를 들어 ResultClass 등에서 패키지명까지 다 입력해주어야하는데 alias를 지정해주면 클래스명만 써도 됩니다.
그리고 아래는 resource, 즉 sql들을 모아둔 xml파일입니다.
우선 제끼고 ValueObject를 만들어봅시다.
Source Packages에 대고 New -> Java Package선택 후 Package Name을 com.phpschool.guestbook.vo 라고 줘서 vo라는 패키지를 만듭시다.
그리고 New -> Java Class선택 후 Class Name을 GuestbookVo라고 합시다.

GuestbookVo.java
[code]private int no;
private String password;
private String name;
private String subject;
private String content;
private String ip;
private Timestamp datetime;[/code]
위 까지만 타이핑하고, Alt + Ins 하면 Getter And Setter가 나오는데 선택하고 전체를 다 선택하면 자동으로 setter와 getter가 만들어집니다.

아 힘들어-_-; 다음 이시간에-_-;

 
Posted by 머드초보
,
 
글쓰기 부분입니다.

얘는 Form이 들어가서 살짝 복잡합니다-_-;












writeController를 보도록 합시다.
[code]
<bean id="guestbookWriteValidator"
  class="com.mudchobo.guestbook.logic.GuestbookWriteValidator" />
 
<bean id="writeController"
  class="com.mudchobo.guestbook.controller.WriteController">
  <property name="sessionForm" value="true" />
  <property name="commandName" value="guestbookWrite" />
  <property name="commandClass"
    value="com.mudchobo.guestbook.logic.GuestbookWrite" />
  <property name="validator" ref="guestbookWriteValidator" />
  <property name="formView" value="list" />
  <property name="successView" value="list.do" />
  <property name="guestbookManager">
   <ref bean="guestbookMan" />
  </property>
</bean>
[/code]
writeController를 보면 여러가지 property가 있습니다. 사실......-_-; 잘 모르겠습니다-_-;
commandClass는 GuestbookWrite클래스를 값으로 사용하는데 이 클래스는 지금 현재 폼에 input이 3개가 있습니다. 이름, 제목, 내용. 이 3가지를 GuestbookWrite라는 VO에 담으려고 쓰는 것 같습니다.
그리고 validator는 guestbookWriteValidator를 참조했는데 이것은 GuestbookWriteValidator라는 클래스입니다. 이걸 Validator로 쓰겠다는 겁니다. 이것은 값을 받았을 때 해당 폼의 input의 값이 ""이면 에러를 추가하도록 되어있습니다. 사실 이부분 구현하다 말았습니다-_-;(귀차나서-_-)

formView는 list, list.jsp를 말하는 것 같습니다. successView는 성공시에 list.do를 수행하라는 겁니다.
guestbookManager는 Manager클래스를 참조합니다. 참조해서 데이터를 넣어야 하기 때문이죠 ^^

자 이제 실질적으로 하는 Controller를 보도록 합시다.
[code]
protected ModelAndView onSubmit(HttpServletRequest request,
   HttpServletResponse response, Object command, BindException errors)
   throws Exception {
  GuestbookVO guestbookVO = new GuestbookVO();
 
  guestbookVO.setName(((GuestbookWrite)command).getName());
  guestbookVO.setSubject(((GuestbookWrite)command).getSubject());
  guestbookVO.setContent(((GuestbookWrite)command).getContent());
  guestbookVO.setIp(request.getRemoteAddr());
  guestbookVO.setDatetime(new Timestamp(System.currentTimeMillis()));
 
  guestbookManager.writeGuestbook(guestbookVO);
 
  return new ModelAndView(new RedirectView(getSuccessView()));
 }
[/code]
우선 form액션을 수행하는 Controller는 SimpleFormController를 상속받아요. onSubmit메소드를 오버라이드합니다. 폼을 채우고 글쓰기버튼을 눌렀을 때 write.do를 수행하는데 그것을 수행하게 되면 writeController를 수행합니다.
command를 GuestbookWrite형으로 형변환하는군요. 아....위에 commandClass가 이건거 같군요.
저렇게 하니까 getName 등의 getter를 사용할 수 있군요.
그것을 가져와서 guestbookVO setter에 넣습니다. ip주소나 시간은 따로 생성합니다.
writeGuestbook메소드를 호출하니 그냥 끝나는군요.
writeGuestbook메소드를 보도록합시다.
[code]
public void writeGuestbook(GuestbookVO guestbookVO) {
  jdbcTemplate = new JdbcTemplate(dataSource);
  String query = "INSERT INTO guestbook (name, subject, content, ip, datetime) " +
      "VALUES (?, ?, ?, ?, ?)";
 
  Object[] params = new Object[] { guestbookVO.getName(),
          guestbookVO.getSubject(),
          guestbookVO.getContent(),
          guestbookVO.getIp(),
          guestbookVO.getDatetime() };
 
  jdbcTemplate.update(query, params);
 }
[/code]
insert 쿼리를 만들고 5가지의 ?를 넣었네요. 거기에 Object를 생성해서 각각의 값을 불러와서 넣어주고 가볍게
update한번하니 끝나네요. 와 간단해요!

아.....아무도 안볼꺼지만 그래도 그나마 저의 삽질이 도움이 되시는 분이 한분이라도 계셨으면 좋겠네요 ^^

 
Posted by 머드초보
,