Nutz:代码生成器开源了
项目地址: https://github.com/Wizzercn/NutzCodematic
Nutz 代码生成器:
可以生成Pojo类、Action类;
支持MySQL、Oracle、MS SQL2000、ODBC等;
classes是在jdk1.7下编译,可以直接双击 run.bat 运行。
迟迟没放出来的原因是代码写的太烂……
Wizzer's Blog
项目地址: https://github.com/Wizzercn/NutzCodematic
Nutz 代码生成器:
可以生成Pojo类、Action类;
支持MySQL、Oracle、MS SQL2000、ODBC等;
classes是在jdk1.7下编译,可以直接双击 run.bat 运行。
迟迟没放出来的原因是代码写的太烂……
网易微博登陆验证,第一次请求使用BASE64加密、第二次请求使用MD5+RSA加密,比较变态,于是使用JAVA+JS相结合的方式,调用其JS方法得到加密字符串。
/core1.7.0.js 是经过处理的,删掉几行在JAVA引用中会报错的浏览器对象。
import org.apache.http.HttpResponse; import org.apache.http.client.CookieStore; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.velocity.util.StringUtils; import org.nutz.lang.Files; import org.nutz.lang.util.ClassTools; import org.nutz.repo.Base64; import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; /** * Created by Wizzer on 14-7-7. */ public class Netease { static String index_url = "http://t.163.com/session"; static String login1_url = "http://reg.163.com/services/httpLoginExchgKeyNew"; static String login2_url = "http://reg.163.com/httpLoginVerifyNew.jsp"; static String status_url = "http://t.163.com/share/check/status"; UrlUtil urlUtil = new UrlUtil(); public static void main(String[] args) { CookieStore cookieStore = new Netease().login("email", "password"); } public CookieStore login(String userid, String password) { try { DefaultHttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(login1_url + "?rnd=" + Base64.encodeToString(userid.getBytes(), true) + "&jsonp=setLoginStatus"); get.setHeader("Accept", "*/*"); get.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"); HttpResponse response = client.execute(get); int code = response.getStatusLine().getStatusCode(); if (code == 200) { InputStream in = response.getEntity().getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String line = "", res = ""; while (null != (line = reader.readLine())) { res += line; } System.out.println("res:::" + res); if (res.contains("200")) { String[] str = StringUtils.split(urlUtil.getStr(res, "setLoginStatus(\"", "\")"), "\\n"); String o = str[1], h = str[2]; ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine se = sem.getEngineByName("javascript"); se.eval(getJs()); String jiami = ""; if (se instanceof Invocable) { Invocable invoke = (Invocable) se; jiami = invoke.invokeFunction("getCode", password, o, h).toString(); System.out.println("jiami = " + jiami); } DefaultHttpClient client2 = new DefaultHttpClient(); client2.setCookieStore(client.getCookieStore()); HttpGet get2 = new HttpGet(login2_url + "?rcode=" + jiami + "&product=t&jsonp=setLoginStatus&savelogin=0&username=" + userid); get2.setHeader("Accept", "*/*"); get2.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"); HttpResponse response2 = client2.execute(get2); int code2 = response2.getStatusLine().getStatusCode(); if (code2 == 200) { InputStream in2 = response2.getEntity().getContent(); BufferedReader reader2 = new BufferedReader(new InputStreamReader(in2)); String line2 = "", res2 = ""; while (null != (line2 = reader2.readLine())) { res2 += line2; } System.out.println("res2:::" + res2); if (res.contains("200")) { return client2.getCookieStore(); } } } } return null; } catch (Exception e) { e.printStackTrace(); return null; } } private String getJs() { String jscontent = Files.read(ClassTools.getClassLoader().getResource("").getPath() + "netease" + "/core1.7.0.js"); jscontent += "function getCode(p,o,h){\n" + "\t\t\t\tvar l=new RSAKey();\n" + "\t\t\t\tl.setPublic(h,o);\n" + "\t\t\t\treturn l.encrypt(getMd5(p));\t\t\t\t\n" + " }"; return jscontent; } }
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;
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 &
入口函数:
@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()); }
功能比较类似于JEECMS,基于Nutz 所以二次开发非常容易,并且UI表现层完全和JEECMS不一样,主要是ajax+弹出窗口的方式。
Q-Q: 1162-4317
Q群:2631-0065 合肥Android/Java开发-GDG
运行效果:
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 下载地址: