Struts开发中常见陷阱及解决方案
立即解锁
发布时间: 2025-08-18 01:59:42 阅读量: 5 订阅数: 5 


Jakarta Pitfalls:Struts、Ant、JUnit和Cactus的省时解决方案
# Struts开发中常见陷阱及解决方案
## 1. 在JSP中执行业务逻辑的陷阱
### 1.1 问题描述
在Struts应用里,于JSP中编写业务逻辑会模糊甚至消除模型、视图和控制器之间的界限。在表示层编写业务逻辑存在问题,因为其实现无法与可能需要访问相同功能的业务层对象共享。若表示层和业务层都需对同一段逻辑进行单独实现,就难以保证行为的一致性。将代码放在JSP而非Java类中,情况会更糟,甚至在表示层类之间也无法共享逻辑。
### 1.2 问题示例
以下是一个在JSP中计算发票逾期日期的示例:
```jsp
<%
InvoiceDO invoice = (InvoiceDO)
request.getSession().getAttribute(“invoice”);
GregorianCalendar dueDateCal = new GregorianCalendar();
GregorianCalendar invoiceCal = new GregorianCalendar();
invoiceCal.setTime(invoice.getBillingDate());
int interval;
switch (invoice.getPaymentTerm().intValue()) {
case InvoiceDO.PAYMENT_TERM_30: interval = -30; break;
case InvoiceDO.PAYMENT_TERM_60: interval = -60; break;
default: interval = 0;
}
dueDateCal.add(Calendar.DATE, interval - 30);
boolean thirtyDaysPastDue = invoiceCal.before(dueDateCal);
%>
```
若其他JSP也需展示相同信息,就必须在每个需要该派生值的JSP中复制这段实现。
### 1.3 问题原因
- 缺乏将模型 - 视图 - 控制器设计模式应用于Web应用开发的经验。
- 在截止日期压力下走捷径。
### 1.4 其他问题
- 容器编译代码时,开发者只能依赖编译器的警告和错误消息,而容器编译器的错误消息通常难以理解。若不预编译JSP,编译错误要到在Web容器中加载页面时才会出现。
- 格式化代码难以共享,通常只能复制粘贴,容易产生问题。
### 1.5 解决方案:将业务逻辑移至辅助类
为避免此陷阱,可使用辅助类来包含业务逻辑,使逻辑能在应用的各层轻松共享。具体步骤如下:
1. 从包含最简单业务逻辑脚本的JSP开始:
- 找出脚本的所有副本,用调用辅助类中新实现的表达式替换它们。
2. 将脚本代码移至辅助类。
3. 必要时修改实现,以便按需共享。
4. 修改JSP中的渲染代码,以利用新实现。
5. 在相关Action中添加代码以调用业务逻辑。
6. 测试新实现:
- 测试完成后,对其他复制了该脚本的JSP应用相同步骤。在移除当前脚本的所有副本之前,不要处理下一个脚本。
7. 继续处理下一个包含业务逻辑脚本的JSP。
### 1.6 解决方案示例
以下是将上述示例中的业务逻辑移至辅助类`BusinessRules`的代码:
```java
package com.aboutobjects.pitfalls.rule;
import com.aboutobjects.pitfalls.InvoiceDO;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
* The business rules for our application.
*/
public class BusinessRules {
/**
* Determines whether the provided invoice is past due by the
* given number of days.
* @param invoice The invoice to be checked
* @param days The number of days before the invoice is considered
* past due
* @return <code>true</code> if the invoice is past due;
* <code>false</code> otherwise
*/
public static boolean isPastDue(InvoiceDO invoice, int days) {
GregorianCalendar dueDateCal = new GregorianCalendar();
GregorianCalendar invoiceCal = new GregorianCalendar();
invoiceCal.setTime(invoice.getBillingDate());
int interval;
switch (invoice.getPaymentTerm().intValue()) {
case InvoiceDO.PAYMENT_TERM_30: interval = -30; break;
case InvoiceDO.PAYMENT_TERM_60: interval = -60; break;
default: interval = 0;
}
dueDateCal.add(Calendar.DATE, interval - days);
return invoiceCal.before(dueDateCal);
}
/**
* Determines whether the provided invoice is thirty or more days
* past due.
* @param invoice The invoice to be checked.
* @return <code>true</code> if the invoice is thirty or more days
* past due; <code>false</code> otherwise
*/
public static boolean isThirtyDaysPastDue(InvoiceDO invoice) {
return isPastDue(i
```
0
0
复制全文
相关推荐










