CSS:限制图片最大宽度
img{max-width:800px;width:expression(this.width > 800 ? 800: true);height:auto;}
img{max-width:800px;width:expression(this.width > 800 ? 800: true);height:auto;}
HSSFWorkbook wb = new HSSFWorkbook();
OutputStream out = new FileOutputStream(“x.xls”);
wb.write(out);
out.close();
return new File(“x.xls”);
ByteArrayOutputStream out = new ……..;
wb………
out.close();
ByteArrayInputStream in = new ………..(out.toByte…);
return in;
/e/class/userfun.php
function currentPage($classid,$thisid){ global $class_r; $fr=explode('|',$class_r[$classid][featherclass]); $topbclassid=$fr[1]?$fr[1]:$classid;//取得第一级栏目id if ($topbclassid==$thisid) { echo "class='cur'"; } else { } }
头部模板:
<ul> <li <?php if(empty($GLOBALS[navclassid])){echo "class='cur'";} ?>><a id="nav-hover0" href="[!--news.url--]">首页</a></li> <?php $i=0; $path=""; ?> [e:loop={'select classid,classname,classpath,wburl from [!db.pre!]enewsclass where bclassid=0 order by classid',0,24,0}] <?php $i=$i+1; $path=$public_r[newsurl].$bqr[classpath]; if(!empty($bqr[wburl])){ $path=$bqr[wburl]; } ?> <li <?=currentPage($GLOBALS[navclassid],$bqr[classid])?>> <a id="nav-hover<?=$i?>" href="<?=$path?>" title="<?=$bqr[classname]?>" target="_self" ><?=$bqr[classname]?></a> </li> [/e:loop] </ul>
首先配置好运行环境:
其次修改nginx配置文件:
server { listen 80; server_name localhost; location ~ ^/bbs/.+\.php$ { alias E:/xuetang/cn/bbs; rewrite /bbs/(.*\.php?) /$1 break; fastcgi_index index.php; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME E:/xuetang/cn/bbs$fastcgi_script_name; include fastcgi_params; } location ~ ^/bbs($|/.*) { alias E:/xuetang/cn/bbs/$1; index index.php index.html index.htm; } location / { root E:/xuetang/cn/www; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location ~ \.php$ { root E:/xuetang/cn/www; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
注意虚拟目录配置要在根目录上面。。
/** * 发送post请求 * @param string $url 请求地址 * @param array $post_data post数据 * @return string */ function send_post($url, $post_data) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS,$post_data); curl_setopt($ch, CURLOPT_RETURNTRANSFER,true); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($post_data)) ); return curl_exec($ch); } <?php header("Content-type: text/html; charset=utf-8"); include_once('../functions.php'); $send_msg="test";//发送内容 $data = array("openid" => "oXS2NuPCEB836NRMrsXXXXXX", "content" => $send_msg); $data_string = json_encode($data); echo send_post('http://XXX.cn/api/wx/push/custom/text?mykey=XXXXXX', $data_string); ?>
1、上传文件的文件池路径问题
upload.js
filePool : {
type : “cn.xuetang.common.file.FilePool”,
args : [“/temp/”, 2000]
}
将路径改到项目的路径下
public class FilePool extends NutFilePool {
public FilePool(String homePath, long size) {
super(webinfPath(homePath), size);
}
private static final String webinfPath(String str) {
return Mvcs.getServletContext().getRealPath(“/WEB-INF”)+str;
}
}
2、Nutz大字段缓存的问题
.nutz/tmp/dao
将 org.nutz.dao.jdbc.nutz_jdbc_experts.js 拷贝到项目类路径下,修改相应的配置,文件夹不冲突即可。
编写执行文件 job.sh
#!/bin/sh CLASSPATH=classes:lib/druid-1.0.1.jar:lib/htmlparser-1.6.jar:lib/log4j-1.2.17.jar:lib/mysql-connector-java-5.1.26-bin.jar:lib/nutz-1.b.50.jar:lib/ojdbc14.jar:lib/quartz-2.2.1.jar:lib/quartz-jobs-2.2.1.jar:lib/slf4j-api-1.6.6.jar:lib/slf4j-log4j12-1.6.6.jar:lib/sqljdbc4.jar:lib/commons-pool2-2.2.jar: #export CLASSPATH java -classpath $CLASSPATH cn.xuetang.job.MyJob &
赋予job.sh 执行权限
chmod a+x job.sh
后台执行,并把标准输出重定向,关闭终端仍在执行
nohup bash /home/work/ImageTask/job.sh > success.log 2>error.log &
输出在当前控制台,关闭该终端时,将退出启动的进程
/home/work/ImageTask/job.sh
每两分钟启动一次,关闭终端不影响任务
crontab -e
*/2 * * * * /home/work/ImageTask/job.sh > success.log 2>error.log &
<Context path=”” docBase=”/usr/local/tomcat8080/webapps/ROOT” reloadable=”true” sessionCookiePath=”/” sessionCookieName=”BB_SESSION”/>
更改SESSION名称。
常用命令
复制文件夹
cp -ri apache-tomcat-7.0.53 /usr/local/tomcat1
删除文件夹
rm -rf
解压文件
tar -xzvf apache-tomcat-7.0.53.tar.gz
安装C++编码环境
yum install -y gcc-c++
安装HTTP GZIP
yum install -y zlib-devel
后台运行
java -jar aaa.jarr &
kill 脚本
kill -15 `ps -ef|grep server.jar|grep -v grep |awk ‘{print $2}’`
/usr/local/nginx/sbin/nginx -t #测试配置
/usr/local/nginx/sbin/nginx
/usr/local/nginx/sbin/nginx -s stop #停止服务器
/usr/local/tomcat1/bin/startup.sh
/usr/local/tomcat2/bin/startup.sh
/usr/local/tomcat8080/bin/startup.sh
查看端口
netstat -an | grep 80
系统
# uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # hostname # 查看计算机名 # lspci -tv # 列出所有PCI设备 # lsusb -tv # 列出所有USB设备 # lsmod # 列出加载的内核模块 # env # 查看环境变量
资源
# free -m # 查看内存使用量和交换区使用量 # df -h # 查看各分区使用情况 # du -sh <目录名> # 查看指定目录的大小 # grep MemTotal /proc/meminfo # 查看内存总量 # grep MemFree /proc/meminfo # 查看空闲内存量 # uptime # 查看系统运行时间、用户数、负载 # cat /proc/loadavg # 查看系统负载
磁盘和分区
# mount | column -t # 查看挂接的分区状态 # fdisk -l # 查看所有分区 # swapon -s # 查看所有交换分区 # hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备) # dmesg | grep IDE # 查看启动时IDE设备检测状况
网络
# ifconfig # 查看所有网络接口的属性 # iptables -L # 查看防火墙设置 # route -n # 查看路由表 # netstat -lntp # 查看所有监听端口 # netstat -antp # 查看所有已经建立的连接 # netstat -s # 查看网络统计信息
进程
# ps -ef # 查看所有进程 # top # 实时显示进程状态
用户
# w # 查看活动用户 # id <用户名> # 查看指定用户信息 # last # 查看用户登录日志 # cut -d: -f1 /etc/passwd # 查看系统所有用户 # cut -d: -f1 /etc/group # 查看系统所有组 # crontab -l # 查看当前用户的计划任务
服务
# chkconfig --list # 列出所有系统服务 # chkconfig --list | grep on # 列出所有启动的系统服务
程序
# rpm -qa # 查看所有安装的软件包
入口函数:
@At
public void downImage(@Param(“tvid”) int tvid, HttpServletResponse resp, HttpServletRequest req) {
}
使用Nutz文件池:
Globals.FILE_POOL= new NutFilePool(“~/tmp/myfiles”, 10);
源码:
int i = 0; File f = Globals.FILE_POOL.createFile(".zip"); ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f.getAbsolutePath())); for (Weixin_image image : list) { i++; String filename = Strings.sNull(bbinfo.get(image.getUid())) + "_" + Strings.sNull(userinfo.get(image.getUid())) + "_" + i+".jpg"; String picurl = image.getPicurl(); if (!Strings.isBlank(image.getImage_url())) { picurl = image.getImage_url(); } URL url = new URL(picurl); try { URLConnection conn = url.openConnection(); InputStream inStream = conn.getInputStream(); byte[] buffer = new byte[1204]; out.putNextEntry(new ZipEntry(filename)); while ((byteread = inStream.read(buffer)) != -1) { bytesum += byteread; out.write(buffer, 0, byteread); } out.closeEntry(); inStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } out.close(); resp.setHeader("Content-Length", "" + f.length()); resp.setHeader("Content-Disposition", "attachment; filename=\"" + tvShow.getPlay_name() + ".zip\""); Streams.writeAndClose(resp.getOutputStream(), Streams.fileIn(f));
仅作参考。
编辑配置Nutz redis配置文件:
var ioc = { jedisConfig : { type : 'cn.xuetang.common.redis.JedisConfig', fields : { maxTotal : 200, maxIdle : 10, maxWaitMillis:10001, testOnBorrow:true, redisUrl:'127.0.0.1', redisPort:6379, redisTimeout:1000 } } }
package cn.xuetang.common.redis; /** * Created by Wizzer on 14-4-8. */ public class JedisConfig { private int maxTotal; private int maxIdle; private int maxWaitMillis; private boolean testOnBorrow; private String redisUrl; private int redisPort; private int redisTimeout;//redis断开后自动重新连接间隔时间 public int getMaxTotal() { return maxTotal; } public void setMaxTotal(int maxTotal) { this.maxTotal = maxTotal; } public int getMaxIdle() { return maxIdle; } public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; } public int getMaxWaitMillis() { return maxWaitMillis; } public void setMaxWaitMillis(int maxWaitMillis) { this.maxWaitMillis = maxWaitMillis; } public boolean isTestOnBorrow() { return testOnBorrow; } public void setTestOnBorrow(boolean testOnBorrow) { this.testOnBorrow = testOnBorrow; } public String getRedisUrl() { return redisUrl; } public void setRedisUrl(String redisUrl) { this.redisUrl = redisUrl; } public int getRedisPort() { return redisPort; } public void setRedisPort(int redisPort) { this.redisPort = redisPort; } public int getRedisTimeout() { return redisTimeout; } public void setRedisTimeout(int redisTimeout) { this.redisTimeout = redisTimeout; } }
Nutz入口类加载配置文件,config路径:
@Modules(scanPackage=true) @Ok("raw") @Fail("http:500") @IocBy(type=ComboIocProvider.class,args={ "*org.nutz.ioc.loader.json.JsonLoader","config", "*org.nutz.ioc.loader.annotation.AnnotationIocLoader","cn.xuetang"}) @SetupBy(value=StartSetup.class) @UrlMappingBy(value=UrlMappingSet.class) public class MainModule { }
初始化配置参数,新建订阅消息处理线程:
public static JedisConfig REDIS_CONFIG; //声明全局的redis连接池 public static ShardedJedisPool SHARDEDJEDIS_POOL=null; public static JedisPool JEDIS_POOL=null; public static void InitRedisConfig() {//初始化redis REDIS_CONFIG = Mvcs.ctx.getDefaultIoc().get(JedisConfig.class); JedisPoolUtil jedisPoolUtil=new JedisPoolUtil(); SHARDEDJEDIS_POOL = jedisPoolUtil.getShardedJedisPool(); JEDIS_POOL = jedisPoolUtil.getJedisPool(); } new Thread(Mvcs.getIoc().get(ImageTask.class)).start();
创建Jedis连接池工具类:
package cn.xuetang.common.redis; import cn.xuetang.common.config.Globals; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.ShardedJedisPool; import java.util.ArrayList; import java.util.List; /** * Created by Wizzer on 14-4-8. */ public class MyJedis { private String redisUrl; private int redisPort; public JedisPoolConfig jedisPoolConfig(){ JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(Globals.REDIS_CONFIG.getMaxTotal()); jedisPoolConfig.setMaxIdle(Globals.REDIS_CONFIG.getMaxIdle()); jedisPoolConfig.setMaxWaitMillis(Globals.REDIS_CONFIG.getMaxWaitMillis()); jedisPoolConfig.setTestOnBorrow(Globals.REDIS_CONFIG.isTestOnBorrow()); return jedisPoolConfig; } public JedisShardInfo jedisShardInfo(){ return new JedisShardInfo(redisUrl, redisPort); } public JedisPool jedisPool(){ return new JedisPool(jedisPoolConfig(),redisUrl, redisPort); } public ShardedJedisPool shardedJedisPool(){ this.redisUrl=Globals.REDIS_CONFIG.getRedisUrl(); this.redisPort=Globals.REDIS_CONFIG.getRedisPort(); List<JedisShardInfo> jedisList = new ArrayList<JedisShardInfo>(); jedisList.add(jedisShardInfo()); return new ShardedJedisPool(jedisPoolConfig(), jedisList); } }
实现自己的监听类:
package cn.xuetang.common.redis; import org.nutz.log.Log; import org.nutz.log.Logs; import redis.clients.jedis.JedisPubSub; /** * 订阅监听类 * Created by Wizzer on 14-4-8. */ public class MyJedisListenter extends JedisPubSub { private final static Log log = Logs.get(); // 取得订阅的消息后的处理 public void onMessage(String channel, String message) { log.info(channel + "=" + message); } // 初始化订阅时候的处理 public void onSubscribe(String channel, int subscribedChannels) { log.info(channel + "=" + subscribedChannels); } // 取消订阅时候的处理 public void onUnsubscribe(String channel, int subscribedChannels) { log.info(channel + "=" + subscribedChannels); } // 初始化按表达式的方式订阅时候的处理 public void onPSubscribe(String pattern, int subscribedChannels) { log.info(pattern + "=" + subscribedChannels); } // 取消按表达式的方式订阅时候的处理 public void onPUnsubscribe(String pattern, int subscribedChannels) { log.info(pattern + "=" + subscribedChannels); } // 取得按表达式的方式订阅的消息后的处理 public void onPMessage(String pattern, String channel, String message) { log.info(pattern + "=" + channel + "=" + message); } }
获取单例Jedis连接池:
package cn.xuetang.common.redis; import cn.xuetang.common.config.Globals; import org.nutz.log.Log; import org.nutz.log.Logs; import redis.clients.jedis.JedisPool; import redis.clients.jedis.ShardedJedisPool; import java.util.Date; /** * Created by Wizzer on 14-4-8. */ public class JedisPoolUtil { private final static Log log = Logs.get(); public synchronized ShardedJedisPool getShardedJedisPool() { if (Globals.SHARDEDJEDIS_POOL == null) { MyJedis myJedis=new MyJedis(); Globals.SHARDEDJEDIS_POOL = myJedis.shardedJedisPool(); } return Globals.SHARDEDJEDIS_POOL; } public synchronized JedisPool getJedisPool() { if (Globals.JEDIS_POOL== null) { MyJedis myJedis=new MyJedis(); Globals.JEDIS_POOL = myJedis.jedisPool(); } return Globals.JEDIS_POOL; } }
数据入列同时发布订阅消息:
ShardedJedis shardedJedis=Globals.SHARDEDJEDIS_POOL.getResource(); txt.put("appid", appInfo.getId()); shardedJedis.lpush("image", Json.toJson(txt)); Jedis jedis=Globals.JEDISPOOL.getResource(); jedis.publish("newimage","true");
处理订阅消息的类:
package cn.xuetang.common.task; import cn.xuetang.common.action.BaseAction; import cn.xuetang.common.config.Globals; import cn.xuetang.common.redis.MyJedisListenter; import cn.xuetang.common.util.DateUtil; import cn.xuetang.modules.baby.bean.Baby_image; import cn.xuetang.modules.baby.bean.Baby_info; import cn.xuetang.modules.user.bean.User_conn_wx; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.json.Json; import org.nutz.lang.Strings; import org.nutz.log.Log; import org.nutz.log.Logs; import redis.clients.jedis.Jedis; import redis.clients.jedis.ShardedJedis; import java.util.*; /** * Created by Wizzer on 14-3-31. */ @IocBean public class ImageTask extends BaseAction implements Runnable { @Inject protected Dao dao; private final static Log log = Logs.get(); public void run() { try { log.info("ImageTask start!"); final JedisPoolUtil jedisPoolUtil = new JedisPoolUtil(); boolean isEnable = false; while (!isEnable) { try { jedisPoolUtil.getShardedJedisPool().getResource(); isEnable = true; } catch (Exception e) { log.info("The redis connection is not successful,wait " + Globals.REDIS_CONFIG.getRedisTimeout() + "ms try again."); } try { wait(Globals.REDIS_CONFIG.getRedisTimeout()); } catch (Exception e) { } } final ShardedJedis shardedJedis = jedisPoolUtil.getShardedJedisPool().getResource(); final Jedis jedis = jedisPoolUtil.getJedisPool().getResource(); MyJedisListenter listenter = new MyJedisListenter() { @Override public void onMessage(String channel, String message) { //业务代码具体实现 while (shardedJedis.exists("image")) { String data = shardedJedis.rpop("image"); } } }; jedis.subscribe(listenter, "newimage"); } catch (Exception e) { log.error(e); } } }
Request req = Request.create("http://127.0.0.1/api/user/sendtext?mykey=" + mykey, Request.METHOD.POST); JsonFormat jsonFormat=new JsonFormat(); jsonFormat.setAutoUnicode(true);//防止中文乱码,以unicode编码,根据需要设置 req.setData(Json.toJson(map,jsonFormat)); req.getHeader().set("Content-Type","application/octet-stream");//设置以字节流传送数据 Response resp = Sender.create(req).send(); if (resp.isOK()) { log.info(resp.getContent()); }
昨天在公交车站等车,看见一小孩子拿了一大包巧克力在吃,一会儿吃了半袋子。我出于好心说了句:小孩子巧克力不能多吃,吃多了会得病。小孩子对我说:我爷爷今年103岁了。我说:因为吃巧克力?小孩说:不是,因为他从来不管闲事。
功能比较类似于JEECMS,基于Nutz 所以二次开发非常容易,并且UI表现层完全和JEECMS不一样,主要是ajax+弹出窗口的方式。
Q-Q: 1162-4317
Q群:2631-0065 合肥Android/Java开发-GDG
运行效果:
领导在门外用门夹核桃,我从门口路过,顺嘴说了一句,用门夹过的核桃还能补脑吗?领导愣了愣,把核桃扔垃圾篓了。刚经过领导电脑桌前,看到领导在百度:门夹过的核桃为什么不能补脑?我滴个天哪,度娘你可给点靠谱答案吧,不然他不得揍死我啊。ps,领导刚从美国回来不久。。。。
StartSetup 项目启动时新建线程:
package com.hits.core; import com.hits.modules.cms.task.LoadTask; import org.nutz.log.Log; import org.nutz.log.Logs; import org.nutz.mvc.NutConfig; import org.nutz.mvc.Setup; import com.hits.common.config.Globals; import org.quartz.SchedulerException; import org.quartz.impl.StdSchedulerFactory; /** * 类描述: 创建人:Wizzer 联系方式:www.wizzer.cn 创建时间:2013-11-26 下午2:11:13 */ public class StartSetup implements Setup { private final static Log log = Logs.get(); @Override public void destroy(NutConfig config) { } @Override public void init(NutConfig config) { try { //初始化Quartz任务 Globals.SCHEDULER = StdSchedulerFactory.getDefaultScheduler(); new Thread(config.getIoc().get(LoadTask.class)).start(); } catch (SchedulerException e) { log.error(e); } catch (Exception e) { log.error(e); } } }
LoadTask.java 从任务表中加载任务,定时执行类方法:
package com.hits.modules.cms.task; import com.hits.common.action.BaseAction; import com.hits.common.config.Globals; import com.hits.modules.cms.task.bean.Cms_task; import org.apache.commons.lang.StringUtils; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.integration.quartz.NutQuartzJobFactory; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.log.Log; import org.nutz.log.Logs; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import java.util.*; /** * Created by Wizzer on 14-3-4. */ @IocBean public class LoadTask extends BaseAction implements Runnable { @Inject protected Dao dao; private final static Log log = Logs.get(); public void run() { List<Cms_task> tasks = daoCtl.list(dao, Cms_task.class, Cnd.where("is_enable", "=", 0)); Globals.SCHEDULER.setJobFactory(new NutQuartzJobFactory()); for (int i = 0; i < tasks.size(); i++) { Cms_task task = tasks.get(i); try { Map<String, String> map = new HashMap<String, String>(); if (task.getTask_type() == 2 || task.getTask_type() == 3) { map.put("site_id", task.getSite_id()); map.put("channel_id", task.getParam_value()); } else if (task.getTask_type() == 1) { map.put("site_id", task.getSite_id()); } JobBuilder jobBuilder = JobBuilder.newJob(getClassByTask(task.getJob_class())); jobBuilder.setJobData(getJobDataMap(map)); TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger(); if (StringUtils.isNotBlank(task.getTask_code())) { jobBuilder.withIdentity(task.getTask_code(), Scheduler.DEFAULT_GROUP); triggerBuilder.withIdentity(task.getTask_code(), Scheduler.DEFAULT_GROUP); } else { UUID uuid = UUID.randomUUID(); jobBuilder.withIdentity(uuid.toString(), Scheduler.DEFAULT_GROUP); triggerBuilder.withIdentity(uuid.toString(), Scheduler.DEFAULT_GROUP); task.setTask_code(uuid.toString()); daoCtl.update(dao, task); } triggerBuilder.withSchedule(getCronScheduleBuilder(getCronExpressionFromDB(task))); //调度任务 Globals.SCHEDULER.scheduleJob(jobBuilder.build(), triggerBuilder.build()); } catch (SchedulerException e) { log.error(e); } catch (ClassNotFoundException e) { log.error(e); } catch (Exception e) { log.error(e); } } if(tasks.size()>0){ Globals.SCHEDULER.start(); } } public static CronScheduleBuilder getCronScheduleBuilder(String cronExpression) { return CronScheduleBuilder.cronSchedule(cronExpression); } public String getCronExpressionFromDB(Cms_task task) { if (task.getExecycle() == 2) { return task.getCron_expression(); } else { int execycle = task.getTask_interval_unit(); String excep = ""; if (execycle == 5) {//月 excep = "0 " + task.getMinute() + " " + task.getHour() + " " + task.getDay_of_month() + " * ?"; } else if (execycle == 4) {//周 excep = "0 " + task.getMinute() + " " + task.getHour() + " " + " ? " + " * " + task.getDay_of_week(); } else if (execycle == 3) {//日 excep = "0 " + task.getMinute() + " " + task.getHour() + " " + " * * ?"; } else if (execycle == 2) {//时 excep = "0 0 */" + task.getInterval_hour() + " * * ?"; } else if (execycle == 1) {//分 excep = "0 */" + task.getInterval_minute() + " * * * ?"; } return excep; } } /** * @param params 任务参数 * @return */ private JobDataMap getJobDataMap(Map<String, String> params) { JobDataMap jdm = new JobDataMap(); Set<String> keySet = params.keySet(); Iterator<String> it = keySet.iterator(); while (it.hasNext()) { String key = it.next(); jdm.put(key, params.get(key)); } return jdm; } /** * @param taskClassName 任务执行类名 * @return * @throws ClassNotFoundException */ @SuppressWarnings("unchecked") private Class getClassByTask(String taskClassName) throws ClassNotFoundException { return Class.forName(taskClassName); } }
quartz-2.2.1 配置文件:
# Default Properties file for use by StdSchedulerFactory # to create a Quartz Scheduler Instance, if a different # properties file is not explicitly specified. # # 跳过版本检查 # org.quartz.scheduler.skipUpdateCheck=true org.quartz.scheduler.instanceName = DefaultQuartzScheduler org.quartz.scheduler.rmi.export = false org.quartz.scheduler.rmi.proxy = false org.quartz.scheduler.wrapJobExecutionInUserTransaction = false # 用NutIoc接管Quartz的JobFactory,实现用户需要的注入功能 # org.quartz.scheduler.jobFactory.class=org.nutz.integration.quartz.NutQuartzJobFactory org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true org.quartz.jobStore.misfireThreshold = 60000 # 使用内存JobStore # org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
NutQuartzJobFactory.java 下载地址:
适用于 Nutz+SWFUpload、Nutz+plupload 、Ueditor 等控件文件上传,验证用户身份。
/** * 验证用户帐号,保存文件 * * @param tmpFile * @param filetype * @param file_password * @param file_username * @param errCtx * @return */ @At @Ok("raw") @AdaptBy(type = UploadAdaptor.class, args = "ioc:upload") public JSONObject uploadOneSave(@Param("Filedata") TempFile tmpFile, @Param("ueditor") String ueditor1, @Param("filetype") String filetype, @Param("title") String title, @Param("file_password") String file_password, @Param("file_username") String file_username, AdaptorErrorContext errCtx) { boolean ueditor = false;//是否是百度编辑器,编辑器对应的JS要做相应的修改 if ("true".equals(StringUtil.null2String(ueditor1))) ueditor = true; System.out.println("ueditor::::::::::"+ueditor); JSONObject js = new JSONObject(); if (errCtx != null) { if (errCtx.getAdaptorErr() != null) { if (ueditor) { js.put("state", errorMsg(errCtx.getAdaptorErr())); } else { js.put("error", errorMsg(errCtx.getAdaptorErr())); js.put("msg", ""); } System.out.println("js1::::::::::"+js.toString()); return js; } for (Throwable e : errCtx.getErrors()) { if (e != null) { if (ueditor) { js.put("state", errorMsg(e)); } else { js.put("error", errorMsg(e)); js.put("msg", ""); } return js; } } } if ("".equals(StringUtil.null2String(file_username)) || "".equals(StringUtil.null2String(file_password))) { if (ueditor) { js.put("state", "错误:请配置文件服务器用户名及密码!"); } else { js.put("error", "错误:请配置文件服务器用户名及密码!"); js.put("msg", ""); } return js; } Ioc ioc = new NutIoc(new JsonLoader("config/fileserver.json")); String u = ioc.get(FileServer.class, "fileserver").getUsername(); String p = ioc.get(FileServer.class, "fileserver").getPassword(); if (!u.equals(file_username) || !p.equals(DecodeUtil.Decrypt(file_password))) { if (ueditor) { js.put("state", "错误:文件服务器用户名或密码不正确!"); } else { js.put("error", "错误:文件服务器用户名或密码不正确!"); js.put("msg", ""); } return js; } if (tmpFile == null || tmpFile.getFile().length() < 10) { if (ueditor) { js.put("state", "错误:文件大小不可小于10B!"); } else { js.put("error", "错误:文件大小不可小于10B!"); js.put("msg", ""); } return js; } String filename = tmpFile.getMeta().getFileLocalName(); File file = tmpFile.getFile(); String suffixname = Files.getSuffixName(file).toLowerCase(); String ss = FileType.getSuffixname(upload, filetype); if (!ss.contains(suffixname)) { if (ueditor) { js.put("state", "错误:不允许的文件扩展名,允许:" + ss); } else { js.put("error", "错误:不允许的文件扩展名,允许:" + ss); js.put("msg", ""); } return js; } long len = tmpFile.getFile().length(); filename = filename.substring(0, filename.lastIndexOf(".")) + "." + suffixname; String date = DateUtil.getToday(); String uuid = UUID.randomUUID().toString().replaceAll("-", ""); String fname = uuid + "." + Files.getSuffixName(file).toLowerCase(); String dest = webPath(date, fname, suffixname); try { Files.move(file, new File(dest)); } catch (IOException e) { e.printStackTrace(); if (ueditor) { js.put("state", "错误:文件服务器IO异常!"); } else { js.put("error", "错误:文件服务器IO异常!"); js.put("msg", ""); } return js; } JSONObject fs = new JSONObject(); if (ueditor) { js.put("state", "SUCCESS"); js.put("original", filename); js.put("url", "/upload/" + FileType.getFileType(upload, suffixname) + "/" + date + "/" + fname); js.put("title", title); } else { fs.put("filename", filename); fs.put("filepath", "/upload/" + FileType.getFileType(upload, suffixname) + "/" + date + "/" + fname); fs.put("filesize", StringUtil.getFileSize(len, 2)); js.put("error", ""); js.put("msg", fs); } return js; } /** * 获取上传路径,根据文件类型+日期生成路径 * * @param date * @param fname * @param suffixname * @return */ public String webPath(String date, String fname, String suffixname) { String newfilepath = Mvcs.getServletContext().getRealPath( "/upload/" + FileType.getFileType(upload, suffixname) + "/" + date + "/"); Files.createDirIfNoExists(newfilepath); return newfilepath + "\\" + fname; } /** * 根据异常提示错误信息 * * @param t * @return */ private String errorMsg(Throwable t) { if (t == null || t.getClass() == null) { return "错误:未知system错误!"; } else { String className = t.getClass().getSimpleName(); if (className.equals("UploadUnsupportedFileNameException")) { String name = upload.getContext().getNameFilter(); return "错误:无效的文件扩展名,支持的扩展名:" + name.substring(name.indexOf("(") + 1, name.lastIndexOf(")")).replace("|", ","); } else if (className.equals("UploadUnsupportedFileTypeException")) { return "错误:不支持的文件类型!"; } else if (className.equals("UploadOutOfSizeException")) { return "错误:文件超出" + StringUtil.getFileSize(upload.getContext().getMaxFileSize(), 2) + "MB"; } else if (className.equals("UploadStopException")) { return "错误:上传中断!"; } else { return "错误:未知错误!"; } } }
项目部署根目录增加:crossdomain.xml 文件,解决上传控件跨域上传的问题(应用和文件服务器分开部署):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd" > <cross-domain-policy> <site-control permitted-cross-domain-policies="all" /> <allow-access-from domain="*" /> <allow-http-request-headers-from domain="*" headers="*"/> </cross-domain-policy>
SWFUpload.prototype.setPostParams = function (paramsObject) {
this.settings.post_params = paramsObject;
this.callFlash(“SetPostParams”, [paramsObject]);
};
swfu.setPostParams({ path:$(“#path”).val() });
upload.json 配置文件,增加扩展配置项extOption,内容可以由用户自定义,返回一个Map对象。
我要实现功能是,用户在相册里只允许上传图片文件、视频里只允许上传视频格式的文件等,
结合上传控件和JS,实现在页面级和代码级的文件类型分类限制、分类保存等功能。
Nutz issue 提交需求不被接纳所以只好自己实现了,大家如需要的话可以提issue,希望以后Nutz能内置:
https://github.com/nutzam/nutz/issues/568
upload.json:
var ioc = { upload : { type : "org.nutz.mvc.upload.UploadAdaptor", args : [{refer : "uploadCtx"}] }, uploadCtx : { type : "org.nutz.mvc.upload.UploadingContext", args : [{refer: "filePool"}], fields : { ignoreNull : true, maxFileSize : 10485760, nameFilter : ".+(jpg|gif|png|jpeg|doc|docx|xls|xlsx|ppt|pptx|wps|pdf|txt|chm|mp3|mp4|3gp|rm|swf|flv|asf|wmv|wma|z|zip|rar|ios|jar)", extOption: { "images":"jpg,gif,png,jpeg", "document":"doc,docx,xls,xlsx,ppt,pptx,wps,pdf,txt,chm", "music":"mp3", "video":"mp4,3gp,rm,swf,flv,asf,wmv,wma", "archive":"z,zip,rar,ios,jar" } } }, filePool : { type : "com.hits.common.file.FilePool", args : ["/temp/", 2000] } };
改写Nutz源码:
org.nutz.mvc.upload.UploadingContext 类,增加代码:
/** * 一个扩展配置项,用户可自定义内容 */ private Map<String, String> extOption; public Map<String, String> getExtOption() { return extOption; } public UploadingContext setExtOption(String extOption) { this.extOption = Json.fromJsonAsMap(String.class,extOption); return this; }
增加一个调用类:
FileType.java
/** * 类描述: * 创建人:Wizzer * 联系方式:www.wizzer.cn * 创建时间:2013-12-25 下午1:13:30 * @version */ public class FileType { /** * 根据文件名获取文件类型,默认返回other * @param upload * @param suffixname * @return */ public static String getFileType(UploadAdaptor upload,String suffixname) { Map<String,String> hm=upload.getContext().getExtOption(); String str = StringUtil.null2String(suffixname).toLowerCase(); Set<Map.Entry<String, String>> set = hm.entrySet(); for (Iterator<Map.Entry<String, String>> it = set.iterator(); it.hasNext();) { Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next(); if(entry.getValue().toLowerCase().indexOf(str)>-1) return entry.getKey(); } return "other"; } /** * 根据文件类型获取文件后缀名,默认返回nameFilter配置 * @param upload * @param filetype * @return */ public static String getSuffixname(UploadAdaptor upload,String filetype) { Map<String,String> hm=upload.getContext().getExtOption(); String str = StringUtil.null2String(filetype).toLowerCase(); if(!"".equals(str)){ Set<Map.Entry<String, String>> set = hm.entrySet(); for (Iterator<Map.Entry<String, String>> it = set.iterator(); it.hasNext();) { Map.Entry<String, String> entry = (Map.Entry<String, String>) it.next(); if(entry.getKey().toLowerCase().equals(str)) return entry.getValue(); } } String name=upload.getContext().getNameFilter(); return name.substring(name.indexOf("(")+1,name.lastIndexOf(")")).replace("|", ","); } }
使用示例:
@Inject protected UploadAdaptor upload; @At @Ok("->:/private/file/uploadOne.html") public void uploadOne(@Param("filetype") String filetype,HttpServletRequest req){ req.setAttribute("filetype", filetype); req.setAttribute("allowExtensions", FileType.getSuffixname(upload, filetype)); }
如上所述,在限制文件上传类型的同时,还可以将文件分类保存在不同类型的目录下。