系统里原来代码基本所有请求都集中在一个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();
}
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;
}
......
@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 ;
}
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;
}
......
@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);
}
}
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);
}
}
}
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);
}
* 根据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);
}
IDatabaseConnection connection = getIDatabaseConnection(conn, "" );
try
{
.....
......
}
catch (IOException e)
{
logger.warn(xmlPath + " file not found " , e);
}
finally
{
org.springframework.jdbc.datasource.DataSourceUtils.releaseConnection(conn, dataSource);
}