系统里原来代码基本所有请求都集中在一个servlet里处理,然后用一大堆的if/else调用相应方法,这让我看得很不爽,于是就给切掉了...
就是根据注解来决定调用哪个方法,这样不管有多少个方法只要单纯地往上加就行了,不用管原来的(当然同名不行...)
对于需要访问权限的方法再加上Security注解,如果权限有分级,可以对Security扩展一下属性,再修改一下判断的方法...
其实哪有把这么多方法都放一个servlet里的........历史遗留...
以下具体步骤:
先是写了一个注解
Alias.java:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 在servlet的方法中设置别名注解,以方便反射获得转发方法
* @author hlw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Alias
{
/**
* url请求中的方法别名
* @return 方法别名
*/
String value();
}
再在每个方法上现加上注解, 比如:
@SuppressWarnings("unused")
@Alias("methoda")
private void method1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
OOXX;
}
@SuppressWarnings("unused")
@Alias("methodb")
private void method2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
OOXX;
}
......
对于需要访问权限的方法再写一个注解
Security.java:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 指明访问此资源需要权限
* @author hlw
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Security
{
boolean value() default true;
}
接着
@SuppressWarnings("unused")
@Security
@Alias("methodc")
private void method3(HttpServletRequest request, HttpServletResponse response)throws ServletException,
IOException{
OOXX;
}
......
然后是转发:
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException
{
request.setCharacterEncoding("UTF-8");
String methodName = request.getParameter("method");
dispatch(methodName, request, response);
}
private void dispatch(String methodName, HttpServletRequest request, HttpServletResponse response){
if(Utils.isBlank(methodName)) {
logger.warn("反射需要的方法名为空!");
//这里依具体情况输出提示
write("errormethod", response);
return;
}
if(!methods.containsKey(methodName)) {
logger.warn("[" + methodName + "]对应的方法不存在!");
//这里依具体情况输出提示
write("errormethod", response);
return;
}
try
{
Method method = methods.get(methodName);
boolean visitable = true;
if (method.isAnnotationPresent(Security.class))
{
if (!method.isAccessible()){
method.setAccessible(true);
}
if(method.getAnnotation(Security.class).value()){
visitable = ContextUtils.signed(request);//这里判断权限
}
}
//检查权限
if(visitable){
method.invoke(this, request, response);
}else{
//这里依具体情况输出提示
write("deny", response);
}
}
catch (IllegalArgumentException e)
{
//除非方法参数设计错误,否则不会发生!
throw new ControllerException(e);
}
catch (IllegalAccessException e)
{
//已在反射获取时处理,不会发生!
throw new ControllerException(e);
}
catch (InvocationTargetException e)
{
throw new ControllerException(e);
}catch(ControllerException e){
logger.error("反射调用方法出错!", e);
}
}
最后是初始化方法:
public OOXXServlet(){
super();
initMethods();
}
private void initMethods()
{
methods = new HashMap<String, Method>();
for (Method method : getClass().getDeclaredMethods())
{
if (method.isAnnotationPresent(Alias.class))
{
if (!method.isAccessible())
method.setAccessible(true);
methods.put(method.getAnnotation(Alias.class).value(), method);
}
}
}
当以OOXXServlet?method=methoda访问的时候就调用method1方法了...
还有一个是DBUnit根据hibernate配置来创建IDatabaseConnection的方法,有点难看:
/**
* 根据classpath文件db.properties中的db.hibernate.dialect
* 属性获取相应的DatabaseConnection
* @param conn 数据库连接
* @param schema 数据表
* @return 供dbunit使用的数据库连接
* @throws DatabaseUnitException
*/
public static IDatabaseConnection getIDatabaseConnection(Connection conn, String schema)
throws DatabaseUnitException
{
IDatabaseConnection connection;
try
{
Properties props = PropertiesUtils.loadProperties("db.properties");
String sqlDialect = props.getProperty("db.hibernate.dialect");
String methodName = "get"
+ sqlDialect.substring(sqlDialect.lastIndexOf('.')+1, sqlDialect.indexOf("Dialect")) + "Connection";
System.out.println(methodName);
Method method = DbUnitUtils.class.getMethod(methodName, Connection.class, String.class);
if (!method.isAccessible())
{
method.setAccessible(true);
}
connection = (IDatabaseConnection) method.invoke(null, conn, schema);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
catch (SecurityException e)
{
throw new RuntimeException(e);
}
catch (IllegalArgumentException e)
{
throw new RuntimeException(e);
}
catch (NoSuchMethodException e)
{
throw new RuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new RuntimeException(e);
}
catch (InvocationTargetException e)
{
throw new RuntimeException(e);
}
catch (RuntimeException e)
{
logger.error("调用方法名错误!", e);
connection = new DatabaseConnection(conn, schema);
e.printStackTrace();
}
return connection;
}
/*
* 获取 MySQLInnoDB DatabaseConnection
*/
public static IDatabaseConnection getMySQLInnoDBConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return new MySqlConnection(conn, schema);
}
/*
* 获取 MySQL5InnoDB DatabaseConnection
*/
public static IDatabaseConnection getMySQL5InnoDBConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return getMySQLInnoDBConnection(conn, schema);
}
/*
* 获取 MySQL DatabaseConnection
*/
public static IDatabaseConnection getMySQLConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return getMySQLInnoDBConnection(conn, schema);
}
/*
* 获取 MySQL5 DatabaseConnection
*/
public static IDatabaseConnection getMySQL5Connection(Connection conn, String schema)
throws DatabaseUnitException
{
return getMySQLInnoDBConnection(conn, schema);
}
/*
* 获取 MySQL5InnoDB DatabaseConnection
*/
public static IDatabaseConnection getMySQLMyISAMConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return getMySQLInnoDBConnection(conn, schema);
}
/*
* 获取 SQLServer DatabaseConnection
*/
public static IDatabaseConnection getSQLServerConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return new MsSqlConnection(conn, schema);
}
/*
* 获取 PostgreSQL DatabaseConnection
*/
public static IDatabaseConnection getPostgreSQLConnection(Connection conn, String schema)
throws DatabaseUnitException
{
IDatabaseConnection connection = new DatabaseConnection(conn, schema);
connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
new PostgresqlDataTypeFactory());
return connection;
}
/*
* 获取 Cgrs DatabaseConnection
*/
public static IDatabaseConnection getCgrsConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return getPostgreSQLConnection(conn, schema);
}
/*
* 获取 PostgresPlus DatabaseConnection
*/
public static IDatabaseConnection getPostgresPlusConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return getPostgreSQLConnection(conn, schema);
}
/*
* 获取 Oracle DatabaseConnection
*/
public static IDatabaseConnection getOracleConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return new OracleConnection(conn, schema);
}
/*
* 获取 Oracle8i DatabaseConnection
*/
public static IDatabaseConnection getOracle8iConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return getOracleConnection(conn, schema);
}
/*
* 获取 Oracle9 DatabaseConnection
*/
public static IDatabaseConnection getOracle9Connection(Connection conn, String schema)
throws DatabaseUnitException
{
return getOracleConnection(conn, schema);
}
/*
* 获取 Oracle9i DatabaseConnection
*/
public static IDatabaseConnection getOracle9iConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return getOracleConnection(conn, schema);
}
/*
* 获取 Oracle10g DatabaseConnection
*/
public static IDatabaseConnection getOracle10gConnection(Connection conn, String schema)
throws DatabaseUnitException
{
IDatabaseConnection connection = new OracleConnection(conn, schema);
connection.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
new Oracle10DataTypeFactory());
return connection;
}
/*
* 获取 H2 DatabaseConnection
*/
public static IDatabaseConnection getH2Connection(Connection conn, String schema)
throws DatabaseUnitException
{
return new H2Connection(conn, schema);
}
/*
* 获取 HSQL DatabaseConnection
*/
public static IDatabaseConnection getHSQLConnection(Connection conn, String schema)
throws DatabaseUnitException
{
return new HsqldbConnection(conn, schema);
}
/*
* 获取 DB2 DatabaseConnection
*/
public static IDatabaseConnection getDB2Connection(Connection conn, String schema)
throws DatabaseUnitException
{
return new Db2Connection(conn, schema);
}
使用的时候:
Connection conn = org.springframework.jdbc.datasource.DataSourceUtils.getConnection(dataSource);
IDatabaseConnection connection = getIDatabaseConnection(conn, "");
try
{
.....
......
}
catch (IOException e)
{
logger.warn(xmlPath + " file not found", e);
}
finally
{
org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(conn, dataSource);
}