提交 b5aa43fb 编写于 作者: 黄勇

first commit

上级
target
*.iml
\ No newline at end of file
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
\ No newline at end of file
Smart Framework
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.smart</groupId>
<artifactId>smart-framework</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>provided</scope>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Log4J -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<!-- CGLib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- Apache Commons -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.8</version>
</dependency>
</dependencies>
<build>
<finalName>smart-framework</finalName>
</build>
</project>
package com.smart.framework;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
public class DataContext {
public static void put(String key, Object value) {
getSession().setAttribute(key, value);
}
@SuppressWarnings("unchecked")
public static <T> T get(String key) {
return (T) getSession().getAttribute(key);
}
public static void remove(String key) {
getSession().removeAttribute(key);
}
public static Map<String, Object> getAll() {
Map<String, Object> map = new HashMap<String, Object>();
Enumeration<String> names = getSession().getAttributeNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
map.put(name, getSession().getAttribute(name));
}
return map;
}
public static void removeAll() {
getSession().invalidate();
}
private static HttpSession getSession() {
return DispatcherServlet.getSession();
}
}
package com.smart.framework;
import com.smart.framework.helper.DBHelper;
import com.smart.framework.helper.SQLHelper;
import com.smart.framework.util.CastUtil;
import com.smart.framework.util.ObjectUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DataSet {
public static <T> T select(Class<T> cls, String condition, Object... params) {
String sql = SQLHelper.generateSelectSQL(cls, condition, params);
return DBHelper.queryBean(cls, sql);
}
public static <T> List<T> selectList(Class<T> cls, String condition, String order, Object... params) {
String sql = SQLHelper.generateSelectSQL(cls, condition, order, params);
return DBHelper.queryBeanList(cls, sql);
}
public static boolean insert(Class<?> cls, Map<String, Object> fieldMap) {
String sql = SQLHelper.generateInsertSQL(cls, fieldMap);
int rows = DBHelper.update(sql);
return rows > 0;
}
public static boolean update(Class<?> cls, Map<String, Object> fieldMap, String condition, Object... params) {
String sql = SQLHelper.generateUpdateSQL(cls, fieldMap, condition, params);
int rows = DBHelper.update(sql);
return rows > 0;
}
public static boolean delete(Class<?> cls, String condition, Object... params) {
String sql = SQLHelper.generateDeleteSQL(cls, "id = ?", params);
int rows = DBHelper.update(sql);
return rows > 0;
}
public static int selectCount(Class<?> cls, String condition, Object... params) {
String sql = SQLHelper.generateSelectSQLForCount(cls, condition, params);
return DBHelper.queryCount(cls, sql);
}
public static <T> List<T> selectListForPager(int pageNumber, int pageSize, Class<T> cls, String condition, String sort, Object... params) {
String sql = SQLHelper.generateSelectSQLForPager(pageNumber, pageSize, cls, condition, sort, params);
return DBHelper.queryBeanList(cls, sql);
}
public static <T> Map<Long, T> selectMap(Class<T> cls, String condition, Object... params) {
Map<Long, T> map = new HashMap<Long, T>();
List<T> list = selectList(cls, condition, "", params);
for (T obj : list) {
Long id = CastUtil.castLong(ObjectUtil.getFieldValue(obj, "id"));
map.put(id, obj);
}
return map;
}
}
package com.smart.framework;
import com.smart.framework.bean.ActionBean;
import com.smart.framework.bean.RequestBean;
import com.smart.framework.bean.Result;
import com.smart.framework.helper.ActionHelper;
import com.smart.framework.helper.BeanHelper;
import com.smart.framework.helper.InitHelper;
import com.smart.framework.util.CastUtil;
import com.smart.framework.util.MapUtil;
import com.smart.framework.util.StringUtil;
import com.smart.framework.util.WebUtil;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
@WebServlet(urlPatterns = "/*", loadOnStartup = 0)
public class DispatcherServlet extends HttpServlet {
private static final Logger logger = Logger.getLogger(DispatcherServlet.class);
private static final ThreadLocal<HttpSession> sessionContainer = new ThreadLocal<HttpSession>();
@Override
public void init(ServletConfig config) throws ServletException {
// 初始化 Helper 类
InitHelper.init();
// 添加 Servlet 映射
addServletMapping(config.getServletContext());
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 放入 Session
HttpSession session = request.getSession(false);
if (session != null) {
sessionContainer.set(session);
}
// 获取当前请求相关数据
String currentRequestMethod = request.getMethod();
String currentRequestURL = request.getPathInfo();
// 获取请求参数映射(包括:Query String 与 Form Data)
Map<String, String> requestParamMap = WebUtil.getRequestParamMap(request);
// 获取并遍历 Action 映射
Map<RequestBean, ActionBean> actionMap = ActionHelper.getActionMap();
for (Map.Entry<RequestBean, ActionBean> actionEntry : actionMap.entrySet()) {
// 从 RequestBean 中获取 Request 相关属性
RequestBean reqestBean = actionEntry.getKey();
String requestURL = reqestBean.getRequestURL(); // 正则表达式
String requestMethod = reqestBean.getRequestMethod();
// 获取正则表达式匹配器(用于匹配请求 URL 并从中获取相应的请求参数)
Matcher matcher = Pattern.compile(requestURL).matcher(currentRequestURL);
// 判断请求方法与请求 URL 是否同时匹配
if (requestMethod.equalsIgnoreCase(currentRequestMethod) && matcher.matches()) {
// 初始化 Action 对象
ActionBean actionBean = actionEntry.getValue();
// 初始化 Action 方法参数列表
List<Object> paramList = new ArrayList<Object>();
for (int i = 1; i <= matcher.groupCount(); i++) {
String param = matcher.group(i);
// 若为数字,则需要强制转型,并放入参数列表中
// 注意:必须转型为低级别类型(低级别类型可安全转换为高级别类型使用)
if (StringUtil.isNumber(param)) {
if (StringUtil.isDigits(param)) {
paramList.add(CastUtil.castInt(param));
} else {
paramList.add(CastUtil.castFloat(param));
}
} else {
paramList.add(param);
}
}
// 向参数列表中添加请求参数映射
if (MapUtil.isNotEmpty(requestParamMap)) {
paramList.add(requestParamMap);
}
// 从 ActionBean 中获取 Action 相关属性
Class<?> actionClass = actionBean.getActionClass();
Method actionMethod = actionBean.getActionMethod();
try {
// 创建 Action 实例
Object actionInstance = BeanHelper.getBean(actionClass);
// 调用 Action 方法(传入请求参数)
actionMethod.setAccessible(true); // 取消类型安全检测(可提高反射性能)
Object actionMethodResult = actionMethod.invoke(actionInstance, paramList.toArray());
if (actionMethodResult instanceof Result) {
// 获取 Action 方法返回值
Result result = (Result) actionMethodResult;
// 将返回值转为 JSON 格式并写入 Response 中
WebUtil.writeJSON(response, result);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
// 若成功匹配,则终止循环
break;
}
}
}
public static HttpSession getSession() {
HttpSession session = sessionContainer.get();
if (session == null) {
throw new RuntimeException("Can not get session!");
}
return session;
}
private void addServletMapping(ServletContext context) {
// 用 DefaultServlet 映射所有静态资源
ServletRegistration defaultServletRegistration = context.getServletRegistration("default");
defaultServletRegistration.addMapping("/favicon.ico", "/www/*");
// 用 UploadServlet 映射 /upload.do 请求
ServletRegistration uploadServletRegistration = context.getServletRegistration("upload");
uploadServletRegistration.addMapping("/upload.do");
}
}
package com.smart.framework;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
@WebFilter(
urlPatterns = "/*",
initParams = {
@WebInitParam(name = "encoding", value = "UTF-8")
}
)
public class EncodingFilter implements Filter {
private String encoding;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
encoding = filterConfig.getInitParameter("encoding");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
\ No newline at end of file
package com.smart.framework;
import com.smart.framework.annotation.Order;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
public class OrderedRunner extends BlockJUnit4ClassRunner {
// 定义一个静态变量,确保 computeTestMethods() 中的排序逻辑只运行一次(JUnit 会调用两次)
private static List<FrameworkMethod> testMethodList;
public OrderedRunner(Class<?> cls) throws InitializationError {
super(cls);
}
@Override
protected List<FrameworkMethod> computeTestMethods() {
if (testMethodList == null) {
// 获取带有 @Test 注解的方法
testMethodList = super.computeTestMethods();
// 获取测试方法上的 @Order 注解,并对所有的测试方法重新排序
Collections.sort(testMethodList, new Comparator<FrameworkMethod>() {
@Override
public int compare(FrameworkMethod m1, FrameworkMethod m2) {
Order o1 = m1.getAnnotation(Order.class);
Order o2 = m2.getAnnotation(Order.class);
if (o1 == null || o2 == null) {
return 0;
}
return o1.value() - o2.value();
}
});
}
return testMethodList;
}
}
package com.smart.framework;
import com.smart.framework.annotation.Transaction;
import com.smart.framework.helper.DBHelper;
import java.lang.reflect.Method;
import java.sql.Connection;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.log4j.Logger;
public class TransactionProxy implements MethodInterceptor {
private static final Logger logger = Logger.getLogger(TransactionProxy.class);
private static final TransactionProxy instance = new TransactionProxy();
private TransactionProxy() {
}
public static TransactionProxy getInstance() {
return instance;
}
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls, this);
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object result;
if (method.isAnnotationPresent(Transaction.class)) {
try {
// 开启事务
DBHelper.beginTransaction();
// 设置事务隔离级别
Transaction transaction = method.getAnnotation(Transaction.class);
int currentIsolation = transaction.isolation();
int defalutIsolation = DBHelper.getDefaultIsolationLevel();
if (currentIsolation != defalutIsolation) {
Connection conn = DBHelper.getConnectionFromThreadLocal();
conn.setTransactionIsolation(currentIsolation);
}
// 执行操作
method.setAccessible(true);
result = methodProxy.invokeSuper(proxy, args);
// 提交事务
DBHelper.commitTransaction();
} catch (Exception e) {
// 回滚事务
DBHelper.rollbackTransaction();
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
} else {
result = methodProxy.invokeSuper(proxy, args);
}
return result;
}
}
package com.smart.framework;
import com.smart.framework.bean.Result;
import com.smart.framework.util.WebUtil;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@MultipartConfig
@WebServlet(name = "upload", urlPatterns = "/upload.do")
public class UploadServlet extends HttpServlet {
private static final String UPLOAD_BASE_PATH = "www/upload/"; // 文件上传基础路径
private static final String UPLOAD_RELATIVE_PATH = "path"; // 文件上传相对路径
private static final String UPLOAD_FILE_NAME = "file"; // 文件标签的 file 名称
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取文件路径
String relativePath = request.getParameter(UPLOAD_RELATIVE_PATH);
String filePath = WebUtil.getFilePath(request, UPLOAD_BASE_PATH + relativePath);
// 获取文件名
Part part = request.getPart(UPLOAD_FILE_NAME);
String fileName = WebUtil.getFileName(request, part);
// 写入文件
part.write(filePath + "/" + fileName);
// 返回结果
Map<String, Object> data = new HashMap<String, Object>();
data.put("fileName", fileName);
data.put("fileType", part.getContentType());
data.put("fileSize", part.getSize());
WebUtil.writeJSON(response, new Result(true).data(data));
}
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Aspect {
String pkg();
String cls() default "";
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Bean {
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Impl {
Class<?> value();
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Inject {
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
int value();
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Request {
String value();
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}
package com.smart.framework.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.sql.Connection;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transaction {
int isolation() default Connection.TRANSACTION_READ_COMMITTED;
}
package com.smart.framework.base;
public abstract class BaseAction {
protected static final int ERROR_PARAM = 10; // 参数有误
protected static final int ERROR_DATA = 20; // 数据有误
}
package com.smart.framework.base;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.log4j.Logger;
public abstract class BaseAspect implements MethodInterceptor {
private static final Logger logger = Logger.getLogger(BaseAspect.class);
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls, this);
}
@Override
public Object intercept(Object proxy, Method methodTarget, Object[] args, MethodProxy methodProxy) throws Throwable {
begin(methodTarget, args);
Object result = null;
try {
if (filter(methodTarget, args)) {
before(methodTarget, args);
result = methodProxy.invokeSuper(proxy, args);
after(methodTarget, args);
} else {
result = methodProxy.invokeSuper(proxy, args);
}
} catch (Exception e) {
error(methodTarget, args, e);
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
} finally {
end(methodTarget, args);
}
return result;
}
protected void begin(Method method, Object[] args) {
}
protected boolean filter(Method method, Object[] args) {
return true;
}
protected void before(Method method, Object[] args) {
}
protected void after(Method method, Object[] args) {
}
protected void error(Method method, Object[] args, Exception e) {
}
protected void end(Method method, Object[] args) {
}
}
package com.smart.framework.base;
import com.smart.framework.util.JSONUtil;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
public abstract class BaseBean implements Serializable {
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
public String toJson() {
return JSONUtil.toJSON(this);
}
}
package com.smart.framework.base;
public abstract class BaseEntity extends BaseBean {
private long id;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
package com.smart.framework.base;
import java.sql.Connection;
public abstract class BaseService {
// 事务隔离级别
protected static final int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
protected static final int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
protected static final int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
protected static final int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
}
package com.smart.framework.base;
import com.smart.framework.OrderedRunner;
import com.smart.framework.helper.DBHelper;
import com.smart.framework.helper.InitHelper;
import com.smart.framework.util.ClassUtil;
import java.io.File;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.junit.runner.RunWith;
@RunWith(OrderedRunner.class)
public abstract class BaseTest {
private static final Logger logger = Logger.getLogger(BaseTest.class);
protected BaseTest() {
InitHelper.init();
}
protected static void initSQL(String sqlPath) {
try {
File sqlFile = new File(ClassUtil.getClassPath() + sqlPath);
List<String> sqlList = FileUtils.readLines(sqlFile);
for (String sql : sqlList) {
DBHelper.update(sql);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
}
package com.smart.framework.bean;
import java.lang.reflect.Method;
public class ActionBean {
private Class<?> actionClass;
private Method actionMethod;
public ActionBean(Class<?> actionClass, Method actionMethod) {
this.actionClass = actionClass;
this.actionMethod = actionMethod;
}
public Class<?> getActionClass() {
return actionClass;
}
public void setActionClass(Class<?> actionClass) {
this.actionClass = actionClass;
}
public Method getActionMethod() {
return actionMethod;
}
public void setActionMethod(Method actionMethod) {
this.actionMethod = actionMethod;
}
}
package com.smart.framework.bean;
import com.smart.framework.base.BaseBean;
import java.util.List;
public class Pager<T> extends BaseBean {
private int pageNumber; // 页面编号
private int pageSize; // 每页条数
private int totalRecord; // 总记录数
private List<T> recordList; // 数据列表
public Pager(int pageNumber, int pageSize, int totalRecord, List<T> recordList) {
this.pageNumber = pageNumber;
this.pageSize = pageSize;
this.totalRecord = totalRecord;
this.recordList = recordList;
}
public int getTotalPage() {
return totalRecord % pageSize == 0 ? totalRecord / pageSize : totalRecord / pageSize + 1;
}
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
}
public List<T> getRecordList() {
return recordList;
}
public void setRecordList(List<T> recordList) {
this.recordList = recordList;
}
}
package com.smart.framework.bean;
public class RequestBean {
private String requestMethod;
private String requestURL;
public RequestBean(String requestMethod, String requestURL) {
this.requestMethod = requestMethod;
this.requestURL = requestURL;
}
public String getRequestMethod() {
return requestMethod;
}
public void setRequestMethod(String requestMethod) {
this.requestMethod = requestMethod;
}
public String getRequestURL() {
return requestURL;
}
public void setRequestURL(String requestURL) {
this.requestURL = requestURL;
}
}
package com.smart.framework.bean;
import com.smart.framework.base.BaseBean;
public class Result extends BaseBean {
private boolean success = false;
private int error = 0;
private Object data = null;
public Result(boolean success) {
this.success = success;
}
public Result data(Object data) {
this.data = data;
return this;
}
public Result error(int error) {
this.error = error;
return this;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public int getError() {
return error;
}
public void setError(int error) {
this.error = error;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
package com.smart.framework.helper;
import com.smart.framework.annotation.Aspect;
import com.smart.framework.base.BaseAspect;
import com.smart.framework.util.CollectionUtil;
import com.smart.framework.util.ObjectUtil;
import com.smart.framework.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
public class AOPHelper {
private static final Logger logger = Logger.getLogger(AOPHelper.class);
static {
if (logger.isInfoEnabled()) {
logger.info("Init AOPHelper...");
}
try {
// 获取并遍历所有的 Aspect 类(切面类)
List<Class<?>> aspectClassList = ClassHelper.getClassListBySuper(BaseAspect.class);
for (Class<?> aspectClass : aspectClassList) {
// 判断 @Aspect 注解是否存在
if (aspectClass.isAnnotationPresent(Aspect.class)) {
// 获取 @Aspect 注解中的属性值
Aspect aspect = aspectClass.getAnnotation(Aspect.class);
String pkg = aspect.pkg(); // 包名
String cls = aspect.cls(); // 类名
// 初始化目标类列表
List<Class<?>> targetClassList = new ArrayList<Class<?>>();
if (StringUtil.isNotEmpty(pkg) && StringUtil.isNotEmpty(cls)) {
// 如果包名与类名均不为空,则添加指定类
targetClassList.add(Class.forName(pkg + "." + cls));
} else {
// 否则(包名不为空)添加该包名下所有类
targetClassList.addAll(ClassHelper.getClassListByPackage(pkg));
}
// 遍历目标类列表
if (CollectionUtil.isNotEmpty(targetClassList)) {
// 创建父切面类
BaseAspect baseAspect = (BaseAspect) aspectClass.newInstance();
for (Class<?> targetClass : targetClassList) {
// 获取目标实例
Object targetInstance = BeanHelper.getBean(targetClass);
// 创建代理实例
Object proxyInstance = baseAspect.getProxy(targetClass);
// 复制目标实例中的成员变量到代理实例中
ObjectUtil.copyFields(targetInstance, proxyInstance);
// 用代理实体覆盖目标实例
BeanHelper.getBeanMap().put(targetClass, proxyInstance);
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
}
package com.smart.framework.helper;
import com.smart.framework.annotation.Request;
import com.smart.framework.base.BaseAction;
import com.smart.framework.bean.ActionBean;
import com.smart.framework.bean.RequestBean;
import com.smart.framework.util.ArrayUtil;
import com.smart.framework.util.StringUtil;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
public class ActionHelper {
private static final Logger logger = Logger.getLogger(ActionHelper.class);
// RequestBean => ActionBean
private static final Map<RequestBean, ActionBean> actionMap = new HashMap<RequestBean, ActionBean>();
static {
if (logger.isInfoEnabled()) {
logger.info("Init ActionHelper...");
}
// 获取并遍历所有 Action 类
List<Class<?>> actionClassList = ClassHelper.getClassListBySuper(BaseAction.class);
for (Class<?> actionClass : actionClassList) {
// 获取并遍历该 Action 类中所有的方法(不包括父类中的方法)
Method[] actionMethods = actionClass.getDeclaredMethods();
if (ArrayUtil.isNotEmpty(actionMethods)) {
for (Method actionMethod : actionMethods) {
// 判断当前 Action 方法是否带有 @Request 注解
if (actionMethod.isAnnotationPresent(Request.class)) {
// 获取 @Requet 注解中的 URL 字符串
String[] urlArray = StringUtil.splitString(actionMethod.getAnnotation(Request.class).value(), ":");
if (ArrayUtil.isNotEmpty(urlArray)) {
// 获取请求方法与请求 URL
String requestMethod = urlArray[0];
String requestURL = urlArray[1]; // 带有占位符
// 将请求 URL 中的占位符转换为 (\d+)(正则表达式)
requestURL = StringUtil.replaceAll(requestURL, "\\{\\w+\\}", "(\\\\w+)");
// 将 RequestBean 与 ActionBean 放入 Action Map 中
actionMap.put(new RequestBean(requestMethod, requestURL), new ActionBean(actionClass, actionMethod));
}
}
}
}
}
}
public static Map<RequestBean, ActionBean> getActionMap() {
return actionMap;
}
}
package com.smart.framework.helper;
import com.smart.framework.annotation.Bean;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
public class BeanHelper {
private static final Logger logger = Logger.getLogger(BeanHelper.class);
// Bean 类 => Bean 实例
private static final Map<Class<?>, Object> beanMap = new HashMap<Class<?>, Object>();
static {
if (logger.isInfoEnabled()) {
logger.info("Init BeanHelper...");
}
try {
// 获取并遍历所有的 Bean(带有 @Bean 注解的类)
List<Class<?>> beanClassList = ClassHelper.getClassListByAnnotation(Bean.class);
for (Class<?> beanClass : beanClassList) {
// 创建 Bean 实例
Object beanInstance = beanClass.newInstance();
// 将 Bean 实例放入 Bean Map 中(键为 Bean 类,值为 Bean 实例)
beanMap.put(beanClass, beanInstance);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
public static Map<Class<?>, Object> getBeanMap() {
return beanMap;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> cls) {
return (T) beanMap.get(cls);
}
}
package com.smart.framework.helper;
import com.smart.framework.util.ClassUtil;
import java.lang.annotation.Annotation;
import java.util.List;
public class ClassHelper {
private static final String packageName = ConfigHelper.getStringProperty("package.name");
public static List<Class<?>> getClassListByPackage(String pkg) {
return ClassUtil.getClassList(pkg, true);
}
public static List<Class<?>> getClassListBySuper(Class<?> superClass) {
return ClassUtil.getClassListBySuper(packageName, superClass);
}
public static List<Class<?>> getClassListByInterface(Class<?> interfaceClass) {
return ClassUtil.getClassListByInterface(packageName, interfaceClass);
}
public static List<Class<?>> getClassListByAnnotation(Class<? extends Annotation> annotationClass) {
return ClassUtil.getClassListByAnnotation(packageName, annotationClass);
}
}
package com.smart.framework.helper;
import com.smart.framework.util.FileUtil;
import com.smart.framework.util.StringUtil;
import java.util.Properties;
public class ConfigHelper {
private static final Properties configProperties = FileUtil.loadPropFile("config.properties");
public static String getStringProperty(String key) {
String value = "";
if (configProperties.containsKey(key)) {
value = configProperties.getProperty(key);
} else {
System.err.println("Can not get property [" + key + "] in config.properties file.");
}
return value;
}
public static int getNumberProperty(String key) {
int value = 0;
String sValue = getStringProperty(key);
if (StringUtil.isNumber(sValue)) {
value = Integer.parseInt(sValue);
}
return value;
}
}
package com.smart.framework.helper;
import com.smart.framework.util.CastUtil;
import com.smart.framework.util.DBUtil;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.log4j.Logger;
public class DBHelper {
private static final Logger logger = Logger.getLogger(DBHelper.class);
private static final BasicDataSource ds = new BasicDataSource();
private static final QueryRunner runner = new QueryRunner(ds);
private static String databaseType;
// 定义一个局部线程变量(使每个线程都拥有自己的连接)
private static ThreadLocal<Connection> connContainer = new ThreadLocal<Connection>();
static {
if (logger.isInfoEnabled()) {
logger.info("Init DBHelper...");
}
// 初始化数据源
ds.setDriverClassName(ConfigHelper.getStringProperty("jdbc.driver"));
ds.setUrl(ConfigHelper.getStringProperty("jdbc.url"));
ds.setUsername(ConfigHelper.getStringProperty("jdbc.username"));
ds.setPassword(ConfigHelper.getStringProperty("jdbc.password"));
ds.setMaxActive(ConfigHelper.getNumberProperty("jdbc.max.active"));
ds.setMaxIdle(ConfigHelper.getNumberProperty("jdbc.max.idle"));
// 获取数据库类型
try {
databaseType = ds.getConnection().getMetaData().getDatabaseProductName();
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
// 获取数据源
public static DataSource getDataSource() {
return ds;
}
// 从数据源中获取数据库连接
public static Connection getConnectionFromDataSource() {
Connection conn;
try {
conn = ds.getConnection();
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return conn;
}
// 从线程局部变量中获取数据库连接
public static Connection getConnectionFromThreadLocal() {
return connContainer.get();
}
// 开启事务
public static void beginTransaction() {
Connection conn = getConnectionFromThreadLocal();
if (conn == null) {
try {
conn = getConnectionFromDataSource();
conn.setAutoCommit(false);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
} finally {
connContainer.set(conn);
}
}
}
// 提交事务
public static void commitTransaction() {
Connection conn = getConnectionFromThreadLocal();
if (conn != null) {
try {
conn.commit();
conn.close();
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
} finally {
connContainer.remove();
}
}
}
// 回滚事务
public static void rollbackTransaction() {
Connection conn = getConnectionFromThreadLocal();
if (conn != null) {
try {
conn.rollback();
conn.close();
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
} finally {
connContainer.remove();
}
}
}
// 获取数据库默认事务隔离级别
public static int getDefaultIsolationLevel() {
int level;
try {
level = getConnectionFromThreadLocal().getMetaData().getDefaultTransactionIsolation();
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return level;
}
// 获取数据库类型
public static String getDBType() {
return databaseType;
}
// 执行查询(返回一个对象)
public static <T> T queryBean(Class<T> cls, String sql, Object... params) {
Map<String, String> map = EntityHelper.getEntityMap().get(cls);
return DBUtil.queryBean(runner, cls, map, sql, params);
}
// 执行查询(返回多个对象)
public static <T> List<T> queryBeanList(Class<T> cls, String sql, Object... params) {
Map<String, String> map = EntityHelper.getEntityMap().get(cls);
return DBUtil.queryBeanList(runner, cls, map, sql, params);
}
// 执行更新(包括 UPDATE、INSERT、DELETE)
public static int update(String sql, Object... params) {
// 若当前线程中存在连接,则传入(用于事务处理),否则将从数据源中获取连接
Connection conn = getConnectionFromThreadLocal();
return DBUtil.update(runner, conn, sql, params);
}
// 执行查询(返回 count 结果)
public static int queryCount(Class<?> cls, String sql, Object... params) {
return CastUtil.castInt(DBUtil.queryColumn(runner, "count(*)", sql, params));
}
// 查询映射列表
public static List<Map<String, Object>> queryMapList(String sql, Object... params) {
return DBUtil.queryMapList(runner, sql, params);
}
// 查询单列数据
public static Object queryColumn(String column, String sql, Object... params) {
return DBUtil.queryColumn(runner, column, sql, params);
}
}
package com.smart.framework.helper;
import com.smart.framework.annotation.Column;
import com.smart.framework.base.BaseEntity;
import com.smart.framework.util.ArrayUtil;
import com.smart.framework.util.MapUtil;
import com.smart.framework.util.StringUtil;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
public class EntityHelper {
private static final Logger logger = Logger.getLogger(EntityHelper.class);
// Entity 类 => (列名 => 字段名)
private static final Map<Class<?>, Map<String, String>> entityMap = new HashMap<Class<?>, Map<String, String>>();
static {
if (logger.isInfoEnabled()) {
logger.info("Init EntityHelper...");
}
// 获取并遍历所有 Entity 类
List<Class<?>> entityClassList = ClassHelper.getClassListBySuper(BaseEntity.class);
for (Class<?> entityClass : entityClassList) {
// 获取并遍历该 Entity 类中所有的字段(不包括父类中的方法)
Field[] fields = entityClass.getDeclaredFields();
if (ArrayUtil.isNotEmpty(fields)) {
// 创建一个 Field Map(用于存放列名与字段名的映射关系)
Map<String, String> fieldMap = new HashMap<String, String>();
for (Field field : fields) {
String fieldName = field.getName();
String columnName;
// 若该字段上存在 @Column 注解,则优先获取注解中的列名
if (field.isAnnotationPresent(Column.class)) {
columnName = field.getAnnotation(Column.class).value();
} else {
columnName = StringUtil.toUnderline(fieldName); // 将驼峰风格替换为下划线风格
}
// 若字段名与列名不同,则需要进行映射
if (!fieldName.equals(columnName)) {
fieldMap.put(columnName, fieldName);
}
}
// 将 Entity 类与 Field Map 放入 Entity Map 中
if (MapUtil.isNotEmpty(fieldMap)) {
entityMap.put(entityClass, fieldMap);
}
}
}
}
public static Map<Class<?>, Map<String, String>> getEntityMap() {
return entityMap;
}
}
package com.smart.framework.helper;
import com.smart.framework.annotation.Impl;
import com.smart.framework.annotation.Inject;
import com.smart.framework.util.ArrayUtil;
import com.smart.framework.util.CollectionUtil;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
public class IOCHelper {
private static final Logger logger = Logger.getLogger(IOCHelper.class);
static {
if (logger.isInfoEnabled()) {
logger.info("Init IOCHelper...");
}
try {
// 获取并遍历所有的 Bean 类
Map<Class<?>, Object> beanMap = BeanHelper.getBeanMap();
for (Map.Entry<Class<?>, Object> beanEntry : beanMap.entrySet()) {
// 获取 Bean 类与 Bean 实例
Class<?> beanClass = beanEntry.getKey();
Object beanInstance = beanEntry.getValue();
// 获取 Bean 类中所有的字段(不包括父类中的方法)
Field[] beanFields = beanClass.getDeclaredFields();
if (ArrayUtil.isNotEmpty(beanFields)) {
// 遍历所有的 Bean 字段
for (Field beanField : beanFields) {
// 判断当前 Bean 字段是否带有 @Inject 注解
if (beanField.isAnnotationPresent(Inject.class)) {
// 获取 Bean 字段对应的接口
Class<?> interfaceClass = beanField.getType();
// 判断接口上是否标注了 @Impl 注解
Class<?> implementClass = null;
if (interfaceClass.isAnnotationPresent(Impl.class)) {
// 获取强制指定的实现类
implementClass = interfaceClass.getAnnotation(Impl.class).value();
} else {
// 获取该接口所有的实现类
List<Class<?>> implementClassList = ClassHelper.getClassListByInterface(interfaceClass);
if (CollectionUtil.isNotEmpty(implementClassList)) {
// 获取第一个实现类
implementClass = implementClassList.get(0);
}
}
// 若存在实现类,则执行以下代码
if (implementClass != null) {
// 从 Bean Map 中获取该实现类对应的实现类实例
Object implementInstance = beanMap.get(implementClass);
// 设置该 Bean 字段的值
if (implementInstance != null) {
beanField.setAccessible(true); // 取消类型安全检测(可提高反射性能)
beanField.set(beanInstance, implementInstance); // beanInstance 是普通实例,或 CGLib 动态代理实例(不能使 JDK 动态代理实例)
}
}
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
}
package com.smart.framework.helper;
import org.apache.log4j.Logger;
public class InitHelper {
private static final Logger logger = Logger.getLogger(InitHelper.class);
public static void init() {
try {
Class<?>[] classList = {
DBHelper.class,
EntityHelper.class,
ActionHelper.class,
BeanHelper.class,
ServiceHelper.class,
IOCHelper.class,
AOPHelper.class,
};
for (Class<?> cls : classList) {
Class.forName(cls.getName());
}
} catch (ClassNotFoundException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
}
package com.smart.framework.helper;
import com.smart.framework.annotation.Table;
import com.smart.framework.util.ArrayUtil;
import com.smart.framework.util.FileUtil;
import com.smart.framework.util.MapUtil;
import com.smart.framework.util.StringUtil;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SQLHelper {
private static final Properties sqlProperties = FileUtil.loadPropFile("sql.properties");
public static String getSQL(String key) {
String value = "";
if (sqlProperties.containsKey(key)) {
value = sqlProperties.getProperty(key);
} else {
System.err.println("Can not get property [" + key + "] in sql.properties file.");
}
return value;
}
public static String generateSelectSQL(Class<?> cls, String condition, Object... params) {
StringBuilder sql = new StringBuilder("select * from ").append(getTable(cls));
sql.append(generateWhere(condition, params));
return sql.toString();
}
public static String generateInsertSQL(Class<?> cls, Map<String, Object> fieldMap) {
StringBuilder sql = new StringBuilder("insert into ").append(getTable(cls));
if (MapUtil.isNotEmpty(fieldMap)) {
int i = 0;
StringBuilder columns = new StringBuilder(" ");
StringBuilder values = new StringBuilder(" values ");
for (Map.Entry<String, ?> fieldEntry : fieldMap.entrySet()) {
String columnName = StringUtil.toUnderline(fieldEntry.getKey());
Object columnValue = fieldEntry.getValue();
if (i == 0) {
columns.append("(").append(columnName);
values.append("('").append(columnValue).append("'");
} else if (i == fieldMap.size() - 1) {
columns.append(", ").append(columnName).append(")");
values.append(", '").append(columnValue).append("')");
} else {
columns.append(", ").append(columnName);
values.append(", '").append(columnValue).append("'");
}
i++;
}
sql.append(columns).append(values);
}
return sql.toString();
}
public static String generateDeleteSQL(Class<?> cls, String condition, Object... params) {
StringBuilder sql = new StringBuilder("delete from ").append(getTable(cls));
sql.append(generateWhere(condition, params));
return sql.toString();
}
public static String generateUpdateSQL(Class<?> cls, Map<String, Object> fieldMap, String condition, Object... params) {
StringBuilder sql = new StringBuilder("update ").append(getTable(cls));
if (MapUtil.isNotEmpty(fieldMap)) {
sql.append(" set ");
int i = 0;
for (Map.Entry<String, ?> fieldEntry : fieldMap.entrySet()) {
String columnName = StringUtil.toUnderline(fieldEntry.getKey());
Object columnValue = fieldEntry.getValue();
if (i == 0) {
sql.append(columnName).append(" = '").append(columnValue).append("'");
} else {
sql.append(", ").append(columnName).append(" = '").append(columnValue).append("'");
}
i++;
}
}
sql.append(generateWhere(condition, params));
return sql.toString();
}
public static String generateSelectSQLForCount(Class<?> cls, String condition, Object... params) {
StringBuilder sql = new StringBuilder("select count(*) from ").append(getTable(cls));
sql.append(generateWhere(condition, params));
return sql.toString();
}
public static String generateSelectSQLForPager(int pageNumber, int pageSize, Class<?> cls, String condition, String sort, Object... params) {
StringBuilder sql = new StringBuilder();
String table = getTable(cls);
String where = generateWhere(condition, params);
String order = generateOrder(sort);
String dbType = DBHelper.getDBType();
if (dbType.equalsIgnoreCase("mysql")) {
int pageStart = (pageNumber - 1) * pageSize;
int pageEnd = pageSize;
appendSQLForMySQL(sql, table, where, order, pageStart, pageEnd);
} else if (dbType.equalsIgnoreCase("oracle")) {
int pageStart = (pageNumber - 1) * pageSize + 1;
int pageEnd = pageStart + pageSize;
appendSQLForOracle(sql, table, where, order, pageStart, pageEnd);
} else if (dbType.equalsIgnoreCase("mssql")) {
int pageStart = (pageNumber - 1) * pageSize;
int pageEnd = pageSize;
appendSQLForSQLServer(sql, table, where, order, pageStart, pageEnd);
} else if (dbType.equalsIgnoreCase("db2")) {
// DB2
} else if (dbType.equalsIgnoreCase("sybase")) {
// Sybase
} else if (dbType.equalsIgnoreCase("derby")) {
// Derby
} else if (dbType.equalsIgnoreCase("postgre")) {
// Postgre
} else if (dbType.equalsIgnoreCase("hsql")) {
// HSQL
} else if (dbType.equalsIgnoreCase("h2")) {
// H2
}
return sql.toString();
}
private static String getTable(Class<?> cls) {
String tableName;
if (cls.isAnnotationPresent(Table.class)) {
tableName = cls.getAnnotation(Table.class).value();
} else {
tableName = StringUtil.toUnderline(cls.getSimpleName());
}
return tableName;
}
private static String generateWhere(String condition, Object[] params) {
StringBuilder builder = new StringBuilder();
if (StringUtil.isNotEmpty(condition)) {
StringBuffer buffer = new StringBuffer();
if (ArrayUtil.isNotEmpty(params)) {
Matcher matcher = Pattern.compile("\\?").matcher(condition);
for (int i = 0; matcher.find(); i++) {
String param = params[i].toString();
if (StringUtil.isNumber(param)) {
matcher.appendReplacement(buffer, param);
} else {
matcher.appendReplacement(buffer, "'" + param + "'");
}
}
matcher.appendTail(buffer);
builder.append(" where ").append(buffer);
} else {
builder.append(" where ").append(condition);
}
}
return builder.toString();
}
private static String generateOrder(String order) {
StringBuilder builder = new StringBuilder();
if (StringUtil.isNotEmpty(order)) {
builder.append(" order by ").append(order);
}
return builder.toString();
}
private static void appendSQLForMySQL(StringBuilder sql, String table, String where, String order, int pageStart, int pageEnd) {
/*
select * from 表名 where 条件 order by 排序 limit 开始位置, 结束位置
*/
sql.append("select * from ").append(table);
sql.append(where);
sql.append(order);
sql.append(" limit ").append(pageStart).append(", ").append(pageEnd);
}
private static void appendSQLForOracle(StringBuilder sql, String table, String where, String order, int pageStart, int pageEnd) {
/*
select a.* from (
select rownum rn, t.* from 表名 t where 条件 order by 排序
) a
where a.rn >= 开始位置 and a.rn < 结束位置
*/
sql.append("select a.* from (select rownum rn, t.* from ").append(table).append(" t");
sql.append(where);
sql.append(order);
sql.append(") a where a.rn >= ").append(pageStart).append(" and a.rn < ").append(pageEnd);
}
private static void appendSQLForSQLServer(StringBuilder sql, String table, String where, String order, int pageStart, int pageEnd) {
/*
select top 结束位置 * from 表名 where 条件 and id not in (
select top 开始位置 id from 表名 where 条件 order by 排序
) order by 排序
*/
sql.append("select top ").append(pageEnd).append(" * from ").append(table);
if (StringUtil.isNotEmpty(where)) {
sql.append(where).append(" and ");
} else {
sql.append(" where ");
}
sql.append("id not in (select top ").append(pageStart).append(" id from ").append(table);
sql.append(where);
sql.append(order);
sql.append(") ").append(order);
}
}
package com.smart.framework.helper;
import com.smart.framework.TransactionProxy;
import com.smart.framework.base.BaseService;
import com.smart.framework.util.ObjectUtil;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
public class ServiceHelper {
private static final Logger logger = Logger.getLogger(ServiceHelper.class);
static {
if (logger.isInfoEnabled()) {
logger.info("Init ServiceHelper...");
}
try {
// 获取并遍历所有的 Service 类
List<Class<?>> serviceClassList = ClassHelper.getClassListBySuper(BaseService.class);
for (Class<?> serviceClass : serviceClassList) {
// 获取目标实例
Map<Class<?>, Object> beanMap = BeanHelper.getBeanMap();
Object targetInstance = BeanHelper.getBean(serviceClass);
if (targetInstance != null) {
// 创建代理实例
Object proxyInstance = TransactionProxy.getInstance().getProxy(serviceClass);
// 复制目标实例中的字段到代理实例中
ObjectUtil.copyFields(targetInstance, proxyInstance);
// 用代理实例覆盖目标实例
BeanHelper.getBeanMap().put(serviceClass, proxyInstance);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
}
package com.smart.framework.util;
import org.apache.commons.lang.ArrayUtils;
public class ArrayUtil {
// 判断 Array 是否非空
public static boolean isNotEmpty(Object[] array) {
return ArrayUtils.isNotEmpty(array);
}
// 判断 Array 是否为空
public static boolean isEmpty(Object[] array) {
return ArrayUtils.isEmpty(array);
}
}
package com.smart.framework.util;
public class CastUtil {
// 转为 String 型
public static String castString(Object obj) {
return CastUtil.castString(obj, "");
}
// 转为 String 型(提供默认值)
public static String castString(Object obj, String defaultValue) {
return obj != null ? String.valueOf(obj) : defaultValue;
}
// 转为 double 型
public static double castDouble(Object obj) {
return CastUtil.castDouble(obj, 0);
}
// 转为 double 型(提供默认值)
public static double castDouble(Object obj, double defaultValue) {
double doubleValue = defaultValue;
if (obj != null) {
String strValue = castString(obj);
if (StringUtil.isNotEmpty(strValue)) {
try {
doubleValue = Double.parseDouble(strValue);
} catch (NumberFormatException e) {
doubleValue = defaultValue;
}
}
}
return doubleValue;
}
// 转为 float 型
public static float castFloat(Object obj) {
return CastUtil.castFloat(obj, 0);
}
// 转为 float 型(提供默认值)
public static float castFloat(Object obj, float defaultValue) {
float floatValue = defaultValue;
if (obj != null) {
String strValue = castString(obj);
if (StringUtil.isNotEmpty(strValue)) {
try {
floatValue = Float.parseFloat(strValue);
} catch (NumberFormatException e) {
floatValue = defaultValue;
}
}
}
return floatValue;
}
// 转为 long 型
public static long castLong(Object obj) {
return CastUtil.castLong(obj, 0);
}
// 转为 long 型(提供默认值)
public static long castLong(Object obj, long defaultValue) {
long longValue = defaultValue;
if (obj != null) {
String strValue = castString(obj);
if (StringUtil.isNotEmpty(strValue)) {
try {
longValue = Long.parseLong(strValue);
} catch (NumberFormatException e) {
longValue = defaultValue;
}
}
}
return longValue;
}
// 转为 int 型
public static int castInt(Object obj) {
return CastUtil.castInt(obj, 0);
}
// 转为 int 型(提供默认值)
public static int castInt(Object obj, int defaultValue) {
int intValue = defaultValue;
if (obj != null) {
String strValue = castString(obj);
if (StringUtil.isNotEmpty(strValue)) {
try {
intValue = Integer.parseInt(strValue);
} catch (NumberFormatException e) {
intValue = defaultValue;
}
}
}
return intValue;
}
// 转为 boolean 型
public static boolean castBoolean(Object obj) {
return CastUtil.castBoolean(obj, false);
}
// 转为 boolean 型(提供默认值)
public static boolean castBoolean(Object obj, boolean defaultValue) {
boolean booleanValue = defaultValue;
if (obj != null) {
booleanValue = Boolean.parseBoolean(castString(obj));
}
return booleanValue;
}
// 转为 String[] 型
public static String[] castStringArray(Object[] objArray) {
if (objArray == null) {
objArray = new Object[0];
}
String[] strArray = new String[objArray.length];
if (ArrayUtil.isNotEmpty(objArray)) {
for (int i = 0; i < objArray.length; i++) {
strArray[i] = castString(objArray[i]);
}
}
return strArray;
}
// 转为 double[] 型
public static double[] castDoubleArray(Object[] objArray) {
if (objArray == null) {
objArray = new Object[0];
}
double[] doubleArray = new double[objArray.length];
if (!ArrayUtil.isEmpty(objArray)) {
for (int i = 0; i < objArray.length; i++) {
doubleArray[i] = castDouble(objArray[i]);
}
}
return doubleArray;
}
// 转为 long[] 型
public static long[] castLongArray(Object[] objArray) {
if (objArray == null) {
objArray = new Object[0];
}
long[] longArray = new long[objArray.length];
if (!ArrayUtil.isEmpty(objArray)) {
for (int i = 0; i < objArray.length; i++) {
longArray[i] = castLong(objArray[i]);
}
}
return longArray;
}
// 转为 int[] 型
public static int[] castIntArray(Object[] objArray) {
if (objArray == null) {
objArray = new Object[0];
}
int[] intArray = new int[objArray.length];
if (!ArrayUtil.isEmpty(objArray)) {
for (int i = 0; i < objArray.length; i++) {
intArray[i] = castInt(objArray[i]);
}
}
return intArray;
}
// 转为 boolean[] 型
public static boolean[] castBooleanArray(Object[] objArray) {
if (objArray == null) {
objArray = new Object[0];
}
boolean[] booleanArray = new boolean[objArray.length];
if (!ArrayUtil.isEmpty(objArray)) {
for (int i = 0; i < objArray.length; i++) {
booleanArray[i] = castBoolean(objArray[i]);
}
}
return booleanArray;
}
}
package com.smart.framework.util;
import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.log4j.Logger;
public class ClassUtil {
private static final Logger logger = Logger.getLogger(ClassUtil.class);
// 获取指定包名下的所有类
public static List<Class<?>> getClassList(String packageName, boolean isRecursive) {
List<Class<?>> classList = new ArrayList<Class<?>>();
try {
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replace(".", "/"));
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
if (url != null) {
String protocol = url.getProtocol();
if (protocol.equals("file")) {
String packagePath = url.getPath();
addClass(classList, packagePath, packageName, isRecursive);
} else if (protocol.equals("jar")) {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarEntryName = jarEntry.getName();
if (jarEntryName.endsWith(".class")) {
String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
if (isRecursive || className.substring(0, className.lastIndexOf(".")).equals(packageName)) {
classList.add(Class.forName(className));
}
}
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return classList;
}
// 获取指定包名下指定注解的所有类
public static List<Class<?>> getClassListByAnnotation(String packageName, Class<? extends Annotation> annotationClass) {
List<Class<?>> classList = new ArrayList<Class<?>>();
try {
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replace(".", "/"));
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
if (url != null) {
String protocol = url.getProtocol();
if (protocol.equals("file")) {
String packagePath = url.getPath();
addClassByAnnotation(classList, packagePath, packageName, annotationClass);
} else if (protocol.equals("jar")) {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarEntryName = jarEntry.getName();
if (jarEntryName.endsWith(".class")) {
String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
Class<?> cls = Class.forName(className);
if (cls.isAnnotationPresent(annotationClass)) {
classList.add(cls);
}
}
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return classList;
}
// 获取指定包名下指定父类的所有类
public static List<Class<?>> getClassListBySuper(String packageName, Class<?> superClass) {
List<Class<?>> classList = new ArrayList<Class<?>>();
try {
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replace(".", "/"));
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
if (url != null) {
String protocol = url.getProtocol();
if (protocol.equals("file")) {
String packagePath = url.getPath();
addClassBySuper(classList, packagePath, packageName, superClass);
} else if (protocol.equals("jar")) {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarEntryName = jarEntry.getName();
if (jarEntryName.endsWith(".class")) {
String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
Class<?> cls = Class.forName(className);
if (superClass.isAssignableFrom(cls) && !superClass.equals(cls)) {
classList.add(cls);
}
}
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return classList;
}
// 获取指定包名下指定接口的所有实现类
public static List<Class<?>> getClassListByInterface(String packageName, Class<?> interfaceClass) {
List<Class<?>> classList = new ArrayList<Class<?>>();
try {
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replace(".", "/"));
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
if (url != null) {
String protocol = url.getProtocol();
if (protocol.equals("file")) {
String packagePath = url.getPath();
addClassByInterface(classList, packagePath, packageName, interfaceClass);
} else if (protocol.equals("jar")) {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarEntryName = jarEntry.getName();
if (jarEntryName.endsWith(".class")) {
String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
Class<?> cls = Class.forName(className);
if (interfaceClass.isAssignableFrom(cls) && !interfaceClass.equals(cls)) {
classList.add(cls);
}
}
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return classList;
}
private static void addClass(List<Class<?>> classList, String packagePath, String packageName, boolean isRecursive) {
try {
File[] files = getClassFiles(packagePath);
if (files != null) {
for (File file : files) {
String fileName = file.getName();
if (file.isFile()) {
String className = getClassName(packageName, fileName);
classList.add(Class.forName(className));
} else {
if (isRecursive) {
String subPackagePath = getSubPackagePath(packagePath, fileName);
String subPackageName = getSubPackageName(packageName, fileName);
addClass(classList, subPackagePath, subPackageName, isRecursive);
}
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
private static File[] getClassFiles(String packagePath) {
return new File(packagePath).listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
}
});
}
private static String getClassName(String packageName, String fileName) {
String className = fileName.substring(0, fileName.lastIndexOf("."));
if (StringUtil.isNotEmpty(packageName)) {
className = packageName + "." + className;
}
return className;
}
private static String getSubPackagePath(String packagePath, String filePath) {
String subPackagePath = filePath;
if (StringUtil.isNotEmpty(packagePath)) {
subPackagePath = packagePath + "/" + subPackagePath;
}
return subPackagePath;
}
private static String getSubPackageName(String packageName, String filePath) {
String subPackageName = filePath;
if (StringUtil.isNotEmpty(packageName)) {
subPackageName = packageName + "." + subPackageName;
}
return subPackageName;
}
private static void addClassByAnnotation(List<Class<?>> classList, String packagePath, String packageName, Class<? extends Annotation> annotationClass) {
try {
File[] files = getClassFiles(packagePath);
if (files != null) {
for (File file : files) {
String fileName = file.getName();
if (file.isFile()) {
String className = getClassName(packageName, fileName);
Class<?> cls = Class.forName(className);
if (cls.isAnnotationPresent(annotationClass)) {
classList.add(cls);
}
} else {
String subPackagePath = getSubPackagePath(packagePath, fileName);
String subPackageName = getSubPackageName(packageName, fileName);
addClassByAnnotation(classList, subPackagePath, subPackageName, annotationClass);
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
private static void addClassBySuper(List<Class<?>> classList, String packagePath, String packageName, Class<?> superClass) {
try {
File[] files = getClassFiles(packagePath);
if (files != null) {
for (File file : files) {
String fileName = file.getName();
if (file.isFile()) {
String className = getClassName(packageName, fileName);
Class<?> cls = Class.forName(className);
if (superClass.isAssignableFrom(cls) && !superClass.equals(cls)) {
classList.add(cls);
}
} else {
String subPackagePath = getSubPackagePath(packagePath, fileName);
String subPackageName = getSubPackageName(packageName, fileName);
addClassBySuper(classList, subPackagePath, subPackageName, superClass);
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
private static void addClassByInterface(List<Class<?>> classList, String packagePath, String packageName, Class<?> interfaceClass) {
try {
File[] files = getClassFiles(packagePath);
if (files != null) {
for (File file : files) {
String fileName = file.getName();
if (file.isFile()) {
String className = getClassName(packageName, fileName);
Class<?> cls = Class.forName(className);
if (interfaceClass.isAssignableFrom(cls) && !interfaceClass.equals(cls)) {
classList.add(cls);
}
} else {
String subPackagePath = getSubPackagePath(packagePath, fileName);
String subPackageName = getSubPackageName(packageName, fileName);
addClassByInterface(classList, subPackagePath, subPackageName, interfaceClass);
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
// 获取类路径
public static String getClassPath() {
String classpath = "";
URL resource = ClassUtil.class.getClassLoader().getResource("");
if (resource != null) {
classpath = resource.getPath();
}
return classpath;
}
}
package com.smart.framework.util;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.UUID;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.log4j.Logger;
public class CodecUtil {
private static final Logger logger = Logger.getLogger(CodecUtil.class);
// 将字符串 UTF-8 编码
public static String encodeForUTF8(String str) {
String target;
try {
target = URLEncoder.encode(str, "UTF-8");
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return target;
}
// 将字符串 UTF-8 解码
public static String decodeForUTF8(String str) {
String target;
try {
target = URLDecoder.decode(str, "UTF-8");
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return target;
}
// 将字符串 Base64 编码
public static String encodeForBase64(String str) {
return Base64.encodeBase64String(str.getBytes());
}
// 将字符串 Base64 解码
public static String decodeForBase64(String str) {
return new String(Base64.decodeBase64(str.getBytes()));
}
// 将字符串 MD5 加密
public static String encryptForMD5(String str) {
return DigestUtils.md5Hex(str);
}
// 将字符串 SHA 加密
public static String encryptForSHA(String str) {
return DigestUtils.sha1Hex(str);
}
// 创建随机数
public static String createRandomNumber(int count) {
return RandomStringUtils.randomNumeric(count);
}
// 获取UUID(32位)
public static String createUUID() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
}
package com.smart.framework.util;
import java.util.Collection;
import org.apache.commons.collections.CollectionUtils;
public class CollectionUtil {
// 判断集合是否非空
public static boolean isNotEmpty(Collection<?> collection) {
return CollectionUtils.isNotEmpty(collection);
}
// 判断集合是否为空
public static boolean isEmpty(Collection<?> collection) {
return CollectionUtils.isEmpty(collection);
}
}
package com.smart.framework.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbutils.BasicRowProcessor;
import org.apache.commons.dbutils.BeanProcessor;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.KeyedHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.apache.log4j.Logger;
public class DBUtil {
private static final Logger logger = Logger.getLogger(DBUtil.class);
// 打开数据库连接(type: MySQL,Oracle,SQLServer)
public static Connection openConnection(String type, String host, String port, String name, String username, String password) {
Connection conn;
try {
String driver;
String url;
if (type.equalsIgnoreCase("MySQL")) {
driver = "com.mysql.jdbc.Driver";
url = "jdbc:mysql://" + host + ":" + port + "/" + name;
} else if (type.equalsIgnoreCase("Oracle")) {
driver = "oracle.jdbc.driver.OracleDriver";
url = "jdbc:oracle:thin:@" + host + ":" + port + ":" + name;
} else if (type.equalsIgnoreCase("SQLServer")) {
driver = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
url = "jdbc:sqlserver://" + host + ":" + port + ";databaseName=" + name;
} else {
throw new RuntimeException();
}
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return conn;
}
// 关闭数据库连接
public static void closeConnection(Connection conn) {
try {
if (conn != null) {
conn.close();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
// 查询(返回 Array)
public static Object[] queryArray(QueryRunner runner, String sql, Object... params) {
Object[] result;
try {
result = runner.query(sql, new ArrayHandler(), params);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
printSQL(sql);
return result;
}
// 查询(返回 ArrayList)
public static List<Object[]> queryArrayList(QueryRunner runner, String sql, Object... params) {
List<Object[]> result;
try {
result = runner.query(sql, new ArrayListHandler(), params);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
printSQL(sql);
return result;
}
// 查询(返回 Map)
public static Map<String, Object> queryMap(QueryRunner runner, String sql, Object... params) {
Map<String, Object> result;
try {
result = runner.query(sql, new MapHandler(), params);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
printSQL(sql);
return result;
}
// 查询(返回 MapList)
public static List<Map<String, Object>> queryMapList(QueryRunner runner, String sql, Object... params) {
List<Map<String, Object>> result;
try {
result = runner.query(sql, new MapListHandler(), params);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
printSQL(sql);
return result;
}
// 查询(返回 Bean)
public static <T> T queryBean(QueryRunner runner, Class<T> cls, Map<String, String> map, String sql, Object... params) {
T result;
try {
if (MapUtil.isNotEmpty(map)) {
result = runner.query(sql, new BeanHandler<T>(cls, new BasicRowProcessor(new BeanProcessor(map))), params);
} else {
result = runner.query(sql, new BeanHandler<T>(cls), params);
}
printSQL(sql);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return result;
}
// 查询(返回 BeanList)
public static <T> List<T> queryBeanList(QueryRunner runner, Class<T> cls, Map<String, String> map, String sql, Object... params) {
List<T> result;
try {
if (MapUtil.isNotEmpty(map)) {
result = runner.query(sql, new BeanListHandler<T>(cls, new BasicRowProcessor(new BeanProcessor(map))), params);
} else {
result = runner.query(sql, new BeanListHandler<T>(cls), params);
}
printSQL(sql);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return result;
}
// 查询指定列名的值(单条数据)
public static Object queryColumn(QueryRunner runner, String column, String sql, Object... params) {
Object result;
try {
result = runner.query(sql, new ScalarHandler<Object>(column), params);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
printSQL(sql);
return result;
}
// 查询指定列名的值(多条数据)
public static <T> List<T> queryColumnList(QueryRunner runner, String column, String sql, Object... params) {
List<T> result;
try {
result = runner.query(sql, new ColumnListHandler<T>(column), params);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
printSQL(sql);
return result;
}
// 查询指定列名对应的记录映射
public static <T> Map<T, Map<String, Object>> queryKeyMap(QueryRunner runner, String column, String sql, Object... params) {
Map<T, Map<String, Object>> result;
try {
result = runner.query(sql, new KeyedHandler<T>(column), params);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
printSQL(sql);
return result;
}
// 更新(包括 UPDATE、INSERT、DELETE,返回受影响的行数)
public static int update(QueryRunner runner, Connection conn, String sql, Object... params) {
int result;
try {
if (conn != null) {
result = runner.update(conn, sql, params);
} else {
result = runner.update(sql, params);
}
printSQL(sql);
} catch (SQLException e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return result;
}
private static void printSQL(String sql) {
if (logger.isDebugEnabled()) {
logger.debug("SQL: " + sql);
}
}
}
package com.smart.framework.util;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
private static final SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 格式化日期时间
public static String formatDatetime(long timestamp) {
return DATETIME_FORMAT.format(new Date(timestamp));
}
}
package com.smart.framework.util;
import java.io.File;
import java.io.InputStream;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
public class FileUtil {
private static final Logger logger = Logger.getLogger(FileUtil.class);
// 加载 properties 文件
public static Properties loadPropFile(String propPath) {
Properties prop = new Properties();
InputStream is = null;
try {
String suffix = ".properties";
if (propPath.lastIndexOf(suffix) == -1) {
propPath += suffix;
}
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(propPath);
if (is != null) {
prop.load(is);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
} finally {
try {
if (is != null) {
is.close();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
return prop;
}
// 创建目录
public static File createPath(String dirPath) {
File dir = null;
try {
if (StringUtil.isNotEmpty(dirPath)) {
dir = new File(dirPath);
if (!dir.exists()) {
FileUtils.forceMkdir(dir);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return dir;
}
}
package com.smart.framework.util;
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
public class JSONUtil {
private static final Logger logger = Logger.getLogger(JSONUtil.class);
private static final ObjectMapper objectMapper = new ObjectMapper();
// 将 Java 对象转为 JSON 字符串
public static <T> String toJSON(T obj) {
String jsonStr;
try {
jsonStr = objectMapper.writeValueAsString(obj);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return jsonStr;
}
// 将 JSON 字符串转为 Java 对象
public static <T> T fromJSON(String json, Class<T> type) {
T obj;
try {
obj = objectMapper.readValue(json, type);
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return obj;
}
}
package com.smart.framework.util;
import java.util.Map;
import org.apache.commons.collections.MapUtils;
public class MapUtil {
// 判断 Map 是否非空
public static boolean isNotEmpty(Map<?, ?> map) {
return MapUtils.isNotEmpty(map);
}
// 判断 Map 是否为空
public static boolean isEmpty(Map<?, ?> map) {
return MapUtils.isEmpty(map);
}
}
package com.smart.framework.util;
import java.lang.reflect.Field;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.log4j.Logger;
public class ObjectUtil {
private static final Logger logger = Logger.getLogger(ObjectUtil.class);
// 设置字段值
public static void setField(Object obj, String fieldName, Object fieldValue) {
try {
if (PropertyUtils.isWriteable(obj, fieldName)) {
PropertyUtils.setProperty(obj, fieldName, fieldValue);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
// 获取字段值
public static Object getFieldValue(Object obj, String fieldName) {
Object propertyValue = null;
try {
if (PropertyUtils.isReadable(obj, fieldName)) {
propertyValue = PropertyUtils.getProperty(obj, fieldName);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return propertyValue;
}
// 复制所有成员变量
public static void copyFields(Object target, Object source) {
try {
for (Field field : target.getClass().getDeclaredFields()) {
field.setAccessible(true); // 可操作私有字段
field.set(source, field.get(target));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
}
package com.smart.framework.util;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import org.apache.log4j.Logger;
public class StreamUtil {
private static final Logger logger = Logger.getLogger(StreamUtil.class);
// 从输入流拷贝到输出流
public static void copyStream(InputStream input, OutputStream output) {
try {
int length;
byte[] buffer = new byte[1024];
while ((length = input.read(buffer, 0, buffer.length)) != -1) {
output.write(buffer, 0, length);
}
output.flush();
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
// 从输入流中返回字符串
public static String toString(InputStream is) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return sb.toString();
}
}
package com.smart.framework.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
public class StringUtil {
// 判断字符串是否非空
public static boolean isNotEmpty(String str) {
return StringUtils.isNotEmpty(str);
}
// 判断字符串是否为空
public static boolean isEmpty(String str) {
return StringUtils.isEmpty(str);
}
// 若字符串为空,则取默认值
public static String defaultIfEmpty(String str, String defaultValue) {
return StringUtils.defaultIfEmpty(str, defaultValue);
}
// 替换固定格式的字符串(支持正则表达式)
public static String replaceAll(String str, String regex, String replacement) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, replacement);
}
m.appendTail(sb);
return sb.toString();
}
// 是否为数字(整数或小数)
public static boolean isNumber(String str) {
return NumberUtils.isNumber(str);
}
// 是否为十进制数(整数)
public static boolean isDigits(String str) {
return NumberUtils.isDigits(str);
}
// 将驼峰风格替换为下划线风格
public static String toUnderline(String str) {
Matcher matcher = Pattern.compile("[A-Z]").matcher(str);
StringBuilder builder = new StringBuilder(str);
for (int i = 0; matcher.find(); i++) {
builder.replace(matcher.start() + i, matcher.end() + i, "_" + matcher.group().toLowerCase());
}
if (builder.charAt(0) == '_') {
builder.deleteCharAt(0);
}
return builder.toString();
}
// 将下划线风格替换为驼峰风格
public static String toCamelhump(String str) {
Matcher matcher = Pattern.compile("_[a-z]").matcher(str);
StringBuilder builder = new StringBuilder(str);
for (int i = 0; matcher.find(); i++) {
builder.replace(matcher.start() - i, matcher.end() - i, matcher.group().substring(1).toUpperCase());
}
if (Character.isUpperCase(builder.charAt(0))) {
builder.replace(0, 1, String.valueOf(Character.toLowerCase(builder.charAt(0))));
}
return builder.toString();
}
// 分割固定格式的字符串
public static String[] splitString(String str, String separator) {
return StringUtils.splitByWholeSeparator(str, separator);
}
// 将字符串首字母大写
public static String firstToUpper(String str) {
return Character.toUpperCase(str.charAt(0)) + str.substring(1);
}
// 将字符串首字母小写
public static String firstToLower(String str) {
return Character.toLowerCase(str.charAt(0)) + str.substring(1);
}
}
package com.smart.framework.util;
import java.io.File;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import org.apache.log4j.Logger;
public class WebUtil {
private static final Logger logger = Logger.getLogger(WebUtil.class);
// 将数据以纯文本格式写入 Response 中
public static void writeText(HttpServletResponse response, Object data) {
try {
// 设置 Response 头
response.setContentType("text/plain"); // 指定内容类型为纯文本格式
response.setCharacterEncoding("UTF-8"); // 防止中文乱码
// 向 Response 中写入数据
PrintWriter writer = response.getWriter();
writer.write(data + ""); // 转为字符串
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
// 将数据以 JSON 格式写入 Response 中
public static void writeJSON(HttpServletResponse response, Object data) {
try {
// 设置Response头
response.setContentType("application/json"); // 指定内容类型为 JSON 格式
response.setCharacterEncoding("UTF-8"); // 防止中文乱码
// 向Response中写入数据
PrintWriter writer = response.getWriter();
writer.write(JSONUtil.toJSON(data)); // 转为 JSON 字符串
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
// 将数据以 HTML 格式写入Response中(在 JS 中获取的是 JSON 字符串,而不是 JSON 对象)
public static void writeHTML(HttpServletResponse response, Object data) {
try {
// 设置Response头
response.setContentType("text/html"); // 指定内容类型为 HTML 格式
response.setCharacterEncoding("UTF-8"); // 防止中文乱码
// 向Response中写入数据
PrintWriter writer = response.getWriter();
writer.write(JSONUtil.toJSON(data)); // 转为 JSON 字符串
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
}
// 获取文件路径
public static String getFilePath(HttpServletRequest request, String relativePath) {
// 获取绝对路径
String filePath = request.getServletContext().getRealPath("/") + relativePath;
// 若该路径对应的目录不存在,则创建此目录
File fileDir = FileUtil.createPath(filePath);
return filePath;
}
// 获取文件名
public static String getFileName(HttpServletRequest request, Part part) {
// 防止中文乱码(可放在 EncodingFilter 中处理)
// request.setCharacterEncoding("UTF-8");
// 从 Request 头中获取文件名
String cd = part.getHeader("Content-Disposition");
String fileName = cd.substring(cd.lastIndexOf("=") + 2, cd.length() - 1);
// 解决 IE 浏览器文件名问题
if (fileName.contains("\\")) {
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
}
return fileName;
}
// 从Request中获取所有参数(当参数名重复时,用后者覆盖前者)
public static Map<String, String> getRequestParamMap(HttpServletRequest request) {
Map<String, String> paramMap = new HashMap<String, String>();
try {
if (request.getMethod().equalsIgnoreCase("put")) {
String queryString = CodecUtil.decodeForUTF8(StreamUtil.toString(request.getInputStream()));
if (StringUtil.isNotEmpty(queryString)) {
String[] qsArray = StringUtil.splitString(queryString, "&");
if (ArrayUtil.isNotEmpty(qsArray)) {
for (String qs : qsArray) {
String[] array = StringUtil.splitString(qs, "=");
if (ArrayUtil.isNotEmpty(array) && array.length == 2) {
paramMap.put(array[0], array[1]);
}
}
}
}
} else {
Enumeration<String> paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = paramNames.nextElement();
String paramValue = request.getParameter(paramName);
paramMap.put(paramName, paramValue);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
}
return paramMap;
}
// 创建查询映射(查询字符串格式:a:1;b:2)
public static Map<String, String> createQueryMap(String queryString) {
Map<String, String> queryMap = new HashMap<String, String>();
if (StringUtil.isNotEmpty(queryString)) {
String[] queryArray = queryString.split(";");
if (ArrayUtil.isNotEmpty(queryArray)) {
for (String query : queryArray) {
String[] fieldArray = query.split(":");
if (ArrayUtil.isNotEmpty(fieldArray) && fieldArray.length == 2) {
queryMap.put(fieldArray[0], fieldArray[1]);
}
}
}
}
return queryMap;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册