'개발'에 해당되는 글 73건

  1. 2009.01.21 mysql
  2. 2009.01.15 스프링 MVC
  3. 2008.09.07 큐와 데크
  4. 2008.09.07 스택
  5. 2008.09.04 레코드
  6. 2008.08.29 스트링과 배열
  7. 2008.08.26 데이타와 데이타 구조
  8. 2008.07.28 스프링 tutorial (8)
  9. 2008.07.27 스프링 tutorial (7)
  10. 2008.07.26 스프링 tutorial (6)

mysql

개발/DB 2009. 1. 21. 15:52
1. mysql 제약조건 생성시 해당 칼럼에 index가 존재해야 한다.

ALTER TABLE TBLPERMMENU ADD INDEX IDX_TBLPERMMENU_NO1(PERM_NO);

ALTER TABLE TBLPERMMENU ADD FOREIGN KEY(PERM_NO) REFERENCES TBLPERM(PERM_NO) ON DELETE RESTRICT;

이런식...

'개발 > DB' 카테고리의 다른 글

아카이브 로그 모드 설정  (0) 2009.11.26
백업및 복구를 위한 기본개념  (0) 2009.11.25
아카이브 로그 모드와 노 아카이브 로그 모드  (0) 2009.11.24
mysql 페이징  (0) 2009.03.02
결합 컬럼 인덱스  (0) 2008.06.11
Posted by 무혹
,

스프링 MVC

개발/스프링 2009. 1. 15. 09:39
책도 몇권 읽었고 혼자 공부도 했지만 역시 난 절실하지 않으면 집중도 못하고 제대로 하지 못한다. 다시 플로우에 대해 차근차근 정리해보자. 기준은 spring 소스에 있는 petstore

1. 기본적으로 web 프로젝트는 WEB-INF에 있는 web.xml 설정파일을 읽어온다.
   (.net쪽은 틀린가? 나중에 확인해보자...)
스프링의 servlet 호출을 위해 web.xml에 아래 부분이 존재해야 한다.

<servlet>
   <servlet-name>petstore</servlet-name>
      <servlet-class>
       org.springframework.web.servlet.DispatcherServlet
       </servlet-class>
   <load-on-startup>2</load-on-startup>
</servlet>

또 DispatcherServlet과 Mapping하기 위한 확장자를 아래와 같이 정해준다.
이런 경우 do 로 끝나는 확장자는 DispatcherServlet이 처리하므로
서블릿 매핑파일( petstore-servlet.xml ) 에서 해당 controller를 찾게 된다.

<servlet-mapping>
   <servlet-name>petstore</servlet-name>
      <url-pattern>*.do</url-pattern>
</servlet-mapping>

2. DispatcherServlet이 진입점이므로 servlet-name으로 정해진 petstore와 연관된
petstore-servlet.xml이 있어야 한다.






'개발 > 스프링' 카테고리의 다른 글

실행오류  (0) 2012.04.05
스프링 tutorial (8)  (0) 2008.07.28
스프링 tutorial (7)  (0) 2008.07.27
스프링 tutorial (6)  (0) 2008.07.26
스프링 tutorial (5)  (0) 2008.07.25
Posted by 무혹
,
한쪽끝에서 항목이 삭제되고 반대편 끝에서는 항목이 삽입되는 선형리스트이다.
선입선출(FIFO : first-in first-out)리스트라고 부른다.

- 원형 큐
큐의 배열을 선형으로 표현하지 않고 원형으로 표현하는 방법이다.

데크는 삽입과 삭제가 양쪽 끝에서 모두 허용될 수 있는 선형 리스트이다.

- 데크의 종류
입력제한 데크 : 입력이 한쪽 끝으로만 제한되는 경우이다.
출력제한 데크 : 출력이 한쪽 끝으로만 일어날 수 있도록 제한하는 경우이다.


'개발 > 자료구조_알고리즘' 카테고리의 다른 글

스택  (0) 2008.09.07
레코드  (0) 2008.09.04
스트링과 배열  (0) 2008.08.29
데이타와 데이타 구조  (0) 2008.08.26
Posted by 무혹
,
선형 리스트 구조의 특별한 형태로 리스트내의 데이타의 삽입과 삭제가 '탑(TOP)'이라
불리는 한쪽 끝에서만 일어난다.
푸시다운 리스트 (pushdown list) 또는 후입 선출 (LIFO : last-in first-out)리스트라고 부른다.

스택의 중요한 연산으로는 스택에 데이타를 삽입하고 삭제하는 연산이 있다.
삽입연산은 푸시(push), 삭제연산은 팝(pop)이라고 부른다.

- 다중스택
하나의 기억장소블록에 2개의 스택을 보관하는것과 하나의기억장소 블록에 n개의 스택을
보관하는 방법이 있다. 가용공간의 이동으로 처리한다.

스택의 응용분야로는 수식의 계산, 서브루틴 호출과 수놘, 미로실험, 푸시다운 오토마타,
퀵 정렬등이 있다.


'개발 > 자료구조_알고리즘' 카테고리의 다른 글

큐와 데크  (0) 2008.09.07
레코드  (0) 2008.09.04
스트링과 배열  (0) 2008.08.29
데이타와 데이타 구조  (0) 2008.08.26
Posted by 무혹
,
레코드를 이질적 데이터 구조라고 부르듯이 레코드의 원소는 배열로 저장되지 않는다.

1. 고정 길이 레코드
일정한 길이를 가지고 있는 레코드이다.
삽입과 삭제가 간단하다.

2. 가변길이 레코드
- 한 파일내에 여러 유형의 레코드 저장
- 한 파일내에 가변 필드를 허용하는 레코드 저장
- 반복적 필드를 허용하는 레코드 저장
2-1. 바이트 스트링 표현
각 레코드 끝에 레코드 끝 기호를 첨가하는 가변 길이 레코드를 사용한다.
단점 : 삭제된 레코드의 기억 장소의 재사용이 쉽지 않다.
         크기가 증가하는 레코드는 기억 장소를 할당하기 어렵다.

2-2. 고정 길이 레코드
- 예약장소 기법 : 가장 큰 기억 장소를 차지하는 최대 레코드 길이가
존재하면 그 길이만큼의 고정 길이 레코드를 사용한다. 사용하지 않는
기억 장소는 의미없는 값이나 레코드 끝 기호를 채운다.
- 포인터 기법 : 포인터를 통하여 연결되는 고정길이 레코드의 리스트로
가변 길이 레코드를 표현한다.

'개발 > 자료구조_알고리즘' 카테고리의 다른 글

큐와 데크  (0) 2008.09.07
스택  (0) 2008.09.07
스트링과 배열  (0) 2008.08.29
데이타와 데이타 구조  (0) 2008.08.26
Posted by 무혹
,
스트링

1. 스트링의 표현 방법

1-1. 비압축 스트링

문자 코드들을 연속적인 워드에 나타내며, 한 워드에 한 개의 문자 코드를
나타낸다. 처리 속도는 빠르지만 기억장소 활용도가 낮으므로 좋지 않다.

1-2. 압축 스트링

워드단위로 사용하는 기계에서 문자 코드를 이용하여 한 위드에 많은 문자를
나타내어 기억 장소의 효율적 사용을 가능하게 한다.

1-3. 연결 리스트

기억장소를 고정 길이로 분할하고, 데이타 저장부와 연결 저장부의 두 부분으로
나눈다. 연결 저장 부는 다음 문자를 포함하는 블록의 위치를 가리키고 있다.
삽입, 삭제 서브스트링 연산등에서 이점이 있다.

1-4. 가변길이 스트링

크기를 예측할 수 없을때 가변길이 스트링을 사용하여 변화에 대처한다.

2. 스트링의 연산

2-1. 결합 연산 : 새로운 스트링을 생성하기 위하여 두 개 이상의 스트링을 연결하는것이다.

2-2. 서브스트링 연산 : 스트링에서 일부를 추출한다.

2-3. 삽입 연산 : 스트링 구성문자사이에 새로운 스트링을 삽입한다.

2-4. 삭제 연산 : 스트링 구성문자중 하나 이상의 문자를 삭제한다.

2-5. 패턴 매칭 연산 : 스트링중 지정된 서브스트링을 찾아서 불린값을 리턴한다.

2-6. 인덱싱 연산 : 스트링 내에서 어떤 문자 또는 서브스트링의 위치를 정수로 나타낸다.

배열

- 배열은 동일한 형의 데이타형을 갖는 원소들이 장방형 구조에 놓여 있는 집합체이다.
  배열은 1차월 배열과 다차원 배열 (2차원 이상)으로 나눌 수 있다.





'개발 > 자료구조_알고리즘' 카테고리의 다른 글

큐와 데크  (0) 2008.09.07
스택  (0) 2008.09.07
레코드  (0) 2008.09.04
데이타와 데이타 구조  (0) 2008.08.26
Posted by 무혹
,

정의
데이타 : 컴퓨터 시스템에 의해 처리하려는 대상
정보 : 문제를 해결하기 위해 컴퓨터 시스템에 의해 처리된 데이타 또는 의미가 있는 데이타

데이타는 프로그램과 협의의 데이타(수치 데이타, 문자 데이타, 논리 데이타)로 나뉜다.

1. 수치 데이터

종류 : 정수, 실수, 배정도(double precision) 실수, 복소수

1-1. 정수

정수중 최상위 비트는 부호비트
정수표현법은 부호있는 절대치 표현, 부호있는 1의보수, 부호있는 2의 보수가 있다.
각각의 표현법은 양수는 모두 동일하게 표현되지만, 0과 음수는 다르다.
10 ( 00001010 ) 을 예로 들면
부호있는 절대치 : 10001010  => 부호비트만 양수와 보수관계
1의 보수        : 11110101  => 양수에서 1을 0으로 0을 1로 변환
2의 보수        : 11110110  => 1의 보수 + 1

1-2. 실수

표현법은 고정소수점 방식과 부동소수점 방식

고정소수점 방식은 비트중에서 소수점위와 아래의 갯수가 정해진것
부동소수점 방식은 지수를 사용함으로써 소수점을 옮겨서 저장하는 방식

부동소수점은 0.10 * 10^-5 는 지수 -5와 가수 0.10으로 이루어진다.
가수 m은 언제나 0<= m < 1 을 만족하므로 소수점밑 첫째자리가 0이 아닌
수가 나오도록 정렬시키는것이 효과적이다.
지수부를 표현할때는 편중값(biased value)를 이용하여 표현한다.
1000000 을 0으로 간주하면 이 값이 편중값이 된다.
따라서 실제 지수=지수부분의 값 - 편중값이다.

1-3. 기타 수치데이타

배정도 실수 : 기억공간을 2개를 묶어서 하나의 실수로 표현한다.
복소수      : z = x+yi 이므로 하나의 복소수를 나타내기 위해 2개의 실수룰 사용한다.
BCD (Binary coded decimal) : 10진 숫자 10개를 코드로 규정하여 저장하여 진법변환없이
처리한다.
BCD의 종류 : BCD8421, BCD2421, Excess-3, Gray, Excess-3 Gray, Hamming

2. 비수치 데이타

2-1. 문자 데이타

7비트 ASCII와 8비트 EBCDIC

2-2. 논리 데이타

참 거짓을 표현

3. 데이타 구조의 종류

3-1. 광의의 데이타 구조 : 기초 데이타 형태, 협의의 데이타 구조, 화일 구조
3-1-1. 기초 데이타 형태 : 정수형, 실수형, 문자형, 논리형, 포이터형
3-1-2. 협의의 데이타 구조 : 단순 형태, 복합 형태(선형), 복합 형태(비선형)
3-1-2-1. 단순형태 : 스트링, 배열, 레코드
3-1-2-2. 복합형태(선형) : 스택, 큐, 리스트
3-1-2-3. 복합형태(비선형) : 그래프, 일반 트리, 이진 트리, 특수 트리

'개발 > 자료구조_알고리즘' 카테고리의 다른 글

큐와 데크  (0) 2008.09.07
스택  (0) 2008.09.07
레코드  (0) 2008.09.04
스트링과 배열  (0) 2008.08.29
Posted by 무혹
,

웹 어플리케이션의 persistence Layer의 통합

 

1.      Service layer의 수정

 

src/springapp/service/SimpleProductManager.java

 

package springapp.service;
 
import java.util.List;
 
import springapp.domain.Product;
 
public class SimpleProductManager implements ProductManager {
 
    privapackage springapp.service;
 
import java.util.List;
 
import springapp.domain.Product;
import springapp.repository.ProductDao;
 
public class SimpleProductManager implements ProductManager {
 
    // private List<Product> products;
    private ProductDao productDao;
 
    public List<Product> getProducts() {
        // return products;
        return productDao.getProductList();
    }
 
    public void increasePrice(int percentage) {
        List<Product> products = productDao.getProductList();
        if (products != null) {
            for (Product product : products) {
                double newPrice = product.getPrice().doubleValue() * 
                                    (100 + percentage)/100;
                product.setPrice(newPrice);
                productDao.saveProduct(product);
            }
        }
    }
 
    public void setProductDao(ProductDao productDao) {
        this.productDao = productDao;
    }
 
//    public void setProducts(List<Product> products) {
//        this.products = products;
//    }
 
}
 

  

2.     Failing tests의 확정

 

test/springapp/repository/InMemoryProductDao.java

 

package springapp.repository;
 
import java.util.List;
 
import springapp.domain.Product;
 
public class InMemoryProductDao implements ProductDao {
 
    private List<Product> productList;
 
    public InMemoryProductDao(List<Product> productList) {
        this.productList = productList;
    }
 
    public List<Product> getProductList() {
        return productList;
    }
 
    public void saveProduct(Product prod) {
    }
 
}
 

test/springapp/service/SimpleProductManagerTests.java

 

package springapp.service;
 
import java.util.ArrayList;
import java.util.List;
 
import springapp.domain.Product;
import springapp.repository.InMemoryProductDao;
import springapp.repository.ProductDao;
 
import junit.framework.TestCase;
 
public class SimpleProductManagerTests extends TestCase {
 
    private SimpleProductManager productManager;
 
    private List<Product> products;
    
    private static int PRODUCT_COUNT = 2;
    
    private static Double CHAIR_PRICE = new Double(20.50);
    private static String CHAIR_DESCRIPTION = "Chair";
    
    private static String TABLE_DESCRIPTION = "Table";
    private static Double TABLE_PRICE = new Double(150.10);         
    
    private static int POSITIVE_PRICE_INCREASE = 10;
    
    protected void setUp() throws Exception {
        productManager = new SimpleProductManager();
        products = new ArrayList<Product>();
        
        // stub up a list of products
        Product product = new Product();
        product.setDescription("Chair");
        product.setPrice(CHAIR_PRICE);
        products.add(product);
        
        product = new Product();
        product.setDescription("Table");
        product.setPrice(TABLE_PRICE);
        products.add(product);
        
        ProductDao productDao = new InMemoryProductDao(products);
        productManager.setProductDao(productDao);
        //productManager.setProducts(products);
    }
 
    public void testGetProductsWithNoProducts() {
        productManager = new SimpleProductManager();
        productManager.setProductDao(new InMemoryProductDao(null));
        assertNull(productManager.getProducts());
    }
    
    public void testGetProducts() {
        List<Product> products = productManager.getProducts();
        assertNotNull(products);        
        assertEquals(PRODUCT_COUNT, productManager.getProducts().size());
    
        Product product = products.get(0);
        assertEquals(CHAIR_DESCRIPTION, product.getDescription());
        assertEquals(CHAIR_PRICE, product.getPrice());
        
        product = products.get(1);
        assertEquals(TABLE_DESCRIPTION, product.getDescription());
        assertEquals(TABLE_PRICE, product.getPrice());      
    }   
    
    public void testIncreasePriceWithNullListOfProducts() {
        try {
            productManager = new SimpleProductManager();
            productManager.setProductDao(new InMemoryProductDao(null));
            productManager.increasePrice(POSITIVE_PRICE_INCREASE);
        }
        catch(NullPointerException ex) {
            fail("Products list is null.");
        }
    }
    
    public void testIncreasePriceWithEmptyListOfProducts() {
        try {
            productManager = new SimpleProductManager();
            productManager.setProductDao(new InMemoryProductDao(new ArrayList<Product>()));
            //productManager.setProducts(new ArrayList<Product>());
            productManager.increasePrice(POSITIVE_PRICE_INCREASE);
        }
        catch(Exception ex) {
            fail("Products list is empty.");
        }           
    }
    
    public void testIncreasePriceWithPositivePercentage() {
        productManager.increasePrice(POSITIVE_PRICE_INCREASE);
        double expectedChairPriceWithIncrease = 22.55;
        double expectedTablePriceWithIncrease = 165.11;
        
        List<Product> products = productManager.getProducts();      
        Product product = products.get(0);
        assertEquals(expectedChairPriceWithIncrease, product.getPrice());
        
        product = products.get(1);      
        assertEquals(expectedTablePriceWithIncrease, product.getPrice());       
    }
        
}
 

test/springapp/service/InventoryControllerTests.java

 

package springapp.web;
 
import java.util.Map;
 
import org.springframework.web.servlet.ModelAndView;
 
import springapp.domain.Product;
import springapp.repository.InMemoryProductDao;
import springapp.service.SimpleProductManager;
import springapp.web.InventoryController;
 
import junit.framework.TestCase;
 
public class InventoryControllerTests extends TestCase {
 
    public void testHandleRequestView() throws Exception{
        InventoryController controller = new InventoryController();
        SimpleProductManager spm = new SimpleProductManager();
        spm.setProductDao(new InMemoryProductDao(new ArrayList<Product>()));
        controller.setProductManager(spm);
        //controller.setProductManager(new SimpleProductManager());
        ModelAndView modelAndView = controller.handleRequest(null, null);
        assertEquals("hello", modelAndView.getViewName());
        assertNotNull(modelAndView.getModel());
        Map modelMap = (Map) modelAndView.getModel().get("model");
        String nowValue = (String) modelMap.get("now");
        assertNotNull(nowValue);
    }
}
 

war/WEB-INF/springapp-servlet.xml

 

<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
    <!-- the application context definition for the springapp DispatcherServlet -->
 
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="messages"/>
    </bean>
    
    <bean name="/hello.htm" class="springapp.web.InventoryController">
        <property name="productManager" ref="productManager"/>
    </bean>
 
    <bean name="/priceincrease.htm" class="springapp.web.PriceIncreaseFormController">
        <property name="sessionForm" value="true"/>
        <property name="commandName" value="priceIncrease"/>
        <property name="commandClass" value="springapp.service.PriceIncrease"/>
        <property name="validator">
            <bean class="springapp.service.PriceIncreaseValidator"/>
        </property>
        <property name="formView" value="priceincrease"/>
        <property name="successView" value="hello.htm"/>
        <property name="productManager" ref="productManager"/>
    </bean>
 
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/jsp/"></property>
        <property name="suffix" value=".jsp"></property>        
    </bean>
 
</beans>
 

war/WEB-INF/web.xml

 

<?xml version="1.0" encoding="UTF-8"?>
 
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
 
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
 
  <servlet>
    <servlet-name>springapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>springapp</servlet-name>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>
 
  <welcome-file-list>
    <welcome-file>
      index.jsp
    </welcome-file>
  </welcome-file-list>
 
  <jsp-config>
    <taglib>
      <taglib-uri>/spring</taglib-uri>
      <taglib-location>/WEB-INF/tld/spring-form.tld</taglib-location>
    </taglib>
  </jsp-config>
 
</web-app>
 

war/WEB-INF/applicationContext.xml

 

<?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:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 
    <!-- the parent application context definition for the springapp application -->
 
    <bean id="productManager" class="springapp.service.SimpleProductManager">
        <property name="productDao" ref="productDao"/>
    </bean>
 
    <bean id="productDao" class="springapp.repository.JdbcProductDao">
        <property name="dataSource" ref="dataSource"/>
    </bean>
 
</beans>
 

war/WEB-INF/applicationContext.xml

 

<bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
 
    <aop:config>
        <aop:advisor pointcut="execution(* *..ProductManager.*(..))" advice-ref="txAdvice"/>
    </aop:config>
 
    <tx:advice id="txAdvice">
        <tx:attributes>
            <tx:method name="save*"/>
            <tx:method name="*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
 

jdbc.properties 재사용

 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
 
    <bean id="propertyConfigurer" 
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>
 

 

 

spring-framework-2.5/lib/aspect/ aspectjweaver.jar

spring-framework-2.5/lib/jakarta-commons/commons-dbcp.jar

spring-framework-2.5/lib/jakarta-commons/commons-pool.jar

=> war/WEB-INF/lib

 

war/WEB-INF/applicationContext.xml

 

<?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:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 
    <!-- the parent application context definition for the springapp application -->
 
    <bean id="productManager" class="springapp.service.SimpleProductManager">
        <property name="productDao" ref="productDao"/>
    </bean>
 
    <bean id="productDao" class="springapp.repository.JdbcProductDao">
        <property name="dataSource" ref="dataSource"/>
    </bean>
 
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
 
    <bean id="propertyConfigurer" 
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>
 
    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
 
    <aop:config>
        <aop:advisor pointcut="execution(* *..ProductManager.*(..))" advice-ref="txAdvice"/>
    </aop:config>
 
    <tx:advice id="txAdvice">
        <tx:attributes>
            <tx:method name="save*"/>
            <tx:method name="*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
 
</beans>
 

 

마지막 테스트 실행 및 완료함

'개발 > 스프링' 카테고리의 다른 글

실행오류  (0) 2012.04.05
스프링 MVC  (0) 2009.01.15
스프링 tutorial (7)  (0) 2008.07.27
스프링 tutorial (6)  (0) 2008.07.26
스프링 tutorial (5)  (0) 2008.07.25
Posted by 무혹
,

DB persistence의 구현

 

1.     DB startup script의 생성

DB jar파일을 복사하므로써 사용할 수 있는 오픈소스 DB HSQL을 사용한다.

hsqldb.jar를 아래와 같이 복사한다.

spring-framework-2.5/lib/hsqldb => war/WEB-INF/lib

 

DB start를 위한 batch 파일을 필요로 한다.

springapp 디렉토리 아래에 db 디렉토리를 생성한다.

 

운영체제에 따라 아래와 같이 생성한다.

 

Linux/Mac OS X 일 경우 :

/db/server.sh

java -classpath ../war/WEB-INF/lib/hsqldb.jar org.hsqldb.Server -database test

이 경우에는 권한을 잊지 말자 'chmod +x server.sh'.

Windows일 경우 :

db/server.bat

java -classpath ..\war\WEB-INF\lib\hsqldb.jar org.hsqldb.Server -database test

 

운영체제에 따른 스크립트를 실행하여 DB start한다.

 

2.     Table test data를 생성

 

DB디렉토리 아래에 create_products.sql 을 생성한다.

 

db/create_products.sql

CREATE TABLE products (
  id INTEGER NOT NULL PRIMARY KEY,
  description varchar(255),
  price decimal(15,2)
);
CREATE INDEX products_description ON products(description);
 

테스트 데이터는 DB 디렉토리 아래에 load_data.sql 로 생성한다.

 

db/load_data.sql

INSERT INTO products (id, description, price) values(1, 'Lamp', 5.78);
INSERT INTO products (id, description, price) values(2, 'Table', 75.29);
INSERT INTO products (id, description, price) values(3, 'Chair', 22.81);

 

3.     스크립트 실행과 테스트 데이터 로드를 위한 ant target를 추가

 

Ant sql task를 사용하여 추가하고 DB properties build.properties에 추가한다.

 

build.properties

# Ant properties for building the springapp
 
appserver.home=${user.home}/apache-tomcat-6.0.14
# for Tomcat 5 use $appserver.home}/server/lib
# for Tomcat 6 use $appserver.home}/lib
appserver.lib=${appserver.home}/lib
 
deploy.path=${appserver.home}/webapps
 
tomcat.manager.url=http://localhost:8080/manager
tomcat.manager.username=tomcat
tomcat.manager.password=s3cret
 
db.driver=org.hsqldb.jdbcDriver
db.url=jdbc:hsqldb:hsql://localhost
db.user=sa
db.pw=
 

build.xml

 

<target name="createTables">
        <echo message="CREATE TABLES USING: ${db.driver} ${db.url}"/>
        <sql driver="${db.driver}"
             url="${db.url}"
             userid="${db.user}"
             password="${db.pw}"
             onerror="continue"
             src="db/create_products.sql">  
            <classpath refid="master-classpath"/>
        </sql> 
    </target>
 
    <target name="dropTables">
        <echo message="DROP TABLES USING: ${db.driver} ${db.url}"/>
        <sql driver="${db.driver}"
             url="${db.url}"
             userid="${db.user}"
             password="${db.pw}"
             onerror="continue">  
            <classpath refid="master-classpath"/>
 
        DROP TABLE products;
 
        </sql> 
    </target>
 
    <target name="loadData">
        <echo message="LOAD DATA USING: ${db.driver} ${db.url}"/>
        <sql driver="${db.driver}"
             url="${db.url}"
             userid="${db.user}"
             password="${db.pw}"
             onerror="continue"
             src="db/load_data.sql">  
            <classpath refid="master-classpath"/>
        </sql> 
    </target>
 
    <target name="printData">
        <echo message="PRINT DATA USING: ${db.driver} ${db.url}"/>
        <sql driver="${db.driver}"
             url="${db.url}"
             userid="${db.user}"
             password="${db.pw}"
             onerror="continue"
             print="true">  
            <classpath refid="master-classpath"/>
 
        SELECT * FROM products;
 
        </sql> 
    </target>
 
    <target name="clearData">
        <echo message="CLEAR DATA USING: ${db.driver} ${db.url}"/>
        <sql driver="${db.driver}"
             url="${db.url}"
             userid="${db.user}"
             password="${db.pw}"
             onerror="continue">  
            <classpath refid="master-classpath"/>
 
        DELETE FROM products;
 
        </sql> 
    </target>
 
    <target name="shutdownDb">
        <echo message="SHUT DOWN DATABASE USING: ${db.driver} ${db.url}"/>
        <sql driver="${db.driver}"
             url="${db.url}"
             userid="${db.user}"
             password="${db.pw}"
             onerror="continue">  
            <classpath refid="master-classpath"/>
 
        SHUTDOWN;
 
        </sql> 
    </target>
 

 

ant createTables loadData printData를 실행함으로써 테이블과 데이터를 준비한다.

 

4.     JDBC 구현을 위한 Data Access Object (DAO) 생성

 

DB access를 위한 클래스들을 가지는 디렉토리를 생성한다.

src/repository

 

ProductDAO라는 이름을 가지는 interface를 생성한다.

 

src/springapp/repository/ProductDao.java

package springapp.repository;
 
import java.util.List;
 
import springapp.domain.Product;
 
public interface ProductDao {
 
    public List<Product> getProductList();
 
    public void saveProduct(Product prod);
 
}
 

인터페이스를 구현한 클래스를 생성한다.

 

src/springapp/repository/JdbcProductDao.java

 

package springapp.repository;
 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
 
import springapp.domain.Product;
 
public class JdbcProductDao extends SimpleJdbcDaoSupport implements ProductDao {
 
    /** Logger for this class and subclasses */
    protected final Log logger = LogFactory.getLog(getClass());
 
 
    public List<Product> getProductList() {
        logger.info("Getting products!");
        List<Product> products = getSimpleJdbcTemplate().query(
                "select id, description, price from products", 
                new ProductMapper());
        return products;
    }
 
    public void saveProduct(Product prod) {
        logger.info("Saving product: " + prod.getDescription());
        int count = getSimpleJdbcTemplate().update(
            "update products set description = :description, price = :price where id = :id",
            new MapSqlParameterSource().addValue("description", prod.getDescription())
                .addValue("price", prod.getPrice())
                .addValue("id", prod.getId()));
        logger.info("Rows affected: " + count);
    }
    
    private static class ProductMapper implements ParameterizedRowMapper<Product> {
 
        public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
            Product prod = new Product();
            prod.setId(rs.getInt("id"));
            prod.setDescription(rs.getString("description"));
            prod.setPrice(new Double(rs.getDouble("price")));
            return prod;
        }
 
    }
 
}
 

domain/Product.java

 

package springapp.domain;
 
import java.io.Serializable;
 
public class Product implements Serializable {
 
    private int id;
    private String description;
    private Double price;
    
    public void setId(int i) {
        id = i;
    }
 
    public int getId() {
        return id;
    }
 
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public Double getPrice() {
        return price;
    }
    
