android中常见的aop,GitHub - HobertHe/AopArms: AopArms编写了Android开发中常用的一套注解,如日志、异步处理、缓存、SP、延迟操作、定时任务、重试机制、...

一、简介

当下Java后端的SpringBoot微服务框架大火,原因离不开注解的使用,其简单易配置的注解方式使得更多的社区为其编写适用于SpringBoot的框架,也就是注解逐渐取代了传统的xml配置方式。那么注解在Android中也同样的得到了升华,著名的框架有ButterKnife、 Dagger2、Retrofit等等。今天带来一款Android中比较实用的注解框架AopArms,其用法简单,里面编写了Android开发中常用的一套注解,如日志、异步处理、缓存、SP、延迟操作、定时任务、重试机制、try-catch安全机制、过滤频繁点击等,后续还会有更多更强大的注解功能加入。

本篇主要内容讲解在Android中的基本用法,关于AOP在Android中的实践请参考另外一篇Android开发之AOP编程。

二、引入方式

1、在主工程中添加依赖

//引入aspectjx插件

apply plugin: 'android-aspectjx'

dependencies {

...

implementation 'cn.com.superLei:aop-arms:1.0.4'

}

2、项目跟目录的gradle脚本中加入

buildscript {

repositories {

mavenCentral()

}

dependencies {

//该库基于沪江aspect插件库

classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4'

}

}

3、在Application中初始化

AopArms.init(this);

三、基本使用

1、缓存篇(可缓存任意类型)

1、插入缓存

/**

* key:缓存的键

* expiry:缓存过期时间,单位s

* @return 缓存的值

*/

@Cache(key = "userList", expiry = 60 * 60 * 24)

private ArrayList initData() {

ArrayList list = new ArrayList<>();

for (int i=0; i<5; i++){

User user = new User();

user.setName("艾神一不小心:"+i);

user.setPassword("密码:"+i);

list.add(user);

}

return list;

}

2、获取缓存

private ArrayList getUser() {

return ArmsCache.get(this).getAsList("userList", User.class);

}

3、移除缓存

/**

* key:缓存的键

* beforeInvocation:缓存的清除是否在方法之前执行, 如果出现异常缓存就不会清除 默认false

* allEntries:是否清空所有缓存(与key互斥) 默认false

*/

@CacheEvict(key = "userList", beforeInvocation = true, allEntries = false)

public void removeUser() {

Log.e(TAG, "removeUser: >>>>");

}

49bc22922c660c60961907af0cd94cfc.png

2、SharedPreferences篇(可保存对象)

1、保存key到sp

@Prefs(key = "article")

private Article initArticle() {

Article article = new Article();

article.author = "jerry";

article.title = "hello android";

article.createDate = "2019-05-31";

article.content = "this is a test demo";

return article;

}

2、从sp中移除key

/**

* key:sp的键

* allEntries:是否清空所有存储(与key互斥) 默认false

*/

@PrefsEvict(key = "article", allEntries = false)

public void removeArticle() {

Log.e(TAG, "removeArticle: >>>>");

}

3、通过key从sp中获取value

public void getArticle() {

Article article = ArmsPreference.get(this, "article", null);

Log.e(TAG, "getArticle: "+article);

}

3、异步篇

@Async

public void asyn() {

Log.e(TAG, "useAync: "+Thread.currentThread().getName());

}

4、try-catch安全机制篇

//自动帮你try-catch 允许你定义回调方法

@Safe(callBack = "throwMethod")

public void safe() {

String str = null;

str.toString();

}

//自定义回调方法(注意要和callBack的值保持一致),必须要有Callback注解

@Callback

public void throwMethod(Throwable throwable){

Log.e(TAG, "throwMethod: >>>>>"+throwable.toString());

}

5、重试机制篇

/**

* @param count 重试次数

* @param delay 每次重试的间隔

* @param asyn 是否异步执行

* @param retryCallback 自定义重试结果回调

* @return 当前方法是否执行成功

*/

@Retry(count = 3, delay = 1000, asyn = true, retryCallback = "retryCallback")

public boolean retry() {

Log.e(TAG, "retryDo: >>>>>>"+Thread.currentThread().getName());

return false;

}

@Callback

public void retryCallback(boolean result){

Log.e(TAG, "retryCallback: >>>>"+result);

}

3744d0118abdfe9e719fd756dfb2d05d.png

6、定时任务篇

/**

* @param interval 初始化延迟

* @param interval 时间间隔

* @param timeUnit 时间单位

* @param count 执行次数

* @param taskExpiredCallback 定时任务到期回调

*/

@Scheduled(interval = 1000L, count = 10, taskExpiredCallback = "taskExpiredCallback")

public void scheduled() {

Log.e(TAG, "scheduled: >>>>");

}

@Callback

public void taskExpiredCallback(){

Log.e(TAG, "taskExpiredCallback: >>>>");

}

7458ec125a8e2e04be9a8a98c35247e2.png

7、延迟任务篇

//开启延迟任务(10s后执行该方法)

@Delay(key = "test", delay = 10000L)

public void delay() {

Log.e(TAG, "delay: >>>>>");

}

//移除延迟任务

@DelayAway(key = "test")

public void cancelDelay() {

Log.e(TAG, "cancelDelay: >>>>");

}

8、过滤频繁点击

//value默认500ms

@OnClick({R.id.singleClick1, R.id.singleClick, R.id.singleClick2})

@SingleClick(ids = {R.id.singleClick, R.id.singleClick2})

public void onViewClicked(View view) {

switch (view.getId()) {

case R.id.singleClick1:

Log.e("singleClick", "我不防抖");

break;

case R.id.singleClick:

Log.e("singleClick", "我防抖");

break;

case R.id.singleClick2:

Log.e("singleClick", "我防抖2");

break;

}

}

9、拦截篇(如登录)

1、在需要进行拦截的方法添加注解

@Intercept("login_intercept")

public void loginIntercept() {

Log.e(TAG, "intercept: 已登陆>>>>");

}

