import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.Interceptor;
/**
* @author Rain_zhou
*
*/
public class ExceptionInterceptor implements Interceptor {
/* (non-Javadoc)
* @see com.opensymphony.xwork.interceptor.Interceptor#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see com.opensymphony.xwork.interceptor.Interceptor#init()
*/
public void init() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see com.opensymphony.xwork.interceptor.Interceptor#intercept(com.opensymphony.xwork.ActionInvocation)
*/
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
ExceptionHandler handler=new ExceptionHandler(arg0);
return handler.invoke();
}
}
import com.founder.study.forum.helper.NoLimitException;
import com.opensymphony.xwork.Action;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.interceptor.PreResultListener;
/**
* @author Rain_zhou
*
*/
public class ExceptionHandler implements PreResultListener {
private ActionInvocation invocation;
private boolean beforeResult=true;
private String result=Action.ERROR;
public ExceptionHandler(ActionInvocation invocation){
this.invocation=invocation;
invocation.addPreResultListener(this);
}
String invoke(){
try{
result=invocation.invoke();
}catch(Exception e){
if(beforeResult){
return Action.ERROR;
}else{
return result;
}
}
return result;
}
/* (non-Javadoc)
* @see com.opensymphony.xwork.interceptor.PreResultListener#beforeResult(com.opensymphony.xwork.ActionInvocation, Java.lang.String)
*/
public void beforeResult(ActionInvocation arg0, String arg1) {
// TODO Auto-generated method stub
beforeResult=false;
result=arg1;
}
}
<bean id="bankManagerSecurity"
class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
<property name="validateConfigAttributes">
<value>true</value>
</property>
<property name="authenticationManager">
<ref bean="authenticationManager"/>
</property>
<property name="accessDecisionManager">
<ref bean="accessDecisionManager"/>
</property>
<property name="objectDefinitionSource">
<value>
net.sf.acegisecurity.context.BankManager.delete*=
ROLE_SUPERVISOR,RUN_AS_SERVER
net.sf.acegisecurity.context.BankManager.getBalance=
ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_
</value>
</property>
</bean>
<bean id="authenticationDao" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>
<bean id="daoAuthenticationProvider"
class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="authenticationDao"><ref bean="authenticationDao"/></property>
</bean>
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list><ref bean="daoAuthenticationProvider"/></list>
</property>
</bean>
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions"><value>false</value></property>
<property name="decisionVoters">
<list><ref bean="roleVoter"/></list>
</property>
</bean>
log4j.rootLogger=debug, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log
log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
import com.foo.Bar;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class MyApp {
static Logger logger = Logger.getLogger(MyApp.class.getName());
public static void main(String[] args) {
// BasicConfigurator replaced with PropertyConfigurator.
PropertyConfigurator.configure(args[0]);
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
logger.info("Exiting application.");
}
}
<filter>
<filter-name>Acegi Channel Processing Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.securechannel.ChannelProcessingFilter</param-value>
</init-param>
</filter>
<filter>
<filter-name>Acegi Authentication Processing Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</param-value>
</init-param>
</filter>
<filter>
<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value>
</init-param>
</filter>
<filter>
<filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
<filter-class>net.sf.acegisecurity.ui.AutoIntegrationFilter</filter-class>
</filter>
<filter>
<filter-name>Acegi HTTP Request Security Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Acegi Channel Processing Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Acegi Authentication Processing Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Acegi HTTP Request Security Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
CREATE TABLE users (
username VARCHAR(50) NOT NULL PRIMARY KEY,
password VARCHAR(50) NOT NULL,
enabled BIT NOT NULL
);
CREATE TABLE authorities (
username VARCHAR(50) NOT NULL,
authority VARCHAR(50) NOT NULL
);
CREATE UNIQUE INDEX ix_auth_username ON authorities ( username, authority );
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users
(username);
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
<property name="url"><value>${jdbc.url}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
<bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>
<bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="authenticationDao"><ref bean="authenticationDao"/></property>
<property name="userCache"><ref bean="userCache"/></property>
</bean>
<bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
<property name="minutesToIdle"><value>5</value></property>
</bean>
<bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider"/>
</list>
</property>
</bean>
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
<property name="allowIfAllAbstainDecisions">
<value>false</value>
</property>
<property name="decisionVoters">
<list><ref bean="roleVoter"/></list>
</property>
</bean>
<bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
<bean id="authenticationProcessingFilterEntryPoint"
class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
<property name="forceHttps"><value>false</value></property>
</bean>
<%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %>
<%@ page import="net.sf.acegisecurity.ui.AbstractProcessingFilter" %>
<%@ page import="net.sf.acegisecurity.AuthenticationException" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="<c:url value='j_acegi_security_check'/>" method="POST">
<table>
<tr><td>User:</td><td><input type='text' name='j_username'></td></tr>
<tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
</table>
</form>
</body>
</html>
<bean id="filterInvocationInterceptor"
class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager">
<ref bean="authenticationManager"/>
</property>
<property name="accessDecisionManager">
<ref bean="accessDecisionManager"/>
</property>
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/sec/administrator.*\Z=ROLE_SUPERVISOR
\A/sec/user.*\Z=ROLE_TELLER
</value>
</property>
</bean>
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
<property name="filterSecurityInterceptor">
<ref bean="filterInvocationInterceptor"/>
</property>
<property name="authenticationEntryPoint">
<ref bean="authenticationProcessingFilterEntryPoint"/>
</property>
</bean>
<bean id="authenticationProcessingFilter"
class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager">
<ref bean="authenticationManager"/>
</property>
<property name="authenticationFailureUrl">
<value>/loginerror.jsp</value>
</property>
<property name="defaultTargetUrl">
<value>/</value>
</property>
<property name="filterProcessesUrl">
<value>/j_acegi_security_check</value>
</property>
</bean>
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
<property name="channelDecisionManager">
<ref bean="channelDecisionManager"/>
</property>
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
\A/sec/administrator.*\Z=REQUIRES_SECURE_CHANNEL
\A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
\A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
\A.*\Z=REQUIRES_INSECURE_CHANNEL
</value>
</property>
</bean>
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref bean="secureChannelProcessor"/>
<ref bean="insecureChannelProcessor"/>
</list>
</property>
</bean>
<bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>
<bean name="/shop/newAccount.do" class="org.springframework.samples.jpetstore.web.spring.AccountFormController">
<property name="petStore"><ref bean="petStore"/></property>
<property name="validator"><ref bean="accountValidator"/></property>
<property name="successView"><value>index</value></property>
</bean>
<bean name="/shop/signon.do" class="org.springframework.samples.jpetstore.web.spring.SignonController">
<property name="petStore"><ref bean="petStore"/></property>
</bean>
<bean name="/shop/signonForm.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
<property name="viewName"><value>SignonForm</value></property>
</bean>
<bean id="secureHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="signonInterceptor"/>
</list>
</property>
<property name="urlMap">
<map>
<entry key="/shop/editAccount.do"><ref local="secure_editAccount"/></entry>
<entry key="/shop/listOrders.do"><ref local="secure_listOrders"/></entry>
<entry key="/shop/newOrder.do"><ref local="secure_newOrder"/></entry>
<entry key="/shop/viewOrder.do"><ref local="secure_viewOrder"/></entry>
</map>
</property>
</bean>
<!-- <filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>com.founder.study.forum.helper.FilterChar</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>-->
<filter>
<filter-name>webwork</filter-name>
<filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
</filter>
<!-- <filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>-->
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<!--
This typically isn't required, as the taglib is included in webwork.jar.
If you really need a taglib configuration within web.xml, copy webwork/src/java/META-INF/taglib.tld
to the WEB-INF directory as webwork.tld.
-->
<taglib>
<taglib-uri>webwork</taglib-uri>
<taglib-location>/WEB-INF/lib/webwork-2.2.4.jar</taglib-location>
</taglib>
<!-- <taglib>
<taglib-uri>sitemesh-decorator</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-decorator.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>sitemesh-page</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-page.tld</taglib-location>
</taglib>-->
</web-app>
xwork.xml
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN" "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd">
<xwork>
<include file="webwork-default.xml" />
<package name="default" extends="webwork-default">
<interceptors>
<interceptor-stack name="modelParamsStack">
<interceptor-ref name="model-driven" />
<interceptor-ref name="params" />
</interceptor-stack>
</interceptors>
</package>
</xwork>
webwork.properties
webwork.objectFactory = spring
webwork.devMode = true
webwork.tag.altSyntax=true
webwork.locale=zh_CN
webwork.i18n.encoding=UTF-8
webwork.custom.i18n.resources=com.founder.study.forum.resource.ApplicationResources
jdbc.properties
# Properties file with JDBC-related settings.
# Applied by PropertyPlaceholderConfigurer from "applicationContext-*.xml".
# Targeted at system administrators, to avoid touching the context XML files.
jdbc.driverClassName=org.gjt.mm.mysql.Driver
jdbc.url=jdbc:mysql://localhost:3306/forum?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
applicationContext.xml
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN""http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <include file="webwork-default.xml"/> <package name="default" extends="webwork-default"> ... </package></xwork>
The contents of webwork-default.xml are here:
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.1.1//EN""http://www.opensymphony.com/xwork/xwork-1.1.1.dtd"> <xwork> <package name="webwork-default"> <result-types> <result-type name="chain" class="com.opensymphony.xwork.ActionChainResult"/> <result-type name="dispatcher" class="com.opensymphony.webwork.dispatcher.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="com.opensymphony.webwork.views.freemarker.FreemarkerResult"/> <result-type name="httpheader" class="com.opensymphony.webwork.dispatcher.HttpHeaderResult"/> <result-type name="jasper" class="com.opensymphony.webwork.views.jasperreports.JasperReportsResult"/> <result-type name="redirect" class="com.opensymphony.webwork.dispatcher.ServletRedirectResult"/> <result-type name="redirect-action" class="com.opensymphony.webwork.dispatcher.ServletActionRedirectResult"/> <result-type name="stream" class="com.opensymphony.webwork.dispatcher.StreamResult"/> <result-type name="tiles" class="com.opensymphony.webwork.views.tiles.TilesResult"/> <result-type name="velocity" class="com.opensymphony.webwork.dispatcher.VelocityResult"/> <result-type name="xslt" class="com.opensymphony.webwork.views.xslt.XSLTResult"/> <result-type name="plaintext" class="com.opensymphony.webwork.dispatcher.PlainTextResult" /> <!-- Results necessary when using 'browse server' and 'upload' feature of Richtexteditor --> <result-type name="richtexteditorGetFolders" class="com.opensymphony.webwork.views.jsp.ui.RichtexteditorGetFoldersResult" /> <result-type name="richtexteditorGetFoldersAndFiles" class="com.opensymphony.webwork.views.jsp.ui.RichtexteditorGetFoldersAndFilesResult" /> <result-type name="richtexteditorCreateFolder" class="com.opensymphony.webwork.views.jsp.ui.RichtexteditorCreateFolderResult" /> <result-type name="richtexteditorFileUpload" class="com.opensymphony.webwork.views.jsp.ui.RichtexteditorFileUploadResult" /> </result-types> <interceptors> <interceptor name="alias" class="com.opensymphony.xwork.interceptor.AliasInterceptor"/> <interceptor name="autowiring" class="com.opensymphony.xwork.spring.interceptor.ActionAutowiringInterceptor"/> <interceptor name="chain" class="com.opensymphony.xwork.interceptor.ChainingInterceptor"/> <interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/> <interceptor name="conversionError" class="com.opensymphony.webwork.interceptor.WebWorkConversionErrorInterceptor"/> <interceptor name="createSession" class="com.opensymphony.webwork.interceptor.CreateSessionInterceptor" /> <interceptor name="debugging" class="com.opensymphony.webwork.interceptor.debugging.DebuggingInterceptor" /> <interceptor name="external-ref" class="com.opensymphony.xwork.interceptor.ExternalReferencesInterceptor"/> <interceptor name="execAndWait" class="com.opensymphony.webwork.interceptor.ExecuteAndWaitInterceptor"/> <interceptor name="exception" class="com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor"/> <interceptor name="fileUpload" class="com.opensymphony.webwork.interceptor.FileUploadInterceptor"/> <interceptor name="i18n" class="com.opensymphony.xwork.interceptor.I18nInterceptor"/> <interceptor name="logger" class="com.opensymphony.xwork.interceptor.LoggingInterceptor"/> <interceptor name="model-driven" class="com.opensymphony.xwork.interceptor.ModelDrivenInterceptor"/> <interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/> <interceptor name="prepare" class="com.opensymphony.xwork.interceptor.PrepareInterceptor"/> <interceptor name="static-params" class="com.opensymphony.xwork.interceptor.StaticParametersInterceptor"/> <interceptor name="scope" class="com.opensymphony.webwork.interceptor.ScopeInterceptor"/> <interceptor name="servlet-config" class="com.opensymphony.webwork.interceptor.ServletConfigInterceptor"/> <interceptor name="sessionAutowiring" class="com.opensymphony.webwork.spring.interceptor.SessionContextAutowiringInterceptor"/> <interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/> <interceptor name="token" class="com.opensymphony.webwork.interceptor.TokenInterceptor"/> <interceptor name="token-session" class="com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor"/> <interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/> <interceptor name="workflow" class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor"/> <!-- Basic stack --> <interceptor-stack name="basicStack"> <interceptor-ref name="exception"/> <interceptor-ref name="servlet-config"/> <interceptor-ref name="prepare"/> <interceptor-ref name="static-params"/> <interceptor-ref name="params"/> <interceptor-ref name="conversionError"/> </interceptor-stack> <!-- Sample validation and workflow stack --> <interceptor-stack name="validationWorkflowStack"> <interceptor-ref name="basicStack"/> <interceptor-ref name="validation"/> <interceptor-ref name="workflow"/> </interceptor-stack> <!-- Sample file upload stack --> <interceptor-stack name="fileUploadStack"> <interceptor-ref name="fileUpload"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample WebWork Inversion of Control stack Note: WebWork's IoC is deprecated - please look at alternatives such as Spring --> <interceptor-stack name="componentStack"><interceptor-ref name="component"/><interceptor-ref name="basicStack"/></interceptor-stack><!-- Sample model-driven stack --><interceptor-stack name="modelDrivenStack"><interceptor-ref name="model-driven"/><interceptor-ref name="basicStack"/></interceptor-stack><!-- Sample action chaining stack --><interceptor-stack name="chainStack"><interceptor-ref name="chain"/><interceptor-ref name="basicStack"/></interceptor-stack><!-- Sample i18n stack --><interceptor-stack name="i18nStack"><interceptor-ref name="i18n"/><interceptor-ref name="basicStack"/></interceptor-stack> <!-- Sample execute and wait stack. Note: execAndWait should always be the *last* interceptor. --> <interceptor-stack name="executeAndWaitStack"><interceptor-ref name="basicStack"/><interceptor-ref name="execAndWait"/></interceptor-stack> <!-- An example of the params-prepare-params trick. This stack is exactly the same as the defaultStack, except that it includes one extra interceptor before the prepare interceptor: the params interceptor. This is useful for when you wish to apply parameters directly to an object that you wish to load externally (such as a DAO or database or service layer), but can't load that object until at least the ID parameter has been loaded. By loading the parameters twice, you can retrieve the object in the prepare() method, allowing the second params interceptor to apply the values on the object. --> <interceptor-stack name="paramsPrepareParamsStack"><interceptor-ref name="exception"/><interceptor-ref name="alias"/><interceptor-ref name="params"/><interceptor-ref name="servlet-config"/><interceptor-ref name="prepare"/><interceptor-ref name="i18n"/><interceptor-ref name="chain"/><interceptor-ref name="model-driven"/><interceptor-ref name="fileUpload"/><interceptor-ref name="static-params"/><interceptor-ref name="params"/><interceptor-ref name="conversionError"/><interceptor-ref name="validation"><param name="excludeMethods">input,back,cancel</param></interceptor-ref><interceptor-ref name="workflow"><param name="excludeMethods">input,back,cancel</param></interceptor-ref></interceptor-stack> <!-- A complete stack with all the common interceptors in place. Generally, this stack should be the one you use, though it may do more than you need. Also, the ordering can be switched around (ex: if you wish to have your servlet-related objects applied before prepare() is called, you'd need to move servlet-config interceptor up. This stack also excludes from the normal validation and workflow the method names input, back, and cancel. These typically are associated with requests that should not be validated. --> <interceptor-stack name="defaultStack"><interceptor-ref name="exception"/><interceptor-ref name="alias"/><interceptor-ref name="servlet-config"/><interceptor-ref name="prepare"/><interceptor-ref name="i18n"/><interceptor-ref name="chain"/><interceptor-ref name="debugging"/><interceptor-ref name="model-driven"/><interceptor-ref name="fileUpload"/><interceptor-ref name="static-params"/><interceptor-ref name="params"/><interceptor-ref name="conversionError"/><interceptor-ref name="validation"><param name="excludeMethods">input,back,cancel,browse</param></interceptor-ref><interceptor-ref name="workflow"><param name="excludeMethods">input,back,cancel,browse</param></interceptor-ref></interceptor-stack> <!-- The completeStack is here for backwards compatibility for applications that still refer to the defaultStack by the old name --> <interceptor-stack name="completeStack"><interceptor-ref name="defaultStack"/></interceptor-stack></interceptors><default-interceptor-ref name="defaultStack"/></package></xwork>
This file defines all of the default bundled results and interceptors and many interceptor stacks which you can use either as-is or as a basis for your own application-specific interceptor stacks. Notice the name of the package is "webwork-default".
下邊是創建一個簡單實例的步驟:
1,新建一個標準的web工程叫sitemesh
在WebRoot下新建一個index.jsp,內容如下
接著在webRoot下新建幾個目錄
style2
login
shared
在login下建立目錄style3
然後把index.jsp分別復制到style2,login/style3,shared下
現在訪問下邊的鏈接:
http://localhost:8080/sitemesh/index.jsp
http://localhost:8080/sitemesh/style2/index.jsp
http://localhost:8080/sitemesh/login/style3/index.jsp
http://localhost:8080/sitemesh/shared/index.jsp
得到的結果是一樣的,那我們如何讓這四個相同的index.jsp有不同的樣式呢。除了每個里邊加入include
還有個解決辦法,就是sitemesh
2,在http://www.opensymphony.com下載sitemesh-2.2.1.jar,sitemesh-decorator.tld,sitemesh-page.tld
三個文件。
復制sitemesh.jar到WEB-INF/lib下,
復制sitemesh-decorator.tld,sitemesh-page.tld到WEB-INF下
把下邊這部分加入web.xml
------------------------------------------------------------------------------
<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<taglib>
<taglib-uri>sitemesh-decorator</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-decorator.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>sitemesh-page</taglib-uri>
<taglib-location>/WEB-INF/sitemesh-page.tld</taglib-location>
</taglib>
--------------------------------------------------------------------------------
在WEB-INF下建立一個decorators.xml,內容如下
excludes代表不使用的部分
其它三個是匹配url,使用style
--------------------------------------------------------------------------
<decorators defaultdir="/decorators">
<excludes>
<pattern>/shared/*</pattern>
</excludes>
<decorator name="style1" page="style1.jsp">
<pattern>/*</pattern>
</decorator>
<decorator name="style2" page="style2.jsp">
<pattern>/style2/*</pattern>
</decorator>
<decorator name="style3" page="style3.jsp">
<pattern>/*/style3/*</pattern>
</decorator>
</decorators>
--------------------------------------------------------------------------
在WebRoot下新建一個目錄decorators
然後在下邊建立三個jsp文件,內容如下
------------------------------------------------------------------
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="sitemesh-decorator" prefix="decorator" %>
<html>
<head>
<title><decorator:title default="裝飾器頁面..." /></title>
<decorator:head />
</head>
<body>
<p><font color="red">this is style2's header</font></p>
<hr>
<decorator:body />
<hr>
<p><font color="red">this is style1's footer</font></p>
</body>
</html>
------------------------------------------------------------------
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="sitemesh-decorator" prefix="decorator" %>
<html>
<head>
<title><decorator:title default="裝飾器頁面..." /></title>
<decorator:head />
</head>
<body>
<p><font color="green">this is style2's header</font></p>
<hr>
<decorator:body />
<hr>
<p><font color="green">this is style2's footer</font></p>
</body>
</html>
------------------------------------------------------------------
<%@ page contentType="text/html; charset=utf-8"%>
<%@ taglib uri="sitemesh-decorator" prefix="decorator" %>
轉自http://www.aygfsteel.com/black_zerg/archive/2005/05/30/5327.html
|
在 src 目錄下為 Java 源碼
dao
負責數據訪問對象的定義和實現
其中
Dao
結尾為接口,
Impl
結尾為實現。目前一般用
hibernate
做實現。 這里 service 是外觀接口, serviceimpl 是實現,考慮目前情況簡單,并沒有進一步分離邏輯,業務邏輯都在 impl 中完成。
web
界面相關的
Java
類
common 是一些常用類,如處理中文問題的 filter. displaytag 中放了 displaytag 相關的類,多為 wrapper. webwork 中都是對應的 action , 其中 BaseAction 是基本的抽象類,基本后續開發應繼承此類 CrudAction 是為了一般的 Crud 工作而作的一個抽象類,可以繼承用來簡化工作。
而
CaseDispatcher
負責菜單點擊后分發到相關
Action
,同時處理權限和
session
工作。 |
|
左邊是 webroot 的結構
重要的配置文件有:
Spring applicationContext.xml applicationContext-db.xml
Webwork xwork.xml webwork.properties
i18n labels.properties
log4j log4j.properties
displaytag displaytag.properties
dbConnect jdbc.properties |
關于一些技術難點和細節:
1. 各框架連接: spring 到 hibernate 使用 spring 的 hibernate 支持。 Spring 到 webwork 使用 autoware 的攔截機制自動裝配。
2. 列表的問題,采用 displaytag 。功能強大,使用簡潔,可實現排序和數據導出。
3. 數據下載,使用 displaytag 自帶的 excel 下載
4. 文件上傳,使用 webwork 提供的解決方案,用攔截機制實現。
5. jsp 代碼組織方面,我們使用 taglib 和 css 技術使 jsp 中頁面邏輯減少到最小,一般情況完全可以不使用 <% %> 的 script 段 。同時我們使用兩個 include 來包含常用的 taglib 定義, js 引用和 html 結構,使 jsp 代碼非常簡潔。
6. 中文問題 我們使用 filter 來解決頁面 gbk 到 Java 程序 unicode 的轉換,同時通過正確的設置數據庫連接 url 完成和數據庫之間的交互。
7. I18n 國際化。我們要求在 jsp 代碼中不出現中文,所有提示信息都通過資源文件 labels.properties 來完成。頁面中可以使用 jstl 或 webwork 標簽來調用。
8. 界面驗證問題。使用 webwork 的 validate 機制用 xml 定義,或在 action 中代碼判斷。