    public void setPrice(Double price) {
        this.price = price;
    }
    
    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("Description: " + description + ";");
        buffer.append("Price: " + price);
        return buffer.toString();
    }
}
 

5.     JDBC DAO 구현의 test

 

spring-framework-2.5/dist/modules/spring-test.jar => war/WEB-INF/lib

 

test/springapp/domain/JdbcProductDaoTests.java

 

package springapp.repository;
 
import java.util.List;
 
public class JdbcProductDaoTests extends AbstractTransactionalDataSourceSpringContextTests {
 
    private ProductDao productDao;
 
    
    public void setProductDao(ProductDao productDao) {
        this.productDao = productDao;
    }
 
    @Override
    protected String[] getConfigLocations() {
        return new String[] {"classpath:test-context.xml"};
    }
 
    @Override
    protected void onSetUpInTransaction() throws Exception {
        super.deleteFromTables(new String[] {"products"});
        super.executeSqlScript("file:db/load_data.sql", true);
    }
 
    public void testGetProductList() {
        
        List<Product> products = productDao.getProductList();
        
        assertEquals("wrong number of products?", 3, products.size());
        
    }
    
    public void testSaveProduct() {
        
        List<Product> products = productDao.getProductList();
        
        for (Product p : products) {
            p.setPrice(200.12);
            productDao.saveProduct(p);
        }
        
        List<Product> updatedProducts = productDao.getProductList();
        for (Product p : updatedProducts) {
            assertEquals("wrong price of product?", 200.12, p.getPrice());
        }
 
    }
 
}
 

test/test-context.xml

 

<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 
 
    <!-- the test application context definition for the jdbc based tests --> 
 
    <bean id="productDao" class="springapp.repository.JdbcProductDao">
        <property name="dataSource" ref="dataSource" />
    </bean>
 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}"/>
      <property name="url" value="${jdbc.url}"/>
      <property name="username"  value="${jdbc.username}"/>
      <property name="password" value="${jdbc.password}"/>
    </bean>
    <bean id="propertyConfigurer" 
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
    </bean>
    
    <bean id="transactionManager" 
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
 
</beans>
 

war/WEB-INF/classes/jdbc.properties

 

jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://localhost
jdbc.username=sa
jdbc.password=
 

build.xml



<property name="test.dir" value="test"/>

 
 
    <path id="test-classpath">
        <fileset dir="${web.dir}/WEB-INF/lib">
            <include name="*.jar"/>
        </fileset>
        <pathelement path="${build.dir}"/>
        <pathelement path="${test.dir}"/>
        <pathelement path="${web.dir}/WEB-INF/classes"/>
    </path>

  

build.xml

  

    
<target name="tests" depends="build, buildtests" description="Run tests">
        <junit printsummary="on"
            fork="false"
            haltonfailure="false"
            failureproperty="tests.failed"
            showoutput="true">
            <classpath refid="test-classpath"/>
            <formatter type="brief" usefile="false"/>
            
            <batchtest>
                <fileset dir="${build.dir}">
                    <include name="**/*Tests.*"/>
                    <exclude name="**/Jdbc*Tests.*"/>
                </fileset>
            </batchtest>
            
        </junit>
        
        <fail if="tests.failed">
            tests.failed=${tests.failed}
            ***********************************************************
            ***********************************************************
            ****  One or more tests failed!  Check the output ...  ****
            ***********************************************************
            ***********************************************************
        </fail>
    </target>
 
    <target name="dbTests" depends="build, buildtests,dropTables,createTables,loadData" 
            description="Run db tests">
        <junit printsummary="on"
            fork="false"
            haltonfailure="false"
            failureproperty="tests.failed"
            showoutput="true">
            <classpath refid="test-classpath"/>
            <formatter type="brief" usefile="false"/>
            
            <batchtest>
                <fileset dir="${build.dir}">
                    <include name="**/Jdbc*Tests.*"/>
                </fileset>
            </batchtest>
            
        </junit>
        
        <fail if="tests.failed">
            tests.failed=${tests.failed}
            ***********************************************************
            ***********************************************************
            ****  One or more tests failed!  Check the output ...  ****
            ***********************************************************
            ***********************************************************
        </fail>
    </target>
  

ant dbTests를 실행하여 테스트 통과를 확인한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'개발 > 스프링' 카테고리의 다른 글

스프링 MVC  (0) 2009.01.15
스프링 tutorial (8)  (0) 2008.07.28
스프링 tutorial (6)  (0) 2008.07.26
스프링 tutorial (5)  (0) 2008.07.25
스프링 tutorial (4)  (0) 2008.07.17
Posted by 무혹
,

웹 인터페이스의 개발

 

1.     Controller에 비즈니스 로직 reference 추가

기존에 만든 HelloController를 좀 더 제대로 된 이름으로 변경하자.

그 이름은 InventoryController.

 

 

HelloController InventoryController, HelloControllerTests InventoryControllerTests

변경한다.

InventoryController를 날자와 Product List를 가진 Map을 리턴하도록 수정한다.

 

src/springapp/web/InventoryController.java

 

package springapp.web;
 
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
import springapp.service.ProductManager;
 
public class InventoryController implements Controller {
 
    protected final Log logger = LogFactory.getLog(getClass());
 
    private ProductManager productManager;
 
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
 
        String now = (new java.util.Date()).toString();
        logger.info("returning hello view with " + now);
 
        Map<String, Object> myModel = new HashMap<String, Object>();
        myModel.put("now", now);
        myModel.put("products", this.productManager.getProducts());
 
        return new ModelAndView("hello", "model", myModel);
    }
 
 
    public void setProductManager(ProductManager productManager) {
        this.productManager = productManager;
    }
 
}

test/springapp/web/InventoryControllerTests.java

 

package springapp.web;
 
import java.util.Map;
 
import org.springframework.web.servlet.ModelAndView;
 
import springapp.service.SimpleProductManager;
import springapp.web.InventoryController;
 
import junit.framework.TestCase;
 
public class InventoryControllerTests extends TestCase {
 
    public void testHandleRequestView() throws Exception{
        InventoryController controller = new InventoryController();
        controller.setProductManager(new SimpleProductManager());
        ModelAndView modelAndView = controller.handleRequest(null, null);
        assertEquals("hello", modelAndView.getViewName());
        assertNotNull(modelAndView.getModel());
        Map modelMap = (Map) modelAndView.getModel().get("model");
        String nowValue = (String) modelMap.get("now");
        assertNotNull(nowValue);
    }
}
 

2.     Message bundle 지원과 비즈니스 데이터의 display를 위해 view를 수정

 

war/WEB-INF/jsp/hello.jsp

 

<%@ include file="/WEB-INF/jsp/include.jsp" %>
 
<html>
  <head><title><fmt:message key="title"/></title></head>
  <body>
    <h1><fmt:message key="heading"/></h1>
    <p><fmt:message key="greeting"/> <c:out value="${model.now}"/></p>
    <h3>Products</h3>
    <c:forEach items="${model.products}" var="prod">
      <c:out value="${prod.description}"/> <i>$<c:out value="${prod.price}"/></i><br><br>
    </c:forEach>
  </body>
</html>
 

3.     비즈니스 객체와 테스트 데이터를 추가

 

war/WEB-INF/springapp-servlet.xml

 

<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
    <!-- the application context definition for the springapp DispatcherServlet -->
 
    <bean id="productManager" class="springapp.service.SimpleProductManager">
        <property name="products">
            <list>
                <ref bean="product1"/>
                <ref bean="product2"/>
                <ref bean="product3"/>
            </list>
        </property>
    </bean>
 
    <bean id="product1" class="springapp.domain.Product">
        <property name="description" value="Lamp"/>
        <property name="price" value="5.75"/>
    </bean>
        
    <bean id="product2" class="springapp.domain.Product">
        <property name="description" value="Table"/>
        <property name="price" value="75.25"/>
    </bean>
 
    <bean id="product3" class="springapp.domain.Product">
        <property name="description" value="Chair"/>
        <property name="price" value="22.79"/>
    </bean>
 
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="messages"/>
    </bean>
 
    <bean name="/hello.htm" class="springapp.web.InventoryController">
        <property name="productManager" ref="productManager"/>
    </bean>
 
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
 
</beans>
 

4.     Message bundle clean 타켓 추가

war/WEB-INF/classes 아래에 messages.properties를 생성한다.

 

war/WEB-INF/classes/messages.properties

 

title=SpringApp
heading=Hello :: SpringApp
greeting=Greetings, it is now
 

소스 파일이름이 변경되었으므로, clean undeploy 타겟을 build에 추가한다.

 

build.xml

 

<target name="clean" description="Clean output directories">
        <delete>
            <fileset dir="${build.dir}">
                <include name="**/*.class"/>
            </fileset>
        </delete>
    </target>
 
    <target name="undeploy" description="Un-Deploy application">
        <delete>
            <fileset dir="${deploy.path}/${name}">
                <include name="**/*.*"/>
            </fileset>
        </delete>
    </target>
 

톰캣을 stop시키고, clean, undeploy, deploy를 차례로 실행하고, 톰캣을

start하면 된다. 


5.
    
form의 추가

form을 위해서 spring-framework-2.5/dist/resources/spring-form.tld

war/WEB-INF/tld   복사한다.

Web.xml <taglib/>를 추가한다.

 

war/WEB-INF/web.xml

 

<?xml version="1.0" encoding="UTF-8"?>
 
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
 
  <servlet>
    <servlet-name>springapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>springapp</servlet-name>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>
 
  <welcome-file-list>
    <welcome-file>
      index.jsp
    </welcome-file>
  </welcome-file-list>
 
  <jsp-config>
    <taglib>
      <taglib-uri>/spring</taglib-uri>
      <taglib-location>/WEB-INF/tld/spring-form.tld</taglib-location>
    </taglib>
  </jsp-config>
 
</web-app>
 

 

태그 라이브러리를 적용한 priceincrease.jspwar/WEB-INF/jsp디렉토리에

생성한다.

 

springapp/war/WEB-INF/jsp/priceincrease.jsp

 

<%@ include file="/WEB-INF/jsp/include.jsp" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
 
<html>
<head>
  <title><fmt:message key="title"/></title>
  <style>
    .error { color: red; }
  </style>  
</head>
<body>
<h1><fmt:message key="priceincrease.heading"/></h1>
<form:form method="post" commandName="priceIncrease">
  <table width="95%" bgcolor="f8f8ff" border="0" cellspacing="0" cellpadding="5">
    <tr>
      <td align="right" width="20%">Increase (%):</td>
        <td width="20%">
          <form:input path="percentage"/>
        </td>
        <td width="60%">
          <form:errors path="percentage" cssClass="error"/>
        </td>
    </tr>
  </table>
  <br>
  <input type="submit" align="center" value="Execute">
</form:form>
<a href="<c:url value="hello.htm"/>">Home</a>
</body>
</html>
 

간단한 javaBean class를 만든다.

 

springapp/src/springapp/service/PriceIncrease.java

 

package springapp.service;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
public class PriceIncrease {
 
    /** Logger for this class and subclasses */
    protected final Log logger = LogFactory.getLog(getClass());
 
    private int percentage;
 
    public void setPercentage(int i) {
        percentage = i;
        logger.info("Percentage set to " + i);
    }
 
    public int getPercentage() {
        return percentage;
    }
 
}
 

체크할 Validator 클래스를 만든다.

 

src/springapp/service/PriceIncreaseValidator.java

 

package springapp.service;
 
import org.springframework.validation.Validator;
import org.springframework.validation.Errors;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
public class PriceIncreaseValidator implements Validator {
    private int DEFAULT_MIN_PERCENTAGE = 0;
    private int DEFAULT_MAX_PERCENTAGE = 50;
    private int minPercentage = DEFAULT_MIN_PERCENTAGE;
    private int maxPercentage = DEFAULT_MAX_PERCENTAGE;
 
    /** Logger for this class and subclasses */
    protected final Log logger = LogFactory.getLog(getClass());
 
    public boolean supports(Class clazz) {
        return PriceIncrease.class.equals(clazz);
    }
 
    public void validate(Object obj, Errors errors) {
        PriceIncrease pi = (PriceIncrease) obj;
        if (pi == null) {
            errors.rejectValue("percentage", "error.not-specified", null, "Value required.");
        }
        else {
            logger.info("Validating with " + pi + ": " + pi.getPercentage());
            if (pi.getPercentage() > maxPercentage) {
                errors.rejectValue("percentage", "error.too-high",
                    new Object[] {new Integer(maxPercentage)}, "Value too high.");
            }
            if (pi.getPercentage() <= minPercentage) {
                errors.rejectValue("percentage", "error.too-low",
                    new Object[] {new Integer(minPercentage)}, "Value too low.");
            }
        }
    }
 
    public void setMinPercentage(int i) {
        minPercentage = i;
    }
 
    public int getMinPercentage() {
        return minPercentage;
    }
 
    public void setMaxPercentage(int i) {
        maxPercentage = i;
    }
 
    public int getMaxPercentage() {
        return maxPercentage;
    }
 
}
 

6.     form controller의 추가

 

war/WEB-INF/springapp-servlet.xml

 

<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<!-- the application context definition for the springapp DispatcherServlet -->
 
<beans>
 
    <bean id="productManager" class="springapp.service.SimpleProductManager">
        <property name="products">
            <list>
                <ref bean="product1"/>
                <ref bean="product2"/>
                <ref bean="product3"/>
            </list>
        </property>
    </bean>
 
    <bean id="product1" class="springapp.domain.Product">
        <property name="description" value="Lamp"/>
        <property name="price" value="5.75"/>
    </bean>
        
    <bean id="product2" class="springapp.domain.Product">
        <property name="description" value="Table"/>
        <property name="price" value="75.25"/>
    </bean>
 
    <bean id="product3" class="springapp.domain.Product">
        <property name="description" value="Chair"/>
        <property name="price" value="22.79"/>
    </bean>
 
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="messages"/>
    </bean>
 
    <bean name="/hello.htm" class="springapp.web.InventoryController">
        <property name="productManager" ref="productManager"/>
    </bean>
 
    <bean name="/priceincrease.htm" class="springapp.web.PriceIncreaseFormController">
        <property name="sessionForm" value="true"/>
        <property name="commandName" value="priceIncrease"/>
        <property name="commandClass" value="springapp.service.PriceIncrease"/>
        <property name="validator">
            <bean class="springapp.service.PriceIncreaseValidator"/>
        </property>
        <property name="formView" value="priceincrease"/>
        <property name="successView" value="hello.htm"/>
        <property name="productManager" ref="productManager"/>
    </bean>
 
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
 
</beans>
 

src/web/PriceIncreaseFormController.java

 

package springapp.web;
 
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
import springapp.service.ProductManager;
import springapp.service.PriceIncrease;
 
public class PriceIncreaseFormController extends SimpleFormController {
 
    /** Logger for this class and subclasses */
    protected final Log logger = LogFactory.getLog(getClass());
 
    private ProductManager productManager;
 
    public ModelAndView onSubmit(Object command)
            throws ServletException {
 
        int increase = ((PriceIncrease) command).getPercentage();
        logger.info("Increasing prices by " + increase + "%.");
 
        productManager.increasePrice(increase);
 
        logger.info("returning from PriceIncreaseForm view to " + getSuccessView());
 
        return new ModelAndView(new RedirectView(getSuccessView()));
    }
 
    protected Object formBackingObject(HttpServletRequest request) throws ServletException {
        PriceIncrease priceIncrease = new PriceIncrease();
        priceIncrease.setPercentage(20);
        return priceIncrease;
    }
 
    public void setProductManager(ProductManager productManager) {
        this.productManager = productManager;
    }
 
    public ProductManager getProductManager() {
        return productManager;
    }
 
}
 

war/WEB-INF/classes/messages.properties

 

title=SpringApp
heading=Hello :: SpringApp
greeting=Greetings, it is now
priceincrease.heading=Price Increase :: SpringApp
error.not-specified=Percentage not specified!!!
error.too-low=You have to specify a percentage higher than {0}!
error.too-high=Don''t be greedy - you can''t raise prices by more than {0}%!
required=Entry required.
typeMismatch=Invalid data.
typeMismatch.percentage=That is not a number!!!
 

hello.jsp 의 수정

 

<%@ include file="/WEB-INF/jsp/include.jsp" %>
 
<html>
  <head><title><fmt:message key="title"/></title></head>
  <body>
    <h1><fmt:message key="heading"/></h1>
    <p><fmt:message key="greeting"/> <c:out value="${model.now}"/></p>
    <h3>Products</h3>
    <c:forEach items="${model.products}" var="prod">
      <c:out value="${prod.description}"/> <i>$<c:out value="${prod.price}"/></i><br><br>
    </c:forEach>
    <br>
    <a href="<c:url value="priceincrease.htm"/>">Increase Prices</a>
    <br>
  </body>
</html>
 

 

 

 

 

'개발 > 스프링' 카테고리의 다른 글

스프링 tutorial (8)  (0) 2008.07.28
스프링 tutorial (7)  (0) 2008.07.27
스프링 tutorial (5)  (0) 2008.07.25
스프링 tutorial (4)  (0) 2008.07.17
스프링 tutorial (3)  (0) 2008.07.17
Posted by 무혹
,