Struts应用中Oracle数据库波斯历与公历的适配需求
我来一步步帮你搞定Struts应用适配波斯历(贾拉利历)的需求,同时支持英/波双语切换和双日历系统适配:
核心思路
整体流程是:前端提交波斯历格式的日期字符串 → Action层解析为对应日期对象 → 存入已配置波斯历的Oracle数据库 → 检索时根据当前语言/日历设置,将日期格式化为波斯历或公历展示。
1. 表单提交与Action层处理
首先,前端表单提交的是波斯历格式的字符串(比如 1403/05/15),Action类接收该参数后,需要用波斯历专用的日期库解析成日期对象。推荐使用ThreeTen-Extra库(和Java 8+的java.time API兼容)来处理贾拉利历,也可以用ICU4J库。
示例代码如下:
import org.threeten.extra.chrono.JalaliChronology; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Locale; public class DateAction extends ActionSupport { // 接收表单提交的波斯历日期字符串 private String persianDateStr; public String submitDate() { // 配置波斯历格式化器 DateTimeFormatter jalaliFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd") .withChronology(JalaliChronology.INSTANCE) .withLocale(new Locale("fa")); // 解析字符串为贾拉利历LocalDate对象 LocalDate jalaliDate = LocalDate.parse(persianDateStr, jalaliFormatter); // 调用DAO层将日期存入Oracle数据库(后续步骤会讲DAO适配) dateDao.saveJalaliDate(jalaliDate); return SUCCESS; } // getter/setter public String getPersianDateStr() { return persianDateStr; } public void setPersianDateStr(String persianDateStr) { this.persianDateStr = persianDateStr; } }
2. Oracle数据库存储适配
既然你的Oracle已经配置了波斯历(通常是设置NLS_CALENDAR='PERSIAN'),数据库的DATE类型会自动以波斯历存储日期。
如果用Hibernate等ORM框架,需要自定义类型映射来适配贾拉利历:
// 自定义Hibernate类型:映射贾拉利历LocalDate到数据库DATE类型 public class JalaliLocalDateType extends AbstractSingleColumnStandardBasicType<LocalDate> { public JalaliLocalDateType() { super(VarcharTypeDescriptor.INSTANCE, new JalaliLocalDateJavaTypeDescriptor()); } @Override public String getName() { return "jalali_local_date"; } }
然后在实体类中使用该类型:
@Type(type = "com.yourpackage.JalaliLocalDateType") @Column(name = "PERSIAN_DATE_COLUMN") private LocalDate persianDate;
如果用原生JDBC,直接将解析后的LocalDate(贾拉利历)通过PreparedStatement存入即可,Oracle会自动适配波斯历存储。
3. 检索时的日期格式化展示
从数据库取出日期后,需要根据当前用户的语言设置,决定展示波斯历还是公历:
首先配置Struts国际化资源文件:
messages_fa.properties(波斯文):date.format=yyyy/MM/ddmessages_en.properties(英文):date.format=MM/dd/yyyy
在Action中根据当前Locale格式化日期:
public String retrieveDate() { // 从数据库取出存储的日期 LocalDate storedDate = dateDao.getDateById(1); Locale currentLocale = ActionContext.getContext().getLocale(); DateTimeFormatter formatter; if (currentLocale.getLanguage().equals("fa")) { // 波斯语环境:用贾拉利历格式化 formatter = DateTimeFormatter.ofPattern(getText("date.format")) .withChronology(JalaliChronology.INSTANCE) .withLocale(currentLocale); } else { // 英语环境:用公历格式化 formatter = DateTimeFormatter.ofPattern(getText("date.format")) .withLocale(currentLocale); } // 格式化后存入request,供JSP展示 request.setAttribute("displayDate", storedDate.format(formatter)); return SUCCESS; }
- 在JSP中展示日期:
<p><s:text name="display.date.label"/> : <s:property value="displayDate"/></p>
4. 双语与日历系统切换
Struts的国际化切换可以通过设置Locale实现,同时自动适配对应日历系统:
- 编写切换语言的Action:
public String switchLanguage() { String lang = request.getParameter("lang"); Locale newLocale = new Locale(lang); // 设置当前请求的Locale ActionContext.getContext().setLocale(newLocale); // 将Locale存入Session,保持会话级别的语言设置 session.put("WW_TRANS_I18N_LOCALE", newLocale); return SUCCESS; }
- 前端添加切换按钮:
<a href="<s:url action='switchLanguage'><s:param name='lang' value='en'/></s:url>">English</a> <a href="<s:url action='switchLanguage'><s:param name='lang' value='fa'/></s:url>">فارسی</a>
切换到波斯语时,自动用波斯历解析和展示日期;切换到英语时,用公历处理。
关键注意事项
- 确保项目引入了ThreeTen-Extra或ICU4J库,用于处理贾拉利历的日期解析和格式化。
- 检查Oracle的NLS配置:
NLS_CALENDAR='PERSIAN'、NLS_DATE_FORMAT='YYYY/MM/DD'(匹配波斯历格式)。 - 前端建议使用波斯历日期选择器(比如jQuery Jalali Datepicker),避免用户输入错误格式的日期字符串。
内容的提问来源于stack exchange,提问作者Tejeshvi Roy
相关产品推荐
相关产品推荐