2、(建议,统一处理)在Application中进行进行监听拦截回调

public class MyApplication extends Application {

private static final String TAG = "MyApplication";

private static MyApplication mApplication;

@Override

public void onCreate() {

super.onCreate();

mApplication = this;

AopArms.init(this);

AopArms.setInterceptor(new Interceptor() {

@Override

public boolean intercept(String key, String methodName) throws Throwable {

Log.e(TAG, "intercept methodName:>>>>>"+methodName);

if ("login_intercept".equals(key)){

String userId = ArmsPreference.get(mApplication, "userId", "");

if (TextUtils.isEmpty(userId)){

Toast.makeText(mApplication, "您还没有登录", Toast.LENGTH_SHORT).show();

return true;//代表拦截

}

}

return false;//放行

}

});

}

}

10、动态授权篇

1、开启请求权限

/**

* @param value 权限值

* @param rationale 拒绝后的下一次提示(开启后,拒绝后,下一次会先提示该权限申请提示语)

* @param requestCode 权限请求码标识

*/

@Permission(value = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, rationale = "为了更好的体验,请打开相关权限")

public void permission(View view) {

Log.e(TAG, "permission: 权限已打开");

}

2、请求拒绝注解回调

@PermissionDenied

public void permissionDenied(int requestCode, List denyList){

Log.e(TAG, "permissionDenied: "+requestCode);

Log.e(TAG, "permissionDenied>>>: "+denyList.toString());

}

3、请求拒绝且不在提示注解回调

@PermissionNoAskDenied

public void permissionNoAskDenied(int requestCode, List denyNoAskList){

Log.e(TAG, "permissionNoAskDenied: "+requestCode);

Log.e(TAG, "permissionNoAskDenied>>>: "+denyNoAskList.toString());

//前往设置页面打开权限

AopPermissionUtils.showGoSetting(this, "为了更好的体验,建议前往设置页面打开权限");

}

11、测试方法耗时篇

@TimeLog

public void getUser(View view) {

ArrayList users = ArmsCache.get(this).getAsList("userList", User.class);

Log.e(TAG, "getUser: " + users);

}

7e862b5092181ba06f20d5072e499002.png

12、统计页面、方法等埋点

//设置全局的回调(建议放到application中)

AopArms.setStatisticCallback(statisticInfo -> {

Log.e(TAG, "statisticInfo: "+statisticInfo.toString());

});

//activity中使用:

@Statistics(Constant.MAIN_ACTIVITY_STATISTIC_KEY)

public class MainActivity extends AppCompatActivity {...}

//方法中使用:

@Statistics(Constant.TEST_CLICK_STATISTIC_KEY)

public void statistic(View view) {

Log.e(TAG, "statistic: ");

}

其中StatisticInfo类中包含了key、开始时间、activity或者方法的标志、activity的生命周期等

f6824e0f619adac7abb3e9d13d0a90fd.png

四、混淆

#AopArms

-keepclassmembers class * {

@cn.com.superLei.aoparms.annotation.Callback ;

}

五、参考

六、许可证

