Spring起步例子 “Developing a Spring Framework MVC application step-by-step” 剖析(二)

类别:Java 点击:0 评论:0 推荐:

3、  减小Controler对页面地址的依赖

在上面的Controler中,return new ModelAndView("WEB-INF/jsp/hello.jsp", "now", now);指出了jsp页面的绝对路径,这可以改变。

首先在springapp-servlet.xml中增加一个bean定义:

   <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

        <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>

        <property name="prefix"><value>/WEB-INF/jsp/</value></property>

        <property name="suffix"><value>.jsp</value></property>

    </bean>

然后把Controler的返回写为:

return new ModelAndView("hello", "now", now);

这样InternalResourceViewResolver在返回页面之前,会自动加上prefix和suffix。

(。。。我不清楚这有什么用,如果我的路径除了/WEB-INF/jsp之外还有多个,那该怎么加呢?。。。看来只好都放到jsp下面了)

 

4、  bean定义中把其属性定义成其他的bean

在springapp-servlet.xml中,我们做出如下定义

<beans>

    <bean id="springappController" class="web.SpringappController">

        <property name="productManager">

            <ref bean="prodMan"/>

        </property>

    </bean>

 

    <bean id="prodMan" class="bus.ProductManager">

        <property name="products">

            <list>

                <ref bean="product1"/>

                <ref bean="product2"/>

                <ref bean="product3"/>

            </list>

        </property>

    </bean>

 

    <bean id="product1" class="bus.Product">

        <property name="description"><value>Lamp</value></property>

        <property name="price"><value>5.75</value></property>

    </bean>

    <bean id="product2" class="bus.Product">

        <property name="description"><value>Table</value></property>

        <property name="price"><value>75.25</value></property>

    </bean>

    <bean id="product3" class="bus.Product">

        <property name="description"><value>Chair</value></property>

        <property name="price"><value>22.79</value></property>

    </bean>

 

</beans>       

 

有2点需要理解的:

1、  可以直接利用<property name="price"><value>75.25</value></property>为bean的属性赋值,也可以用<property name="productManager"> <ref bean="prodMan"/> </property>将属性赋为另一个定义的bean。

2、  这些被定义为属性的bean是在Web Module被加载时同时被加载的并且赋给属性的。一旦加载完成,就可以直接使用,因此没有必要在Class定义中为这些属性赋值(但必须有这些属性的setter定义)。比如按照上面的XML定义,我们把SpringappController写成这样:

public class SpringappController implements Controller {

    private ProductManager prodMan;

 

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {

        Map myModel = new HashMap();

        myModel.put("products", getProductManager().getProducts());

 

        return new ModelAndView("hello", "model", myModel);

    }

 

    public void setProductManager(ProductManager pm) {

        prodMan = pm;

    }

 

    public ProductManager getProductManager() {

      return prodMan;

    }

}

可以看到,没有为属性private ProductManager prodMan赋值,但定义了它的setter――setProductManager,这个setter在<bean id="springappController">被加载的时候自动调用了,以给prodMan赋上值。

 

5、  单元测试

在WEB应用开发中,我们习惯的测试方法是实际测试,即把WEB Module部署好了之后,用测试用例测试。这样效率很低,因为编译、打包、部署、测试的过程很费时间。

Spring的思想是及早测试以发现问题。

例子中,为测试SpringappController编写了测试程序:

package tests;

 

import java.util.Map;

import java.util.List;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.ServletException;

import junit.framework.TestCase;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

import org.springframework.web.servlet.ModelAndView;

import web.SpringappController;

import bus.ProductManager;

import bus.Product;

 

public class TestSpringappController extends TestCase {

 

    private ApplicationContext ac;

 

    public void setUp() throws IOException {

        ac = new FileSystemXmlApplicationContext("src/tests/WEB-INF/springapp-servlet.xml");

    }

 

    public void testHandleRequest() throws ServletException, IOException {

        SpringappController sc = (SpringappController) ac.getBean("springappController");

        ModelAndView mav = sc.handleRequest((HttpServletRequest) null, (HttpServletResponse) null);

        Map m = mav.getModel();

        List pl = (List) ((Map) m.get("model")).get("products");

        Product p1 = (Product) pl.get(0);

        assertEquals("Lamp", p1.getDescription());

        Product p2 = (Product) pl.get(1);

        assertEquals("Table", p2.getDescription());

        Product p3 = (Product) pl.get(2);

        assertEquals("Chair", p3.getDescription());

    }

}

测试类继承自junit.framework.TestCase。测试的时候,主要是测试controler产生的model对不对。当然在上面的例子中,测试没有多大的意义,因为model的产生太简单了。但是如果model产生的逻辑非常复杂,那这种测试是非常有意义的。

 

注意上面例子中的

    public void setUp() throws IOException {

        ac = new FileSystemXmlApplicationContext ( "src/tests/WEB-INF/springapp-servlet.xml" );

    }

它为controler创建了一个类似于app server的环境(bean的加载就是在这里完成的)

本文地址:http://com.8s8s.com/it/it14955.htm