首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

JBuilder 2005 整合 Spring 開發實戰:從 Hello World 到數據庫持久層完整教程

     編輯:Java 程式設計入門

環境準備

  • IDE:JBuilder 2005 (Borland 經典 Java IDE)
  • Spring 版本:1.2.x / 2.0.x (下載 `spring-framework-*-with-dependencies.zip`)
    解壓後 `dist/` 含核心 JAR,`lib/` 含 `log4j/`、`jakarta-commons/` 等第三方依賴
  • 服務器:Tomcat 5.5 (JBuilder 內建集成)
  • 日志:Log4j (Spring 默認用 Jakarta Commons Logging,橋接到 Log4j)

項目結構創建

  1. **專案** → `myProject.jpx`
  2. **Web Module** → `springapp.war` (Context Root: `/springapp`)
  3. **Libraries** → 添加 `Spring Library` (含 `dist/*.jar`)、`Log4j Library`、`Jakarta Commons Library`、`JSTL Library`、`HSQLDB Library`

第一階段:最小化 Spring MVC (Hello World)

1. web.xml 配置 DispatcherServlet

<web-app version="2.4" xmlns="https://java.sun.com/xml/ns/j2ee">
  <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>
</web-app>

2. springapp-servlet.xml (Spring MVC 上下文)

<beans>
  <bean id="springappController" class="spring.SpringappController"/>
  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
      <props><prop key="/hello.htm">springappController</prop></props>
    </property>
  </bean>
</beans>

3. Controller 實現

package spring;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.*;
import java.io.IOException;
import org.apache.log4j.Logger;

public class SpringappController implements Controller {
    static Logger logger = Logger.getLogger(SpringappController.class);
    public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
        logger.info("SpringappController - returning hello view");
        return new ModelAndView("hello.jsp");
    }
}

4. View: hello.jsp

<%@ page contentType="text/html; charset=Big5" %>
<html><body><h1>Hello - Spring Application</h1><p>Greetings.</p></body></html>

5. 運行驗證

Run Configuration → Server → Launch URI: `/springapp/hello.htm` → 控制台輸出日志、訪問頁面成功。

第二階段:最佳實踐重構 (JSTL、ViewResolver、分層、國際化)

1. 統一頁面片段 /WEB-INF/jsp/include.jsp

<%@ taglib prefix="c" uri="https://java.sun.com/jstl/core" %>
<%@ taglib prefix="fmt" uri="https://java.sun.com/jstl/fmt" %>

2. index.jsp 重定向到 Controller

<%@ include file="/WEB-INF/jsp/include.jsp" %>
<c:redirect url="/hello.htm"/>

3. hello.jsp 使用 JSTL 輸出模型數據

<%@ 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="${now}"/></p>
</body></html>

4. Controller 返回模型數據 + 移除硬編碼視圖路徑

public class SpringappController implements Controller {
    protected final Log logger = LogFactory.getLog(getClass());
    public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception {
        String now = new java.util.Date().toString();
        logger.info("returning hello view with " + now);
        return new ModelAndView("hello", "now", now); // 視圖邏輯名 "hello"
    }
}

5. springapp-servlet.xml 添加 ViewResolver + MessageSource

<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>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
  <property name="basename" value="messages"/>
</bean>

6. messages.properties (類路徑 /WEB-INF/classes/)

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

第三階段:業務邏輯分層 + 測試數據注入

1. 領域對象 bus.Product

package bus;
public class Product implements Serializable {
    private String description; private Double price;
    // getter/setter...
}

2. 服務層 bus.ProductManager

package bus;
public class ProductManager implements Serializable {
    private List products;
    public List getProducts() { return products; }
    public void setProducts(List products) { this.products = products; }
}

3. springapp-servlet.xml 注入測試數據

<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"/><property name="price" value="5.75"/></bean>
<bean id="product2" class="bus.Product">
  <property name="description" value="Table"/><property name="price" value="75.25"/></bean>
<bean id="product3" class="bus.Product">
  <property name="description" value="Chair"/><property name="price" value="22.79"/></bean>

4. Controller 使用 Model Map 傳遞多對象

public ModelAndView handleRequest(...) {
    Map model = new HashMap<>();
    model.put("now", new Date().toString());
    model.put("products", getProductManager().getProducts());
    return new ModelAndView("hello", "model", model);
}

5. hello.jsp 迭代顯示產品列表

<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>

第四階段:數據庫持久層 (HSQLDB + Spring JDBC)

1. HSQLDB 建表腳本 (JBuilder Database Pilot 執行)