Copyright 2016 liulei

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、volley 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载; (2) 网络请求的排序(scheduling) (3) 网络请求的优先级处理 (4) 缓存 (5) 多级别取消请求 (6) 和Activity和生命周期的联动(Activity结束时同时取消所有网络请求) 2、android-async-http 项目地址:https://github.com/loopj/android-async-http 文档介绍:http://loopj.com/android-async-http/ (1) 在匿名回调处理请求结果 (2) 在UI线程外进行http请求 (3) 文件断点上传 (4) 智能重试 (5) 默认gzip压缩 (6) 支持解析成Json格式 (7) 可将Cookies持久化到SharedPreferences 3、Afinal框架 项目地址:https://github.com/yangfuhai/afinal 主要有四大模块: (1) 数据库模块:android的orm框架,使用了线程池对sqlite进行操作。 (2) 注解模块:android的ioc框架,完全注解方式就可以进行UI绑定和事件绑定。无需findViewById和setClickListener等。 (3) 网络模块:通过httpclient进行封装http数据请求,支持ajax方式加载,支持下载、上传文件功能。 (4) 图片缓存模块:通过FinalBitmap,imageview加载bitmap的时候无需考虑bitmap加载过程出现的oom和android容器快速滑动时候出现的图片错位等现象。 FinalBitmap可以配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等。FinalBitmap的内存管理使用lru算法, 没有使用弱引用(android2.3以后google已经不建议使用弱引用,android2.3后强行回收软引用和弱引用,详情查看android官方文档), 更好的管理bitmap内存。FinalBitmap可以自定义下载器,用来扩展其他协议显示网络图片,比如ftp等。同时可以自定义bitmap显示器, 在imageview显示图片的时候播放动画等(默认是渐变动画显示)。 4、xUtils框架 项目地址:https://github.com/wyouflf/xUtils 主要有四大模块: (1) 数据库模块:android的orm框架,一行代码就可以进行增删改查; 支持事务,默认关闭; 可通过注解自定义表名,列名,外键,唯一性约束,NOT NULL约束,CHECK约束等(需要混淆的时候请注解表名和列名); 支持绑定外键,保存实体时外键关联实体自动保存或更新; 自动加载外键关联实体,支持延时加载; 支持链式表达查询,更直观的查询语义,参考下面的介绍或sample的例子。 (2) 注解模块:android的ioc框架,完全注解方式就可以进行UI,资源和事件绑定; 新的事件绑定方式,使用混淆工具混淆后仍可正常工作; 目前支持常用的20种事件绑定,参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event。 (3) 网络模块:支持同步,异步方式的请求; 支持大文件上传,上传大文件不会oom; 支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT请求; 下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件; 返回文本内容的请求(默认只启用了GET请求)支持缓存,可设置默认过期时间和针对当前请求的过期时间。 (4) 图片缓存模块:加载bitmap的时候无需考虑bitmap加载过程出现的oom和android容器快速滑动时候出现的图片错位等现象; 支持加载网络图片和本地图片; 内存管理使用lru算法,更好的管理bitmap内存; 可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等... 5、ThinkAndroid 项目地址:https://github.com/white-cat/ThinkAndroid 主要有以下模块: (1) MVC模块:实现视图与模型的分离。 (2) ioc模块:android的ioc模块,完全注解方式就可以进行UI绑定、res的资源的读取、以及对象的初始化。 (3) 数据库模块:android的orm框架,使用了线程池对sqlite进行操作。 (4) http模块:通过httpclient进行封装http数据请求,支持异步及同步方式加载。 (5) 缓存模块:通过简单的配置及设计可以很好的实现缓存,对缓存可以随意的配置 (6) 图片缓存模块:imageview加载图片的时候无需考虑图片加载过程出现的oom和android容器快速滑动时候出现的图片错位等现象。 (7) 配置器模块:可以对简易的实现配对配置的操作,目前配置文件可以支持Preference、Properties对配置进行存取。 (8) 日志打印模块:可以较快的轻易的是实现日志打印,支持日志打印的扩展,目前支持对sdcard写入本地打印、以及控制台打印 (9) 下载器模块:可以简单的实现多线程下载、后台下载、断点续传、对下载进行控制、如开始、暂停、删除等等。 (10) 网络状态检测模块:当网络状态改变时,对其进行检 6、LoonAndroid 项目地址:https://github.com/gdpancheng/LoonAndroid 主要有以下模块: (1) 自动注入框架(只需要继承框架内的application既可) (2) 图片加载框架(多重缓存,自动回收,最大限度保证内存的安全性) (3) 网络请求模块(继承了基本上现在所有的http请求) (4) eventbus(集成一个开源的框架) (5) 验证框架(集成开源框架) (6) json解析(支持解析成集合或者对象) (7) 数据库(不知道是哪位写的 忘记了) (8) 多线程断点下载(自动判断是否支持多线程,判断是否是重定向) (9) 自动更新模块 (10) 一系列工具类
一、简介当下Java后端的SpringBoot微服务框架大火,原因离不开注解的使用,其简单易配置的注解方式使得更多的社区为其编写适用于SpringBoot的框架,也就是注解逐渐取代了传统的xml配置方式。那么注解Android也同样的得到了升华,著名的框架有ButterKnife、 Dagger2、Retrofit等等。今天带来一款Android比较实用的注解框架AopArms,其用法简单,里面编写Android开发常用一套注解,如日志异步处理缓存SP延迟操作定时任务重试机制、try-catch安全机制、过滤频繁点击等,后续还会有更多更强大的注解功能加入。 本篇主要内容讲解在Android的基本用法,关于AOPAndroid的实践请参考另外一篇Android开发AOP编程。二、引入方式1、在主工程添加依赖//引入aspectjx插件 apply&nbsp;plugin:&nbsp;'android-aspectjx' dependencies&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;... &nbsp;&nbsp;&nbsp;&nbsp;implementation&nbsp;'cn.com.superLei:aop-arms:1.0.2' }2、项目跟目录的gradle脚本加入buildscript&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;repositories&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mavenCentral() &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;dependencies&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//该库基于沪江aspect插件库 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;classpath&nbsp;'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.4' &nbsp;&nbsp;&nbsp;&nbsp;} }3、在Application初始化AopArms.init(this);三、基本使用1、缓存篇(可缓存任意类型)1、插入缓存 &nbsp;&nbsp;&nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;key:缓存的键 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;expiry:缓存过期时间,单位s &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;缓存的值 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;@Cache(key&nbsp;=&nbsp;"userList",&nbsp;expiry&nbsp;=&nbsp;60&nbsp;*&nbsp;60&nbsp;*&nbsp;24) &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArrayList<User>&nbsp;initData()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ArrayList<User>&nbsp;list&nbsp;=&nbsp;new&nbsp;ArrayList<>(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i=0;&nbsp;i<5;&nbsp;i ){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;user&nbsp;=&nbsp;new&nbsp;User(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.setName("艾神一不小心:" i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.setPassword("密码:" i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.add(user); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;list; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; 2、获取缓存 &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ArrayList<User>&nbsp;getUser()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ArmsCache.get(this).getAsList("userList",&nbsp;User.class); &nbsp;&nbsp;&nbsp;&nbsp;} 3、移除缓存 &nbsp;&nbsp;&nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;key:缓存的键 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;beforeInvocation:缓存的清除是否在方法之前执行,&nbsp;如果出现异常缓存就不会清除&nbsp;&nbsp;&nbsp;默认false &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;allEntries:是否清空所有缓存(与key互斥)&nbsp;&nbsp;默认false &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;@CacheEvict(key&nbsp;=&nbsp;"userList",&nbsp;beforeInvocation&nbsp;=&nbsp;true,&nbsp;allEntries&nbsp;=&nbsp;false) &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;removeUser()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"removeUser:&nbsp;>>>>"); &nbsp;&nbsp;&nbsp;&nbsp;}2、SharedPreferences篇(可保存对象)1、保存key到sp &nbsp;&nbsp;&nbsp;&nbsp;@Prefs(key&nbsp;=&nbsp;"article") &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Article&nbsp;initArticle()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Article&nbsp;article&nbsp;=&nbsp;new&nbsp;Article(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;article.author&nbsp;=&nbsp;"jerry"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;article.title&nbsp;=&nbsp;"hello&nbsp;android"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;article.createDate&nbsp;=&nbsp;"2019-05-31"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;article.content&nbsp;=&nbsp;"this&nbsp;is&nbsp;a&nbsp;test&nbsp;demo"; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;article; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; 2、从sp移除key &nbsp;&nbsp;&nbsp;&nbsp;/** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;key:sp的键 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;allEntries:是否清空所有存储(与key互斥)&nbsp;&nbsp;默认false &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;@PrefsEvict(key&nbsp;=&nbsp;"article",&nbsp;allEntries&nbsp;=&nbsp;false) &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;removeArticle()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"removeArticle:&nbsp;>>>>"); &nbsp;&nbsp;&nbsp;&nbsp;} 3、通过key从sp获取value &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;getArticle()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Article&nbsp;article&nbsp;=&nbsp;ArmsPreference.get(this,&nbsp;"article",&nbsp;null); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"getArticle:&nbsp;" article); &nbsp;&nbsp;&nbsp;&nbsp;}3、异步篇@Async &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;asyn()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"useAync:&nbsp;" Thread.currentThread().getName()); &nbsp;&nbsp;&nbsp;&nbsp;}4、try-catch安全机制篇//自动帮你try-catch&nbsp;&nbsp;&nbsp;允许你定义回调方法 &nbsp;&nbsp;&nbsp;&nbsp;@Safe(callBack&nbsp;=&nbsp;"throwMethod") &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;safe()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;str&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str.toString(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//自定义回调方法(注意要和callBack的值保持一致) &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;throwMethod(Throwable&nbsp;throwable){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"throwMethod:&nbsp;>>>>>" throwable.toString()); &nbsp;&nbsp;&nbsp;&nbsp;}5、重试机制篇/** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;count&nbsp;重试次数 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;delay&nbsp;每次重试的间隔 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;asyn&nbsp;是否异步执行 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;retryCallback&nbsp;自定义重试结果回调 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;当前方法是否执行成功 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;@Retry(count&nbsp;=&nbsp;3,&nbsp;delay&nbsp;=&nbsp;1000,&nbsp;asyn&nbsp;=&nbsp;true,&nbsp;retryCallback&nbsp;=&nbsp;"retryCallback") &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;retry()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"retryDo:&nbsp;>>>>>>" Thread.currentThread().getName()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;retryCallback(boolean&nbsp;result){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"retryCallback:&nbsp;>>>>" result); &nbsp;&nbsp;&nbsp;&nbsp;}6、定时任务篇/** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;interval&nbsp;初始化延迟 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;interval&nbsp;时间间隔 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;timeUnit&nbsp;时间单位 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;count&nbsp;执行次数 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;taskExpiredCallback&nbsp;定时任务到期回调 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/ &nbsp;&nbsp;&nbsp;&nbsp;@Scheduled(interval&nbsp;=&nbsp;1000L,&nbsp;count&nbsp;=&nbsp;10,&nbsp;taskExpiredCallback&nbsp;=&nbsp;"taskExpiredCallback") &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;scheduled()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"scheduled:&nbsp;>>>>"); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;taskExpiredCallback(){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"taskExpiredCallback:&nbsp;>>>>"); &nbsp;&nbsp;&nbsp;&nbsp;}7、延迟任务篇//开启延迟任务(10s后执行该方法) &nbsp;&nbsp;&nbsp;&nbsp;@Delay(key&nbsp;=&nbsp;"test",&nbsp;delay&nbsp;=&nbsp;10000L) &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;delay()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"delay:&nbsp;>>>>>"); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//移除延迟任务 &nbsp;&nbsp;&nbsp;&nbsp;@DelayAway(key&nbsp;=&nbsp;"test") &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;cancelDelay()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"cancelDelay:&nbsp;>>>>"); &nbsp;&nbsp;&nbsp;&nbsp;}8、过滤频繁点击//value默认500ms &nbsp;&nbsp;&nbsp;&nbsp;@SingleClick(value&nbsp;=&nbsp;2000L) &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;onclick(){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"onclick:&nbsp;>>>>"); &nbsp;&nbsp;&nbsp;&nbsp;}9、拦截篇(如登录)1、在需要进行拦截的方法添加注解 &nbsp;&nbsp;&nbsp;&nbsp;@Intercept("login_intercept") &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;loginIntercept()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"intercept:&nbsp;已登陆>>>>"); &nbsp;&nbsp;&nbsp;&nbsp;} 2、(建议,统一处理)在Application进行进行监听拦截回调 public&nbsp;class&nbsp;MyApplication&nbsp;extends&nbsp;Application&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;final&nbsp;String&nbsp;TAG&nbsp;=&nbsp;"MyApplication"; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;MyApplication&nbsp;mApplication; &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onCreate()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.onCreate(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mApplication&nbsp;=&nbsp;this; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AopArms.init(this); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AopArms.setInterceptor(new&nbsp;Interceptor()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;boolean&nbsp;intercept(String&nbsp;key,&nbsp;String&nbsp;methodName)&nbsp;throws&nbsp;Throwable&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log.e(TAG,&nbsp;"intercept&nbsp;methodName:>>>>>" methodName); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;("login_intercept".equals(key)){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;userId&nbsp;=&nbsp;ArmsPreference.get(mApplication,&nbsp;"userId",&nbsp;""); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(TextUtils.isEmpty(userId)){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Toast.makeText(mApplication,&nbsp;"您还没有登录",&nbsp;Toast.LENGTH_SHORT).show(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;//代表拦截 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;//放行 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;} }四、参考HujiangTechnology/gradle_plugin_android_aspectjx深入理解AndroidAOP
这个可以实现ImageView异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画。解决了:1. listview加载oom问题 2. listview加载时卡顿的现象 3. listview加载时item图片重复错位等情况 可以配置: 1. 设置加载图片的最大尺寸 2. 设置默认图片的显示 3. 设置图片位图模式 4. 设置内存缓存的最大值。 5. 文件缓存保存的目录   这个框架基本的代码是很久以前不知道哪里弄的,零零碎碎的,现在已经优化了很多,所以现在上传到github上共享。   讲讲使用方式吧: &nbsp; 首先使用前下载源码或者jar包(见github:https://github.com/wangjiegulu/ImageLoaderSample) 然后进行图片加载器(ImageLoader)的配置和初始化,推荐的方法如下: 新建MyApplication类,继承Application,在onCreate增加如下代码:/** &nbsp;*&nbsp;Created&nbsp;with&nbsp;IntelliJ&nbsp;IDEA. &nbsp;*&nbsp;Author:&nbsp;wangjie&nbsp;&nbsp;email:[email protected] &nbsp;*&nbsp;Date:&nbsp;14-2-27 &nbsp;*&nbsp;Time:&nbsp;上午11:25 &nbsp;*/ public&nbsp;class&nbsp;MyApplication&nbsp;extends&nbsp;Application{ &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onCreate()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.onCreate(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ImageLoader.init(getApplicationContext(), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;CacheConfig() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.setDefRequiredSize(600)&nbsp;//&nbsp;设置默认的加载图片尺寸(表示宽高任一不超过该值,默认是70px) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultResId(R.drawable.ic_launcher)&nbsp;//&nbsp;设置显示的默认图片(默认是0,即空白图片) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.setBitmapConfig(Bitmap.Config.ARGB_8888)&nbsp;//&nbsp;设置图片位图模式(默认是Bitmap.CacheConfig.ARGB_8888) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.setMemoryCachelimit(Runtime.getRuntime().maxMemory()&nbsp;/&nbsp;3)&nbsp;//&nbsp;设置图片内存缓存大小(默认是Runtime.getRuntime().maxMemory()&nbsp;/&nbsp;4) //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.setFileCachePath(Environment.getExternalStorageDirectory().toString()&nbsp; &nbsp;"/mycache")&nbsp;//&nbsp;设置文件缓存保存目录 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;…… }然后再AndroidManifest.xml添加:......到此,配置已经全部完成:接下来,使用ImageLoader来加载图片:holder.progress.setText("0%"); &nbsp;&nbsp;&nbsp;&nbsp;holder.progress.setVisibility(View.VISIBLE); &nbsp;&nbsp;&nbsp;&nbsp;final&nbsp;ViewHolder&nbsp;vhr&nbsp;=&nbsp;holder; &nbsp;&nbsp;&nbsp;&nbsp;ImageLoader.getInstances().displayImage(list.get(position),&nbsp;holder.image,&nbsp;new&nbsp;ImageLoader.OnImageLoaderListener()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onProgressImageLoader(ImageView&nbsp;imageView,&nbsp;int&nbsp;currentSize,&nbsp;int&nbsp;totalSize)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vhr.progress.setText(currentSize&nbsp;*&nbsp;100&nbsp;/&nbsp;totalSize&nbsp; &nbsp;"%"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;onFinishedImageLoader(ImageView&nbsp;imageView,&nbsp;Bitmap&nbsp;bitmap)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vhr.progress.setVisibility(View.GONE); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;或者: &nbsp;&nbsp;&nbsp;&nbsp;ImageLoader.getInstances().displayImage(url,&nbsp;imageIv); &nbsp;&nbsp;&nbsp;&nbsp;或者 &nbsp;&nbsp;&nbsp;&nbsp;ImageLoader.getInstances().displayImage(url,&nbsp;imageIv,&nbsp;100);备注:例子,用到了一部分注解(与ImageLoader功能无关,但是可以简化代码的编写) 可以点下面连接进入:github:https://github.com/wangjiegulu/androidInject博客:http://www.cnblogs.com/tiantianbyconan/p/3459139.htmlhttp://www.cnblogs.com/tiantianbyconan/p/3540427.html
ThinkAndroid是一个免费的开源的、简易的、遵循Apache2开源协议发布的Android开发框架,其开发宗旨是简单、快速的进行 Android应用程序的开发,包含Android mvc、简易sqlite orm、ioc模块、封装Android httpclitent的http模块, 具有快速构建文件缓存功能,无需考虑缓存文件的格式,都可以非常轻松的实现缓存,它还基于文件缓存模块实现了图片缓存功能, 在android加载的图片的时候,对oom的问题,和对加载图片错位的问题都轻易解决。他还包括了一个手机开发经常应用的实用工具类, 如日志管理,配置文件管理,android下载器模块,网络切换检测等等工具。 目前ThinkAndroid主要有以下模块: MVC模块:实现视图与模型的分离。 ioc模块:android的ioc模块,完全注解方式就可以进行UI绑定、res的资源的读取、以及对象的初始化。 数据库模块:android的orm框架,使用了线程池对sqlite进行操作。 http模块:通过httpclient进行封装http数据请求,支持异步及同步方式加载。 缓存模块:通过简单的配置及设计可以很好的实现缓存,对缓存可以随意的配置 图片缓存模块:imageview加载图片的时候无需考虑图片加载过程出现的oom和android容器快速滑动时候出现的图片错位等现象。 配置器模块:可以对简易的实现配对配置的操作,目前配置文件可以支持Preference、Properties对配置进行存取。 日志打印模块:可以较快的轻易的是实现日志打印,支持日志打印的扩展,目前支持对sdcard写入本地打印、以及控制台打印 下载器模块:可以简单的实现多线程下载、后台下载、断点续传、对下载进行控制、如开始、暂停、删除等等。 网络状态检测模块:当网络状态改变时,对其进行检测。 项目主页:https://github.com/white-cat/ThinkAndroid(不过这个项目已经两年没更新了) &nbsp;
Spring4GWT GWT Spring 使得在 Spring 框架下构造 GWT 应用变得很简单,提供一个易于理解的依赖注入和RPC机制。 Java扫雷游戏 JVMine JVMine用Applets开发的扫雷游戏,可在线玩。 public class JVMine extends java.applet.Applet 简单实现!~ 网页表格组件 GWT Advanced Table GWT Advanced Table 是一个基于 GWT 框架的网页表格组件,可实现分页数据显示、数据排序和过滤等功能! Google Tag Library 该标记库和 Google 有关。使用该标记库,利用 Google 为你的网站提供网站查询,并且可以直接在你的网页里面显示搜查的结果。 github-java-api github-java-api 是 Github 网站 API 的 Java 语言版本。 java缓存工具 SimpleCache SimpleCache 是一个简单易用的java缓存工具,用来简化缓存代码的编写,让你摆脱单调乏味的重复工作!1. 完全透明的缓存支持,对业务代码零侵入 2. 支持使用Redis和Memcached作为后端缓存。3. 支持缓存数据分区规则的定义 4. 使用redis作缓存时,支持list类型的高级数据结构,更适合论坛帖子列表这种类型的数据 5. 支持混合使用redis缓存和memcached缓存。可以将列表数据缓存到redis,其他kv结构数据继续缓存到memcached 6. 支持redis的主从集群,可以做读写分离。缓存读取自redis的slave节点,写入到redis的master节点。 Java对象的SQL接口 JoSQL JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于【自动提示】的需要(如:Google搜索), 而开发的架构无关的公共控件, 以满足该类需求可以通过快速配置来开发。AutoTips基于搜索引擎Apache Lucene实现。AutoTips提供统一UI。 WAP浏览器 j2wap j2wap 是一个基于Java的WAP浏览器,目前处于BETA测试阶段。它支持WAP 1.2规范,除了WTLS 和WBMP。 Java注册表操作类 jared jared是一个用来操作Windows注册表的 Java 类库,你可以用来对注册表信息进行读写。 GIF动画制作工具 GiftedMotion GiftedMotion是一个很小的,免费而且易于使用图像互换格式动画是能够设计一个有趣的动画了一系列的数字图像。使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端 JOpenID JOpenID是一个轻量级的OpenID 2.0 Java客户端,仅50KB+(含源代码),允许任何Web网站通过OpenID支持用户直接登录而无需注册,例如Google Account或Yahoo Account。 JActor的文件持久化组件 JFile JFile 是 JActor 的文件持久化组件,以及一个高吞吐量的可靠事务日志组件。 Google地图JSP标签库 利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JSEditor JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮以及一些通用的面向对象方法。 Java数据库连接池 BoneCP BoneCP 是一个高性能的开源java数据库连接池实现库。它的设计初衷就是为了提高数据库连接池的性能,根据某些测试数据发现,BoneCP是最快的连接池。BoneCP很小,只有四十几K
jfinal好用的插件正在开发,下载源码https://github.com/Dreampie/jfinal-dreampie,maven引入方式:http://search.maven.org/&nbsp;输入jfinal-dreampie搜索 <dependencies> <dependency> <groupId>cn.dreampie</groupId> <artifactId>jfinal-dreampie</artifactId> <version>0.2.3</version> </dependency> </dependencies> https://github.com/Dreampie?tab=repositories&nbsp; &nbsp;分割成多个独立的插件进行优化,可以看我的博客拆分优化情况&nbsp;http://my.oschina.net/wangrenhui1990/blog demo:(Angularjs前端 jfinal-dreampie插件)&nbsp;https://github.com/Dreampie/icedog 剥离框架前的源码https://github.com/Dreampie/dreampie https://github.com/Dreampie?tab=repositories&nbsp;目录下有多款插件: cn.dreampie.jfinal-shiro &nbsp; &nbsp;&nbsp;https://github.com/Dreampie/jfinal-shiro&nbsp; &nbsp; 支持注解和数据库配置的shiro插件 cn.dreampie.jfinal-shiro-freemarker &nbsp;&nbsp;https://github.com/Dreampie/jfinal-shiro-freemarker&nbsp; &nbsp; shiro插件实现的freemarker标签库 cn.dreampie.jfinal-web &nbsp; &nbsp;&nbsp;https://github.com/Dreampie/jfinal-web&nbsp;&nbsp; 相关web插件,简洁model实现 cn.dreampie.jfinal-utils &nbsp; &nbsp; &nbsp; &nbsp;https://github.com/Dreampie/jfinal-utils&nbsp; &nbsp;部分jfinal工具 cn.dreampie.jfinal-tablebind &nbsp; &nbsp; &nbsp; &nbsp;https://github.com/Dreampie/jfinal-tablebind&nbsp; &nbsp;jfinal的table自动绑定插件,支持多数据源 cn.dreampie.jfinal-flyway &nbsp; &nbsp; &nbsp;https://github.com/Dreampie/jfinal-flyway&nbsp; &nbsp;数据库脚本升级插件,开发升级应用时,使用脚本同步升级数据库或者回滚 cn.dreampie.jfinal-captcha &nbsp; &nbsp; &nbsp;https://github.com/Dreampie/jfinal-captcha&nbsp;&nbsp; 基于jfinal render的超简单验证吗插件 cn.dreampie.jfinal-quartz &nbsp; &nbsp; &nbsp;&nbsp;https://github.com/Dreampie/jfinal-quartz&nbsp;&nbsp; 基于jfinal 的quartz管理器 cn.dreampie.jfinal-sqlinxml &nbsp; &nbsp; &nbsp;https://github.com/Dreampie/jfinal-sqlinxml&nbsp;&nbsp; 基于jfinal 的类似ibatis的sql语句管理方案 cn.dreampie.jfinal-lesscss &nbsp; &nbsp; &nbsp;&nbsp;https://github.com/Dreampie/jfinal-lesscss&nbsp; &nbsp;java实现的lesscsss实时编译插件,可以由于jfinal cn.dreampie.jfinal-coffeescript &nbsp; &nbsp;&nbsp;https://github.com/Dreampie/jfinal-coffeescript&nbsp; &nbsp;java实现的coffeescript实时编译插件,可以由于jfinal&nbsp; cn.dreampie.jfinal-akka &nbsp; &nbsp;https://github.com/Dreampie/jfinal-akka&nbsp; &nbsp;java使用akka执行异步任务 cn.dreampie.jfinal-mailer &nbsp; &nbsp; &nbsp;&nbsp;https://github.com/Dreampie/jfinal-mailer&nbsp; &nbsp;使用akka发布邮件的jfinal插件 cn.dreampie.jfinal-slf4j &nbsp; &nbsp;&nbsp;https://github.com/Dreampie/jfinal-slf4j&nbsp; &nbsp;让jfinal使用slf4j的日志api 使用方法请移步:http://my.oschina.net/wangrenhui1990/blog 部分代码正在调试和开发,欢迎大家使用 介绍-> jfinal-dreampie是一个基于jfinal的开源框架库,主要集成或调优功能如下(由于篇幅原因部分源码未贴出,可以到github下载源码): 1.缓存维护更细粒度 &nbsp;@CacheNameRemove(name&nbsp;=&nbsp;AppConstants.DEFAULT_CACHENAME) @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,&nbsp;ElementType.METHOD}) public&nbsp;@interface&nbsp;CacheNameRemove&nbsp;{ &nbsp;&nbsp;String&nbsp;name(); &nbsp;&nbsp;String[]&nbsp;keys()&nbsp;default&nbsp;{}; } //根据key值来移除基于某个特定方法的缓存,而不是移除整个controller下的缓存 String&nbsp;controllerKey&nbsp;=&nbsp;ai.getControllerKey(); &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!ValidateUtils.me().isNullOrEmpty(removeCacheName))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;keyPrefix&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!ValidateUtils.me().isNullOrEmpty(removeCacheKeys))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(String&nbsp;removeKey&nbsp;:&nbsp;removeCacheKeys)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyPrefix&nbsp;=&nbsp;controllerKey&nbsp; &nbsp;SLASH&nbsp; &nbsp;removeKey; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeByCacheKey(removeCacheName,&nbsp;keyPrefix); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyPrefix&nbsp;=&nbsp;controllerKey; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeByCacheKey(removeCacheName,&nbsp;keyPrefix); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} 2.增加Slf4jLogger实现,然日志配置能基于任何Slf4j下的log实现,如logback public&nbsp;class&nbsp;Slf4jLogFactory&nbsp;implements&nbsp;ILoggerFactory 3.基础model实现,实现基础的常用的部分功能用于复用 &nbsp;public&nbsp;List<M>&nbsp;findAll()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;find(getSelectSql()&nbsp; &nbsp;getExceptSelectSql()); &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;List<M>&nbsp;findBy(String&nbsp;where,&nbsp;Object...&nbsp;paras)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;find(getSelectSql()&nbsp; &nbsp;getExceptSelectSql()&nbsp; &nbsp;getWhere(where),&nbsp;paras); &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;List<M>&nbsp;findTopBy(int&nbsp;topNumber,&nbsp;String&nbsp;where,&nbsp;Object...&nbsp;paras)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;paginate(1,&nbsp;topNumber,&nbsp;getSelectSql(),&nbsp;getExceptSelectSql()&nbsp; &nbsp;getWhere(where),&nbsp;paras).getList(); &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;M&nbsp;findFirstBy(String&nbsp;where,&nbsp;Object...&nbsp;paras)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;findFirst(getSelectSql()&nbsp; &nbsp;getExceptSelectSql()&nbsp; &nbsp;getWhere(where),&nbsp;paras); &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;Page<M>&nbsp;paginateAll(int&nbsp;pageNumber,&nbsp;int&nbsp;pageSize)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;paginate(pageNumber,&nbsp;pageSize,&nbsp;getSelectSql(),&nbsp;getExceptSelectSql()); &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;Page<M>&nbsp;paginateBy(int&nbsp;pageNumber,&nbsp;int&nbsp;pageSize,&nbsp;String&nbsp;where,&nbsp;Object...&nbsp;paras)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;paginate(pageNumber,&nbsp;pageSize,&nbsp;getSelectSql(),&nbsp;getExceptSelectSql()&nbsp; &nbsp;getWhere(where),&nbsp;paras); &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;boolean&nbsp;updateAll(String&nbsp;set,&nbsp;Object...&nbsp;paras)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Db.update(getUpdateSql()&nbsp; &nbsp;getSet(set),&nbsp;paras)&nbsp;>&nbsp;0; &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;boolean&nbsp;updateBy(String&nbsp;set,&nbsp;String&nbsp;where,&nbsp;Object...&nbsp;paras)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Db.update(getUpdateSql()&nbsp; &nbsp;getSet(set)&nbsp; &nbsp;getWhere(where),&nbsp;paras)&nbsp;>&nbsp;0; &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;boolean&nbsp;deleteAll()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Db.update(getDeleteSql())&nbsp;>&nbsp;0; &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;boolean&nbsp;deleteBy(String&nbsp;where,&nbsp;Object...&nbsp;paras)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Db.update(getDeleteSql()&nbsp; &nbsp;getWhere(where),&nbsp;paras)&nbsp;>&nbsp;0; &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;boolean&nbsp;dropAll()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Db.update(getDropSql())&nbsp;>&nbsp;0; &nbsp;&nbsp;} &nbsp;&nbsp;public&nbsp;boolean&nbsp;dropBy(String&nbsp;where,&nbsp;Object...&nbsp;paras)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Db.update(getDropSql()&nbsp; &nbsp;getWhere(where),&nbsp;paras)&nbsp;>&nbsp;0; &nbsp;&nbsp;} 4.akka异步执行框架 public&nbsp;class&nbsp;AkkaPlugin&nbsp;implements&nbsp;IPlugin Akka.system().scheduler().scheduleOnce(Duration.create(1000,&nbsp;TimeUnit.MILLISECONDS), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;Runnable()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;run()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//do&nbsp;Something &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;Akka.system().dispatcher()); 5.atmosphere &nbsp;chat demo @ManagedService(path&nbsp;=&nbsp;"/im/{room:&nbsp;[a-zA-Z][a-zA-Z_0-9]*}") public&nbsp;class&nbsp;ChatRoom&nbsp;{ } 6.coffeescript &nbsp;compiler plugin,编译coffeescript代码,并监控文件改动重新编译 public&nbsp;class&nbsp;CoffeeScriptPlugin&nbsp;implements&nbsp;IPlugin&nbsp;{ } 7.Flyway 数据库自动脚本升级 Plugin,用于自动生成或升级数据库,避免不断使用数据库工具修改数据导致的版本问题 public&nbsp;class&nbsp;FlywayPlugin&nbsp;implements&nbsp;IPlugin&nbsp;{ } 8.lesscss compiler plugin,编译less代码,并监控文件改动重新编译 public&nbsp;class&nbsp;LessCssPlugin&nbsp;implements&nbsp;IPlugin&nbsp;{ } 9.mailer 邮件发送plugin,使用akka异步发送邮件 &nbsp;Akka.system().scheduler().scheduleOnce(Duration.create(1000,&nbsp;TimeUnit.MILLISECONDS), &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;Runnable()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;run()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MailerConf&nbsp;mailerConf&nbsp;=&nbsp;MailerPlugin.mailerConf; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HtmlEmail&nbsp;htmlEmail&nbsp;=&nbsp;new&nbsp;HtmlEmail(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setCharset(mailerConf.getCharset()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setSocketTimeout(mailerConf.getTimeout()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setCharset(mailerConf.getEncode()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setHostName(mailerConf.getHost()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!ValidateUtils.me().isNullOrEmpty(mailerConf.getSslport())) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setSslSmtpPort(mailerConf.getSslport()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!ValidateUtils.me().isNullOrEmpty(mailerConf.getPort())) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setSmtpPort(Integer.parseInt(mailerConf.getPort())); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setSSLOnConnect(mailerConf.isSsl()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setStartTLSEnabled(mailerConf.isTls()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setDebug(mailerConf.isDebug()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setAuthenticator(new&nbsp;DefaultAuthenticator(mailerConf.getUser(),&nbsp;mailerConf.getPassword())); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setFrom(mailerConf.getFrom(),&nbsp;mailerConf.getName()); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setSubject(subject); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.addTo(recipients); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setHtmlMsg(body); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;set&nbsp;the&nbsp;alternative&nbsp;message &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.setTextMsg("Your&nbsp;email&nbsp;client&nbsp;does&nbsp;not&nbsp;support&nbsp;HTML&nbsp;messages"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!ValidateUtils.me().isNullOrEmpty(attachment)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.attach(attachment); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;htmlEmail.send(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(EmailException&nbsp;e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;Akka.system().dispatcher()); 10.自定义验证码,可以自定义使用字符或者数字,颜色和样式可以自调 public&nbsp;class&nbsp;PatchcaRender&nbsp;extends&nbsp;Render&nbsp;{ &nbsp;&nbsp;private&nbsp;static&nbsp;final&nbsp;String&nbsp;CODE_CHAR&nbsp;=&nbsp;"0123456789"; } 11.QuartzPlugin使用quartz执行定时任务,参照部分网络实例,简易实现 QuartzFactory.me().startJobOnce(TimeUtils.me().toString(DateTime.now()),&nbsp; jobId,&nbsp;"stati",&nbsp;this.getClass().getSimpleName(),&nbsp;OrderDataJob.class,&nbsp;param); 12.shiro权限框架,基于数据库url配置过滤,验证码验证 //读取数据库权限只需实现该接口 public&nbsp;interface&nbsp;JdbcAuthzService&nbsp;{ &nbsp;&nbsp;public&nbsp;Map<String,&nbsp;AuthzHandler>&nbsp;getJdbcAuthz(); } 13.shiro的freemarker标签库 <@shiro.hasPermission&nbsp;name="P_USER"> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<li><a&nbsp;href="/admin/user">${i18n.getText("admin.user")}</a></li> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</@shiro.hasPermission> 14.xss过滤的StringEscapeUtils过滤器实现 public&nbsp;class&nbsp;AttackHandler&nbsp;extends&nbsp;Handler&nbsp;{ &nbsp;&nbsp;@Override &nbsp;&nbsp;public&nbsp;void&nbsp;handle(String&nbsp;target,&nbsp;HttpServletRequest&nbsp;request,&nbsp;HttpServletResponse&nbsp;response,&nbsp;boolean[]&nbsp;isHandled)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;request&nbsp;=&nbsp;new&nbsp;HttpServletRequestWrapper(request); &nbsp;&nbsp;&nbsp;&nbsp;nextHandler.handle(target,&nbsp;request,&nbsp;response,&nbsp;isHandled); &nbsp;&nbsp;} } 15.json数据请求时,返回的error信息使用json字符串 public&nbsp;class&nbsp;JsonErrorRenderFactory&nbsp;implements&nbsp;IErrorRenderFactory&nbsp;{ &nbsp;&nbsp;public&nbsp;Render&nbsp;getRender(int&nbsp;errorCode,&nbsp;String&nbsp;view)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(ThreadLocalUtil.isJson()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;JsonErrorRender(errorCode,&nbsp;view); &nbsp;&nbsp;&nbsp;&nbsp;else &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;ErrorRender(errorCode,&nbsp;view); &nbsp;&nbsp;} } 16.自动绑定多数据源的tablebind AutoMultiSourceTableBindPlugin tableBindDefault = new AutoMultiSourceTableBindPlugin(druidDefault, SimpleNameStyles.LOWER); //让default数据源排除shop目录下的model,因为该目录的model属于custom数据源 tableBindDefault.addExcludePaths("cn.dreampie.function.shop"); AutoMultiSourceTableBindPlugin tableBindCustom = new AutoMultiSourceTableBindPlugin(druidCustom, SimpleNameStyles.LOWER); //让custom只扫描shop目录,注意当使用includepaths是只会扫描配置的路径,如果没有使用includepaths会扫描全路径 tableBindCustom.addIncludePaths("cn.dreampie.function.shop"); 17.压缩请求数据的gzipFilter,可测试 <!--gzip compress filter--> <filter> <filter-name>gzipFilter</filter-name> <filter-class>cn.dreampie.common.web.filter.gzip.GZIPFilter</filter-class> </filter> <filter-mapping> <filter-name>gzipFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <!--gzip compress filter--> 18.http缓存cacheFilter,和gzipFilter共同用于提高用户性能 <!-- cache filter--> <filter> <filter-name>cacheFilter</filter-name> <filter-class>cn.dreampie.common.web.filter.cache.CacheFilter</filter-class> </filter> <filter-mapping> <filter-name>cacheFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <!--cache filter--> 标签:jfinal

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值