公司一直不是ssh零配置的框架,每次写action都要在applicationcontext和struts里面配置,好麻烦,最近有空,写了一个ssh零配置的框架
这里写了一个小的项目,以用户权限管理为例
先做准备工作:
一、先建立一个空的web的项目sshframe,加载必须的包
1.添加struts2必备的包。我下载的是最近的struts2.3.8
asm-3.3.jar --asm字节码库 ,使用“cglib”则必要
aopalliance-1.0.jar --这个包为aop提供了最普通和通用的接口
commons-fileupload-1.2.2.jar --struts2上传下载的jar
commons-io-2.0.1.jar --struts2上传下载的jar
commons-logging-1.1.1.jar --jakarta的通用日志记录包
freemarker-2.3.19.jar
ognl-3.0.6.jar --支持ognl表达式
struts2-core-2.3.8.jar --struts2的核心包
struts2-spring-plugin-2.3.8.jar --struts2与spring整合所需
struts2-convention-plugin-2.3.8.jar --struts2零配置注释用
xwork-core-2.3.8.jar
2.添加hibernate 所需要的包。hibernate-4.1.9.final
把下载下来的hibernate\lib\required下的包全部拷贝进去,分别是
antlr-2.7.7.jar --语言转换工具,hibernate用他将hql语句转换为sql语句
dom4j-1.6.1.jar --解析xml文档的工具
hibernate-commons-annotations-4.0.1.final.jar
hibernate-core-4.1.9.final.jar --核心包
hibernate-jpa-2.0-api-1.0.1.final.jar
javassist-3.17.1-ga.jar
jboss-logging-3.1.0.ga.jar
jboss-transaction-api_1.1_spec-1.0.0.final.jar
还有加入hibernate\lib\optional\c3p0\c3p0-0.9.1.jar
hibernate-ehcache-4.1.9.final.jar
ehcache-core-2.4.3.jar
slf4j-api-1.6.4.jar
slf4j-log4j12-1.6.4.jar
3添加spring3 所需要的包 spring-framework-3.2.0.release
spring-aop-3.2.0.release.jar
spring-aspects-3.2.0.release.jar
spring-beans-3.2.0.release.jar
spring-context-3.2.0.release.jar
spring-core-3.2.0.release.jar
spring-expression-3.2.0.release.jar
spring-instrument-3.2.0.release.jar
spring-jdbc-3.2.0.release.jar
spring-jms-3.2.0.release.jar
spring-orm-3.2.0.release.jar
spring-oxm-3.2.0.release.jar
spring-test-3.2.0.release.jar --测试时用
spring-tx-3.2.0.release.jar --事务处理所用
spring-web-3.2.0.release.jar
aspectjweaver-1.5.3.jar --spring所依赖的包
其他
asm-commons-3.3.jar
commons—pool.jar ,commons-dbcp.jar ----------dbcp数据库连接池,apache的jakarta组织开发 的,tomcat连接池也是dbcp(可选)
cglib.jar----------------------------高效的代码生成工具, hibernate用它在运行时扩展 java类和实现 java 接
jta.jar --标准的jta api(jta即java事物api,jta事务比jdbc事务更强大。一个jta事务可以有多个参与者,而一个jdbc事务则被限定在一个单一的数据库连接),我暂时还没加,先备着
mysql-connector-java-5.1.18-bin.jar
log4j-1.2.16.jar
二、添加配置文件
在struts包下struts\src\apps\blank\src\main\resources提供了空白的struts.xml文件,把它复制到项目的src下
web.xml中
<!-- spring 配置 -->
<listener>
<listener-class>org.springframework.web.context.contextloaderlistener</listener-class>
</listener>
<context-param>
<description>spring上下文</description>
<param-name>contextconfiglocation</param-name>
<param-value>classpath:applicationcontext*.xml</param-value>
</context-param>
<!-- hibernate 懒加载的问题过滤 ,可以不配置 -->
<filter>
<description>hibernate session 过滤器</description>
<filter-name>opensessioninviewfilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.opensessioninviewfilter</filter-class>
</filter>
<filter-mapping>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<!-- struts配置 -->
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter</filter-class>
struts.xml配置
<struts>
<!-- 使用spring -->
<constant name="struts.objectfactory" value="spring" />
<constant name="struts.devmode" value="true" />
<constant name="struts.configuration.xml.reload" value="true" />
<package name="default" extends="struts-default" namespace="/">
<interceptors>
<!-- 使用权限拦截 -->
<interceptor name="authority" class="com.sshframe.zero.interceptor.authorityinterceptor"/>
<!-- 异常拦截 -->
<interceptor name="exceptioninterceptor" class="com.sshframe.zero.interceptor.exceptioninterceptor"/>
<!-- 解决struts安全漏洞,拦截所有的带有#号的url -->
<interceptor-stack name="basestack">
<interceptor-ref name="authority"/>
<interceptor-ref name="exceptioninterceptor"/>
<interceptor-ref name="params">
<param name="excludeparams">.*\\u0023.*</param>
</interceptor-ref>
<interceptor-ref name="defaultstack"/>
</interceptor-stack>
</interceptors>
<!-- 配置默认拦截器栈 -->
<default-interceptor-ref name="basestack"/>
<global-results>
<result name="login">/index.jsp</result>
<result name="error">/error.jsp</result>
</global-results>
</package>
</struts>
applicationcontext.xml配置:
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
xsi:schemalocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="datasource" class="org.apache.commons.dbcp.basicdatasource">
<property name="driverclassname" value="com.mysql.jdbc.driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/osdesignaid"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<bean id="sessionfactory"
class="org.springframework.orm.hibernate4.localsessionfactorybean">
<property name="datasource" ref="datasource" />
<property name="hibernateproperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.mysqldialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcacheregionfactory</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="packagestoscan">
<list>
<value>com.sshframe.zero.pojo</value>
<value>com.sshframe.test.pojo</value>
</list>
<aop:aspectj-autoproxy /><!-- 代理 -->
<!-- 定义事务管理器 -->
<bean id="txmanager" class="org.springframework.orm.hibernate4.hibernatetransactionmanager">
<property name="sessionfactory" ref="sessionfactory" />
<!-- 申明annotation 加载事务驱动 -->
<tx:annotation-driven transaction-manager="txmanager" proxy-target-class="true"/>
<tx:advice id="txadvice" transaction-manager="txmanager">
<tx:attributes>
<tx:method name="save*" propagation="required" />
<tx:method name="add*" propagation="required" />
<tx:method name="create*" propagation="required" />
<tx:method name="insert*" propagation="required" />
<tx:method name="update*" propagation="required" />
<tx:method name="merge*" propagation="required" />
<tx:method name="del*" propagation="required" />
<tx:method name="remove*" propagation="required" />
<tx:method name="put*" propagation="required" />
<tx:method name="use*" propagation="required"/>
<!--hibernate4必须配置为开启事务 否则 getcurrentsession()获取不到-->
<tx:method name="get*" propagation="required" read-only="true" />
<tx:method name="count*" propagation="required" read-only="true" />
<tx:method name="find*" propagation="required" read-only="true" />
<tx:method name="list*" propagation="required" read-only="true" />
<tx:method name="*" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config expose-proxy="true">
<!-- 只对业务逻辑层实施事务 -->
<aop:pointcut id="txpointcut" expression="execution(* cn.javass..service..*.*(..))" />
<aop:advisor advice-ref="txadvice" pointcut-ref="txpointcut"/>
</aop:config>
<!-- 自动扫描包 -->
<context:annotation-config />
<context:component-scan base-package="com.sshframe.zero.*,com.sshframe.test.*" annotation-config="true"/>
</beans>
三、写框架基类
改写基本的框架类了
basedao
package com.sshframe.zero.dao;
import java.io.serializable;
import java.lang.reflect.field;
import java.lang.reflect.parameterizedtype;
import java.lang.reflect.type;
import java.util.list;
import javax.persistence.id;
import org.hibernate.criteria;
import org.hibernate.hibernateexception;
import org.hibernate.query;
import org.hibernate.session;
import org.hibernate.sessionfactory;
import org.hibernate.criterion.example;
import org.springframework.beans.factory.annotation.autowired;
/**
* 基于hibernate的basedao
* spring3对hibernate4已经没有了hibernatedaosupport和hibernatetemplate的支持,使用了原生态的api
* @author 雪精灵
*
* @param <t>
*/
public class basedao<t extends serializable> {
@autowired
private sessionfactory sessionfactory;
//当前泛型类
@suppresswarnings("rawtypes")
private class entityclass;
//当前主键名称
private string pkname;
private final string hql_list_all;
private final string hql_count_all;
public class getentityclass() {
return entityclass;
}
public void setentityclass(class entityclass) {
this.entityclass = entityclass;
public basedao() {
//获取当前泛型类
type type = this.getclass().getgenericsuperclass();
if (type.tostring().indexof("basedao") != -1) {
parameterizedtype type1 = (parameterizedtype) type;
type[] types = type1.getactualtypearguments();
setentityclass((class) types[0]);
}else{
type = ((class)type).getgenericsuperclass();
}
getpkname();
hql_list_all="from "+this.entityclass.getsimplename()+" order by "+pkname+" desc";
hql_count_all="select count(*) from "+this.entityclass.getsimplename();
/**
* 获取主键名称
* @return
*/
public string getpkname() {
field[] fields = this.entityclass.getdeclaredfields();//反射类字段
for (field field : fields) {
field.isannotationpresent(id.class);
this.pkname=field.getname();
break;
return pkname;
* 保存实例
*
* @param t
* @throws hibernateexception
public void save(t t) throws hibernateexception{
session session=null;
try {
session=sessionfactory.opensession();
session.begintransaction();
session.save(t);
session.gettransaction().commit();
} catch (hibernateexception e) {
e.printstacktrace();
throw new hibernateexception(e);
}finally{
session.close();
* 修改实例
public void update(t t) throws hibernateexception{
session.update(t);
* 删除实例
public void delete(t t) throws hibernateexception{
session.delete(t);
* 获取实例
* @param id
@suppresswarnings("unchecked")
public t get(serializable id) throws exception{
t t=null;
t=(t) session.get(getentityclass(), id);
return t;
* 查询全部
public list<t> findall() throws exception {
list<t> list=null;
session = sessionfactory.opensession();
query query = session.createquery(hql_list_all);
list = query.list();
return list;
* 查询总数
public integer findallcount() throws exception {
integer count=0;
query query = session.createquery(hql_count_all);
list<?> list = query.list();
if(list!=null&&!list.isempty()){
count=((integer) list.get(0)).intvalue();
}
return count;
* qbc查询
* @param criteria
public list<t> findbycriteria(criteria criteria) throws exception {
criteria criteria1 = session.createcriteria(getentityclass());
criteria1=criteria;
list = criteria1.list();
* qbe查询
public list<t> findbyexample(t t) throws exception {
example example = example.create(t);
criteria criteria = session.createcriteria(getentityclass());
criteria.add(example);
list = criteria.list();
* hql查询
* @param hql
* @param objects
public list<object[]> findbyhql(string hql,final object...objects) throws exception{
list<object[]> list=null;
query query = session.createquery(hql);
for (int i = 0; i < objects.length; i++) {
query.setparameter(i, objects[i]);
} catch (exception e) {
* sql查询
public list<object[]> findbysql(string sql,final object...objects){
query query = sessionfactory.getcurrentsession().createsqlquery(sql);
}
baseservice
package com.sshframe.zero.service;
import com.sshframe.zero.dao.basedao;
public class baseservice<t extends serializable> {
protected basedao<t> basedao;
public void save(t t) throws exception{
basedao.save(t);
public void update(t t) throws exception{
basedao.update(t);
public void delete(t t) throws exception{
basedao.delete(t);
return basedao.get(id);
public list<t> findall() throws exception{
return basedao.findall();
public list<t> findbyexample(t t) throws exception{
return basedao.findbyexample(t);
public basedao<t> getbasedao() {
return basedao;
public void setbasedao(basedao<t> basedao) {
this.basedao = basedao;
}</t>
四、写7个pojo
package com.sshframe.zero.pojo;
import java.util.hashset;
import java.util.set;
import javax.persistence.cascadetype;
import javax.persistence.column;
import javax.persistence.entity;
import javax.persistence.fetchtype;
import javax.persistence.generatedvalue;
import javax.persistence.onetomany;
import javax.persistence.table;
import org.hibernate.annotations.genericgenerator;
@entity
@table(name="userinfo")
public class userinfo implements serializable{
private static final long serialversionuid = 1l;
private string userid;
private string username;
private string password;
private string depid;
private string dutyid;
private set<userrole> userroles=new hashset<userrole>();
@genericgenerator(name = "generator", strategy = "uuid")
@id
@generatedvalue(generator = "generator")
@column(name = "userid", unique = true, nullable = false, length = 50)
public string getuserid() {
return userid;
public void setuserid(string userid) {
this.userid = userid;
@column(name = "username", nullable = false, length = 50)
public string getusername() {
return username;
public void setusername(string username) {
this.username = username;
@column(name = "password", nullable = false, length = 50)
public string getpassword() {
return password;
public void setpassword(string password) {
this.password = password;
@column(name = "depid", nullable = false, length = 50)
public string getdepid() {
return depid;
public void setdepid(string depid) {
this.depid = depid;
@column(name = "dutyid", nullable = false, length = 50)
public string getdutyid() {
return dutyid;
public void setdutyid(string dutyid) {
this.dutyid = dutyid;
@onetomany(cascade=cascadetype.remove,mappedby="userinfo",fetch=fetchtype.lazy)
public set<userrole> getuserroles() {
return userroles;
public void setuserroles(set<userrole> userroles) {
this.userroles = userroles;
@table(name="role")
public class role implements serializable{
private string id;
private string name;
private set<rolerights> rolerights=new hashset<rolerights>();
@column(name = "id", unique = true, nullable = false, length = 50)
public string getid() {
return id;
public void setid(string id) {
this.id = id;
@column(name = "name", nullable = false, length = 50)
public string getname() {
return name;
public void setname(string name) {
this.name = name;
@onetomany(cascade=cascadetype.remove,fetch=fetchtype.lazy,mappedby="role")
public set<rolerights> getrolerights() {
return rolerights;
public void setrolerights(set<rolerights> rolerights) {
this.rolerights = rolerights;
@table(name="rights")
public class rights implements serializable{
@onetomany(cascade=cascadetype.remove,fetch=fetchtype.lazy,mappedby="rights")
@table(name="resources")
public class resources implements serializable{
private string url;
private set<rightsresources> rightsresourcs=new hashset<rightsresources>();
@column(name = "url", nullable = false, length = 100)
public string geturl() {
return url;
public void seturl(string url) {
this.url = url;
@onetomany(cascade=cascadetype.remove,fetch=fetchtype.lazy,mappedby="resources")
public set<rightsresources> getrightsresourcs() {
return rightsresourcs;
public void setrightsresourcs(set<rightsresources> rightsresourcs) {
this.rightsresourcs = rightsresourcs;
import javax.persistence.joincolumn;
import javax.persistence.manytoone;
@table(name="userrole")
public class userrole implements serializable{
private userinfo userinfo;
private role role;
@manytoone(fetch=fetchtype.lazy)
@joincolumn(name="userid")
public userinfo getuserinfo() {
return userinfo;
public void setuserinfo(userinfo userinfo) {
this.userinfo = userinfo;
@joincolumn(name="roleid")
public role getrole() {
return role;
public void setrole(role role) {
this.role = role;
@table(name="rolerights")
public class rolerights implements serializable{
private rights rights;
@joincolumn(name="rightsid")
public rights getrights() {
return rights;
public void setrights(rights rights) {
this.rights = rights;
@table(name="rightsresources")
public class rightsresources implements serializable{
private resources resources;
@joincolumn(name="resourcesid")
public resources getresources() {
return resources;
public void setresources(resources resources) {
this.resources = resources;
五、写各个service和action
userinfoservice 这个一定要注意,要在setuserinfodao方法里把当前的dao给basedao,否则,basedao会报空指针
package com.sshframe.zero.service.users;
import org.springframework.stereotype.component;
import org.springframework.stereotype.service;
import com.sshframe.zero.dao.users.userinfodao;
import com.sshframe.zero.pojo.userinfo;
import com.sshframe.zero.service.baseservice;
* 用户管理
@service
@component("userinfoservice")
public class userinfoservice extends baseservice<userinfo>{
private userinfodao userinfodao;
public userinfoservice() {
super();
public userinfo findlogin(string username,string password) throws exception{
userinfo userinfo=new userinfo();
userinfo.setusername(username);
userinfo.setpassword(password);
list<userinfo> userinfos = findbyexample(userinfo);
if(userinfos!=null&&!userinfos.isempty()){
userinfo=userinfos.get(0);
userinfo=null;
public list<?> used(string userid,string url) throws exception {
string hql="select ur.userinfo.userid,re.name,re.url from userrole ur,role r,rolerights rr,rights ri,rightsresources rs,resources re "+
"where ur.role.id=r.id and r.id=rr.role.id and rr.rights.id=ri.id and ri.id=rs.rights.id and rs.resources.id=re.id and "+
"ur.userinfo.userid=? and re.url=?";
list<?> userresource = userinfodao.findbyhql(hql,userid,url);
return userresource;
public userinfodao getuserinfodao() {
return userinfodao;
* 一定要用set方法注入,并赋值给basedao,否则basedao为null;
* 只适用于注入一个dao
* @param userinfodao
public void setuserinfodao(userinfodao userinfodao) {
super.setbasedao(userinfodao);
this.userinfodao = userinfodao;
</t>
package com.sshframe.zero.action.users;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import org.apache.struts2.convention.annotation.action;
import org.apache.struts2.convention.annotation.namespace;
import org.apache.struts2.convention.annotation.result;
import org.apache.struts2.interceptor.servletrequestaware;
import org.apache.struts2.interceptor.servletresponseaware;
import org.springframework.context.annotation.scope;
import com.opensymphony.xwork2.actionsupport;
import com.sshframe.zero.service.users.userinfoservice;
*
@namespace("/")
@scope("prototype")
@component("userinfoaction")
public class userinfoaction extends actionsupport implements servletrequestaware,servletresponseaware{
private httpservletrequest request;
private httpservletresponse response;
private userinfoservice userinfoservice;
@action(value="login",results={
@result(name="success",location="init.jsp"),
@result(name="failure",location="/index.jsp")
})
public string login(){
string username=request.getparameter("username");
string password=request.getparameter("password");
userinfo userinfo=null;
userinfo = userinfoservice.findlogin(username, password);
if(userinfo==null){
request.setattribute("msg", "用户名或密码错误");
return "failure";
request.getsession().setattribute("userid", userinfo.getuserid());
return "success";
public boolean used(string userid,string url) {
list<?> list=null;
list = userinfoservice.used(userid, url);
return false;
if(list!=null&&!list.isempty()){
return true;
return false;
@override
public void setservletresponse(httpservletresponse response) {
this.response=response;
public void setservletrequest(httpservletrequest request) {
this.request=request;
public userinfoservice getuserinfoservice() {
return userinfoservice;
public void setuserinfoservice(userinfoservice userinfoservice) {
this.userinfoservice = userinfoservice;
import org.apache.struts2.convention.annotation.parentpackage;
@namespace("/admin")
@parentpackage("default")
public class adminaction extends actionsupport implements servletrequestaware,servletresponseaware{
@action(value="init",results={@result(name="success",location="main.jsp"),
@result(name="failure",location="/index.jsp")})
public string init(){
string userid=(string) request.getsession().getattribute("userid");
system.out.println(userid);
return success;
六、加入拦截器
package com.sshframe.zero.interceptor;
import org.apache.struts2.servletactioncontext;
import com.opensymphony.xwork2.action;
import com.opensymphony.xwork2.actioninvocation;
import com.opensymphony.xwork2.interceptor.abstractinterceptor;
import com.sshframe.zero.action.users.userinfoaction;
import com.sshframe.zero.exception.ahcustomexception;
import com.sshframe.zero.exception.ahcustomexception.exccode;
* 用户权限拦截器,在struts.xml中配置
public class authorityinterceptor extends abstractinterceptor{
private static final long serialversionuid = 2914081148619842225l;
private userinfoaction userinfoaction;
public string intercept(actioninvocation invocation) throws exception {
httpservletrequest request = servletactioncontext.getrequest();
// string method = invocation.getproxy().getmethod();
// string actionname=invocation.getinvocationcontext().getname();
string userid = (string) request.getsession().getattribute("userid");
if(userid==null||"".equals(userid)){
request.setattribute("msg",ahcustomexception.getexcmessage(exccode.unlogined));
return action.error;
//获取项目路径
string contextpath=request.getservletcontext().getcontextpath();
//获取当前路径
string uri = request.getrequesturi();
//当前相对项目的路径
string actionurl=uri.replace(contextpath, "");
boolean used = userinfoaction.used(userid, actionurl);
if(used){
return invocation.invoke();
request.setattribute("msg",ahcustomexception.getexcmessage(exccode.invalidrights));
public userinfoaction getuserinfoaction() {
return userinfoaction;
public void setuserinfoaction(userinfoaction userinfoaction) {
this.userinfoaction = userinfoaction;
import org.apache.log4j.logger;
* 错误权限拦截器,在struts.xml中配置
public class exceptioninterceptor extends abstractinterceptor{
private logger logger=logger.getlogger(exceptioninterceptor.class);
private static final long serialversionuid = -3490533736557683231l;
private string excmessage="";
string result;
result = invocation.invoke();
logger.error("异常拦截器拦截到异常:"+"<br/>"+"uri为:"+uri+"<br/>"+e);
excmessage=ahcustomexception.getexcmessage(exccode.dataprocessing);
request.setattribute("msg", excmessage);
result=action.error;
}catch (nullpointerexception e) {
logger.error("异常拦截器拦截到异常:"+"<br/>"+"action的名称为:"+uri+"<br/>"+e);
excmessage=ahcustomexception.getexcmessage(exccode.illegaldata);
}catch (ahcustomexception e) {
excmessage=e.getexcmessage();
}catch (exception e) {
excmessage=ahcustomexception.getexcmessage(exccode.apperror);
return result;
七、自定义异常类
package com.sshframe.zero.exception;
* 自定义异常处理
public class ahcustomexception extends exception{
/**
* 错误类型标识
private exccode exccode = null;
public enum exccode{
apperror,
invalidrights,
illegaldata,
dataprocessing,
unlogined
public static final string[] excmessage = {
"内部异常",
"您没有执行本操作的权限",
"提供的数据为空或不合法",
"数据处理异常",
"您可能还没有登录本系统,或者已经超时,您必须先登录本系统后才能使用该功能<p><a href='../' target='_parent'>重新登录</a></p>"
};
public ahcustomexception(){
super(getexcmessage(exccode.apperror));
exccode = exccode.apperror;
* 构造函数
* @param arg0
* 错误类型标识
public ahcustomexception(exccode exccode) {
super(getexcmessage(exccode));
this.exccode = exccode;
* 根据错误类型标识获取错误信息
* @param emflag
* @return 错误信息
public static string getexcmessage(exccode exccode) {
return excmessage[exccode.ordinal()];
public string getexcmessage() {
/**
*
* @param arg1
* 被包含的异常对象
public ahcustomexception(exccode exccode, throwable throwable) {
super(getexcmessage(exccode), throwable);
setstacktrace(throwable.getstacktrace());
public ahcustomexception(throwable throwable) {
super(getexcmessage(throwable.getclass() == ahcustomexception.class ? ((ahcustomexception) throwable).exccode : exccode.apperror), throwable);
if (throwable.getclass() == ahcustomexception.class)
exccode = ((ahcustomexception) throwable).exccode;
else
exccode = exccode.apperror;
八、页面
index.jsp,在webcontent下
<%@ page language="java" import="java.util.*" pageencoding="utf-8"%>
<%
string path = request.getcontextpath();
string basepath = request.getscheme()+"://"+request.getservername()+":"+request.getserverport()+path+"/";
%>
<!doctype html public "-//w3c//dtd html 4.01 transitional//en">
<html>
<head>
<base href="<%=basepath%>">
<title>my jsp 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
${msg }
<form action="login" method="post">
<table>
<tbody>
<tr><td>用户名:</td><td><input type="text" name="username"/></td></tr>
<tr><td>密码:</td><td><input type="password" name="password"/></td></tr>
<tr><td colspan="2"><input type="submit" value="login"/></td></tr>
</tbody>
</table>
</form>
</body>
</html>
init.jsp.在web-inf/content/下
<title>my jsp 'init.jsp' starting page</title>
<script type="text/javascript">
window.onload=function(){
window.location.href="admin/init";
</script>
欢迎进入