声明式异常处理
在程序中出现异常可以尽管往外抛,由统一接口做页面处理
代码:
服务层:抛出异常
public List<Category> list() throws SQLException {
Connection conn = DB.createConn();
String sql = "select * from _category_";
PreparedStatement ps = DB.prepare(conn, sql);
List<Category> categories = new ArrayList<Category>();
try {
ResultSet rs = ps.executeQuery();
Category c = null;
while(rs.next()) {
c = new Category();
c.setId(rs.getInt("id"));
c.setName(rs.getString("name"));
c.setDescription(rs.getString("description"));
categories.add(c);
}
} catch (SQLException e) {
e.printStackTrace();
throw(e);
}
DB.close(ps);
DB.close(conn);
return categories;
}
Action:调用服务,抛出异常
public String list() throws Exception {
categories = categoryService.list();
return SUCCESS;
}
配置声明异常:
<package name="bbs2009_default" extends="struts-default"> <global-results> <result name="error">/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping> </global-exception-mappings> </package>
这样抛出的异常java.lang.Exception由struts2处理,跳转到/error.jsp页面。
这个异常声明是全局的,也可以声明成局部的。
原理:
Struts2利用exception的拦截器try…catch Action的调用,在catch中做异常的跳转处理。
这个拦截器的实现类可以从struts2-core.jar中的struts-default.xml文件中找到:
<package name="struts-default" abstract="true"> <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/> <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/> <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/> <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" /> </result-types> <interceptors> <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/> <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/> <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/> <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/> <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" /> <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" /> <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" /> <interceptor name="externalRef" class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/> <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/> <interceptor name="exception " class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor "/>
ExceptionMappingInterceptor类中
public String intercept(ActionInvocation invocation)
{
String result;
try
{
result = invocation.invoke();
}
catch(Exception e)
{
if(isLogEnabled())
handleLogging(e);
List exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
String mappedResult = findResultFromExceptions(exceptionMappings, e);
if(mappedResult != null)
{
result = mappedResult;
publishException(invocation, new ExceptionHolder(e));
} else
{
throw e;
}
}
return result;
}
ActionInvocation为Action的调用过程。
I18N
1、原理:
a)ResourceBundle和Locale的概念
b)资源文件
c) native2ascii
2、Struts资源文件
a)Action-Package-App级
b)一般只用app
i.在struts.xml中定义<constant name="struts.custom.i18n.resources" value="bbs2009">
</constant>
ii.页面中去国际化值使用<s:property value="getText('login.username')"/>
c) PropertiesEditor插件
补充:LocalizedTextUtil是Struts 2.0中国际化的工具类,<s:text>标志就是通过调用它实现国际化的
国际化占位符使用:
如:
welcome.msg=欢迎你:{0}
页面:
<s:text name="welcome.msg">
<s:param value="username"></s:param>
</s:text>
或
<s:text name="welcome.msg">
<s:param>test</s:param>
</s:text>
上面value中设置变量为取得是值栈中的属性值
动态语言切换
通过在当前页面加个链接并且这个链接是自动继续返回到这个当前页面,需要在页面链接后面加上一个参数
request_locale:
<a href="admin/lang?request_locale=en_US">en</a>
<a href="admin/lang?request_locale=zh_CN">cn</a>
前面admin/lang这个action请求是返回到当前这个页面
标签取出国际化值:
<s:textfield name="name" label="%{getText('UserName')}"/>
或者
<s:property value="%{getText('UserName')}"/>
其中这个调用getText表示OGNL表达式调用Action中的普通方法:
public String getText(String aTextName, String defaultValue)
资源文件查找顺序
之所以说Struts2的国际化更灵活是因为它可以能根据不同需要配置和获取资源(properties)文件。在Struts 2.0中
有下面几种方法:
1.使用全局的资源文件,方法如上例所示。这适用于遍布于整个应用程序的国际化字符
串,它们在不同的包(package)中被引用,如一些比较共用的出错提示;
2.使用包范围内的资源文件。做法是在包的根目录下新建名的package.properties
和 package_xx_XX.properties文件。这就适用于在包中不同类访问的资源;
3.使用Action范围的资源文件。做法为 Action的包下新建文件名(除文件扩展名外)
与Action类名同样的资源文件。它只能在该Action中访问。如此一来,我们就可以
在不同的 Action里使用相同的properties名表示不同的值。例如,在ActonOne中
title为“动作一”,而同样用title在 ActionTwo表示“动作二”,节省一些命名工夫;
4.使用<s:i18n>标志访问特定路径的properties文件。使用方法请参考我早前的文
章《常用的Struts 2.0的标志(Tag)介绍》。在您使用这一方法时,请注意
<s:i18n>标志的范围。在<s:i18n name="xxxxx">到</s:i18n>之间,所有的
国际化字符串都会在名为xxxxx资源文件查找,如果找不到,Struts 2.0就会输出
默认值(国际化字符串的名字)。
上面我列举了四种配置和访问资源的方法,它们的范围分别是从大到小,而Struts 2.0在查找国际化字符串所遵循的是特定的顺序 ,如图所示:
纠正图中查找在struts.properties中配置的默认资源文件,在struts2.1.6中是配置在default.properties,也可以配置在struts.xml中。
struts.xml:
<constant name="struts.custom.i18n.resources" value="bbs2009"></constant>
这样就会在classpath下查找bbs2009_locale.properties的资源文件。
在Application级别时需要配置资源文件名称:
在strut2-core.jar#org.apache.struts2.default.properties中找到