CREATE TABLE products (
  id INTEGER NOT NULL PRIMARY KEY,
  description VARCHAR(255),
  price DECIMAL(15,2)
);
CREATE INDEX products_description ON products(description);
INSERT INTO products VALUES (1, 'Lamp', 5.78);
INSERT INTO products VALUES (2, 'Table', 75.29);
INSERT INTO products VALUES (3, 'Chair', 22.81);

2. DAO 接口 db.ProductManagerDao

package db;
public interface ProductManagerDao {
    List getProductList();
    void increasePrice(Product prod, int pct);
}

3. Spring JDBC 實現 db.ProductManagerDaoJdbc

package db;
public class ProductManagerDaoJdbc implements ProductManagerDao {
    protected final Log logger = LogFactory.getLog(getClass());
    private DataSource dataSource;
    
    public List getProductList() {
        logger.info("Getting products!");
        return new ProductQuery(dataSource).execute();
    }
    
    public void increasePrice(Product prod, int pct) {
        SqlUpdate su = new SqlUpdate(dataSource,
            "UPDATE products SET price = price * (100 + ?) / 100 WHERE id = ?");
        su.declareParameter(new SqlParameter("increase", Types.INTEGER));
        su.declareParameter(new SqlParameter("id", Types.INTEGER));
        su.compile();
        su.update(new Object[]{pct, prod.getId()});
    }
    
    public void setDataSource(DataSource ds) { this.dataSource = ds; }
    
    private class ProductQuery extends MappingSqlQuery {
        ProductQuery(DataSource ds) { super(ds, "SELECT id, description, price FROM products"); compile(); }
        protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {
            Product p = new Product();
            p.setId(rs.getInt("id"));
            p.setDescription(rs.getString("description"));
            p.setPrice(new Double(rs.getDouble("price")));
            return p;
        }
    }
}

4. 業務層整合 DAO

package bus;
public class ProductManager {
    private ProductManagerDao productManagerDao;
    public List getProducts() { return productManagerDao.getProductList(); }
    public void increasePrice(int pct) {
        for (Product p : getProducts()) productManagerDao.increasePrice(p, pct);
    }
    // setter/getter...
}

5. 完整 springapp-servlet.xml (含 DataSource、DAO、事務)

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
  <property name="url" value="jdbc:hsqldb:/home/trisberg/workspace/springapp/db/test"/>
  <property name="username" value="sa"/><property name="password" value=""/>
</bean>
<bean id="prodManDao" class="db.ProductManagerDaoJdbc">
  <property name="dataSource" ref="dataSource"/>
</bean>
<bean id="prodMan" class="bus.ProductManager">
  <property name="productManagerDao" ref="prodManDao"/>
</bean>
<!-- Controller、urlMapping、viewResolver、messageSource 同前 -->
<bean id="priceIncreaseValidator" class="bus.PriceIncreaseValidator"/>
<bean id="priceIncreaseForm" class="web.PriceIncreaseFormController">
  <property name="sessionForm" value="true"/>
  <property name="commandName" value="priceIncrease"/>
  <property name="commandClass" value="bus.PriceIncrease"/>
  <property name="validator" ref="priceIncreaseValidator"/>
  <property name="formView" value="priceincrease"/>
  <property name="successView" value="hello.htm"/>
  <property name="productManager" ref="prodMan"/>
</bean>

測試體系:Mock DAO + JUnit

// tests.MockProductManagerDaoImpl - 內存實現,無需數據庫
// tests.TestProductManagerDaoJdbc - 真實數據庫集成測試
// tests.TestProductManager - 業務邏輯單元測試 (Mock DAO)

關鍵經驗總結

  1. 分層架構:web (Controller) → bus (Service/Domain) → db (DAO) → 資源 (DataSource),依賴倒置
  2. 配置驅動:XML 聲明式裝配,環境差異隔離在配置文件
  3. ViewResolver 解耦:Controller 僅返回邏輯視圖名,物理路徑由配置決定
  4. JSTL + MessageSource:國際化、邏輯標籤、表達式語言,JSP 純展示
  5. Spring JDBC 模板:`MappingSqlQuery`/`SqlUpdate` 封裝 JDBC 樣板代碼,專注 SQL 與映射
  6. 測試分層:單元測試 Mock DAO,集成測試真實 DB,JBuilder 內建 JUnit 支持

現代化映照

JBuilder 2005 + Spring 1.2 的這套教程,完整展示了 **Spring MVC 核心設計**:DispatcherServlet 前端控制器、HandlerMapping、Controller 接口、ModelAndView、ViewResolver、簡單表單控制器、驗證器、JDBC 抽象、聲明式事務 (後續版本)。今日 Spring Boot 只是將這些「約定優於配置」、內嵌容器、Starter 依賴管理、Actuator 監控,核心編程模型**一脈相承**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved