‘编程学习’ 分类下的所有文章
20154 月27

Nutz 集成Activiti5.17.0 [03]扩展用户、组使用自己的数据表

首先值得一提的是,taskService.createTaskQuery().taskCandidateOrAssigned(userId) 方法有bug,不会调用重写的工厂类,请使用taskService.createTaskQuery().taskCandidateUser(userId)方法。

CustomGroupEntityManager

/**
 * 分组工厂类
 * Created by wizzer on 15-4-27.
 */
@IocBean
public class CustomGroupEntityManager extends GroupEntityManager {
    Dao dao= Mvcs.getIoc().get(Dao.class);
    private final Log log = Logs.get();

    @Override
    public List<Group> findGroupsByUser(String userId) {
        Sql sql = Sqls.create("SELECT a.* FROM sys_role a,sys_user_role b WHERE a.id=b.roleid AND b.userid=@c");
        sql.params().set("c", userId);
        sql.setCallback(Sqls.callback.maps());
        dao.execute(sql);
        List<Map> list=sql.getList(Map.class);
        List<Group> groupList=new ArrayList<Group>();
        for (Map m:list){
            GroupEntity group=new GroupEntity();
            group.setId(Strings.sNull(m.get("id")));
            group.setName(Strings.sNull(m.get("name")));
            group.setType("assignment");
            group.setRevision(1);
            groupList.add(group);
        }
        return groupList;
    }
}

 

CustomGroupEntityManagerFactory

/**
 * 分组接口类
 * Created by wizzer on 15-4-27.
 */
@IocBean
public class CustomGroupEntityManagerFactory implements SessionFactory {
    private GroupEntityManager groupEntityManager;
    public void setGroupEntityManager(GroupEntityManager groupEntityManager) {
        this.groupEntityManager = groupEntityManager;
    }
    @Override
    public Class<?> getSessionType() {
        return GroupIdentityManager.class;
    }
    @Override
    public Session openSession() {
        return groupEntityManager;
    }
}

 

CustomUserEntityManager

/**
 * 用户工厂类
 * Created by wizzer on 15-4-24.
 */
@IocBean
public class CustomUserEntityManager extends UserEntityManager {
    Dao dao= Mvcs.getIoc().get(Dao.class);
    private final Log log = Logs.get();

    @Override
    public User findUserById(String userId) {

        log.info("findUserById:::::::::::::::::::::::::::::::"+userId);
        UserEntity userEntity = new UserEntity();
        Sys_user sysUser = dao.fetch(Sys_user.class, Cnd.where("uid", "=", userId));
        userEntity.setId(userId);
        userEntity.setFirstName(sysUser.getRealname());
        userEntity.setEmail(sysUser.getEmail());
        userEntity.setRevision(1);
        return userEntity;
    }

    @Override
    public List<Group> findGroupsByUser(String userId) {
        // TODO Auto-generated method stub
        log.info("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        Sql sql = Sqls.create("SELECT a.* FROM sys_role a,sys_user_role b WHERE a.id=b.roleid AND b.userid=@c");
        sql.params().set("c", userId);
        sql.setCallback(Sqls.callback.maps());
        dao.execute(sql);
        List<Map> list=sql.getList(Map.class);
        List<Group> groupList=new ArrayList<Group>();
        for (Map m:list){
            GroupEntity group=new GroupEntity();
            group.setId(Strings.sNull(m.get("id")));
            group.setName(Strings.sNull(m.get("name")));
            group.setType("assignment");
            group.setRevision(1);
            groupList.add(group);
        }
        return groupList;
    }


}

 

CustomUserEntityManagerFactory

/**
 * 用户接口类
 * Created by wizzer on 15-4-24.
 */
@IocBean
public class CustomUserEntityManagerFactory implements SessionFactory {
    private UserEntityManager userEntityManager;
    public void setUserEntityManager(UserEntityManager userEntityManager) {
        this.userEntityManager = userEntityManager;
    }
    @Override
    public Class<?> getSessionType() {
        return UserIdentityManager.class;
    }
    @Override
    public Session openSession() {
        return userEntityManager;
    }
}

Nutz 集成Activiti5.17.0 [01]初始化activiti

在初始化activiti时追加代码:

        List<SessionFactory> list=new ArrayList<SessionFactory>();
        CustomGroupEntityManagerFactory customGroupManagerFactory=new CustomGroupEntityManagerFactory();
        customGroupManagerFactory.setGroupEntityManager(new CustomGroupEntityManager());
        CustomUserEntityManagerFactory customUserEntityManagerFactory=new CustomUserEntityManagerFactory();
        customUserEntityManagerFactory.setUserEntityManager(new CustomUserEntityManager());
        list.add(customGroupManagerFactory);
        list.add(customUserEntityManagerFactory);
        processEngineConfiguration.setCustomSessionFactories(list);
20154 月27

Nutz 集成Activiti5.17.0 [02]集成流程设计器及汉化

下载 activiti-modeler 源码,里面的方法用nutz重写,然后修改editor-app里面页面和js里对应的路径。

5.17.0汉化文件下载:http://pan.baidu.com/s/1qWlzHDE

细节不多述了,自己动手吧,哇哈哈……

20154 月27

Nutz 集成Activiti5.17.0 [01]初始化activiti

@SetupBy(value=StartSetup.class)
public class MainModule {
}

private void activitiInit(NutConfig config) {
        log.info("Activiti Init Start...");
        ProcessEngineConfigurationImpl processEngineConfiguration = (ProcessEngineConfigurationImpl) ProcessEngineConfiguration
                .createStandaloneProcessEngineConfiguration();

        processEngineConfiguration.setDataSource(config.getIoc().get(DataSource.class));
        processEngineConfiguration.setDatabaseSchemaUpdate("false");
        processEngineConfiguration.setJobExecutorActivate(false);
        processEngineConfiguration.setActivityFontName("宋体");
        processEngineConfiguration.setLabelFontName("宋体");
        processEngineConfiguration.setXmlEncoding("utf-8");
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        ((Ioc2) config.getIoc()).getIocContext().save("app", "processEngine", new ObjectProxy(processEngine));
        ((Ioc2) config.getIoc()).getIocContext().save("app", "repositoryService", new ObjectProxy(processEngine.getProcessEngineConfiguration().getRepositoryService()));
        ((Ioc2) config.getIoc()).getIocContext().save("app", "runtimeService", new ObjectProxy(processEngine.getProcessEngineConfiguration().getRuntimeService()));
        ((Ioc2) config.getIoc()).getIocContext().save("app", "taskService", new ObjectProxy(processEngine.getProcessEngineConfiguration().getTaskService()));
        ((Ioc2) config.getIoc()).getIocContext().save("app", "formService", new ObjectProxy(processEngine.getProcessEngineConfiguration().getFormService()));
        ((Ioc2) config.getIoc()).getIocContext().save("app", "historyService", new ObjectProxy(processEngine.getProcessEngineConfiguration().getHistoryService()));
        ((Ioc2) config.getIoc()).getIocContext().save("app", "managementService", new ObjectProxy(processEngine.getProcessEngineConfiguration().getManagementService()));
        ((Ioc2) config.getIoc()).getIocContext().save("app", "identityService", new ObjectProxy(processEngine.getProcessEngineConfiguration().getIdentityService()));
        log.info("Activiti Init End.");

    }
20154 月24

Velocity:文本模板渲染

public String getTemplateStr(String template, Map<String, String> para) {
        StringWriter writer = new StringWriter();
        try {
            RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();
            StringReader reader = new StringReader(template);
            SimpleNode node = runtimeServices.parse(reader, "Template name");
            Template t = new Template();
            t.setRuntimeServices(runtimeServices);
            t.setData(node);
            t.initDocument();
            VelocityContext context = new VelocityContext();
            if (para.size() > 0) {
                for (String key : para.keySet()) {
                    context.put(key, para.get(key));
                }
            }
            t.merge(context, writer);
        } catch (Exception e) {
            throw new RuntimeException("Error commiting transaction! cause:"+ e.getMessage());
        }
        return writer.toString();
    }
    
    @At("/form")
    @Ok("vm:template.private.test")
    public void form(HttpServletRequest req, HttpServletResponse resp) {
        Map<String, Object> formParams = new HashMap<String, Object>();
        formParams.put("formKey", "form/waizhibiaodan/01/01.form");
        int timeout = 60 * 1000;
        String str = Http.post("http://127.0.0.1/test/getFormKey", formParams, timeout);
        NutMap map = Json.fromJson(NutMap.class, str);
        String formData = map.getString("data");
        Map<String, String> params = new HashMap<String, String>();
        params.put("startDate", "2015-04-21");
        params.put("endDate", "2015-04-25");
        req.setAttribute("formData", getTemplateStr(formData, params));
    }
20154 月21

Nutz:打包命令

mvn package -Dmaven.test.skip=true

20154 月16

Activiti 5.17.0 解决中文乱码问题

processEngineConfiguration.setActivityFontName(“宋体”);
processEngineConfiguration.setLabelFontName(“宋体”);

 

windows环境变量:

JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8

201410 月24

Android:tcpdump抓包命令

adb shell

su

chmod 777 /data/local/tcpdump

/data/local/tcpdump -p -vv -s 0 -w /sdcard/capture.pcap

20149 月29

MySQL:not in 语句优化

select a.*
from wx_nickname a
left join (select distinct nickname_id from wx_group_nickname )b on
a.id = b.nickname_id
where b.nickname_id is null

20148 月28

Cordova:Toast浮动提示插件

第一步:编写插件类

package cn.xuetang.plugin;

import android.widget.Toast;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;

/**
 * Created by Wizzer on 14-8-28.
 */
public class ToastPlugin extends CordovaPlugin {
    public ToastPlugin() {

    }

    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        if (this.cordova.getActivity().isFinishing()) return true;
        if (action.equals("show")) {
            this.show(args.getString(0));
        } else if (action.equals("showlong")) {
            this.showlong(args.getString(0));
        } else {
            return false;
        }
        callbackContext.success();
        return true;
    }

    public void show(String message) {
        Toast.makeText(this.cordova.getActivity(), Toast.LENGTH_SHORT).show();
    }

    public void showlong(String message) {
        Toast.makeText(this.cordova.getActivity(), message, Toast.LENGTH_LONG).show();
    }
}

 

第二步:配置  res/xml/config.xml

    <feature name="ToastPlugin">
        <param name="android-package" value="cn.xuetang.plugin.ToastPlugin" />
    </feature>

注:这里的 feature name ,要和↓↓面讲的的js文件里一致。

 

第三步:创建js文件 plugins/toast.js

/**
 * Created by Wizzer on 14-8-28.
 */
cordova.define("cn.xuetang.plugin.ToastPlugin", function(require, exports, module) {
    var exec = require('cordova/exec');
    module.exports = {

        /**
         * 一共5个参数
         第一个 :成功回调
         第二个 :失败回调
         第三个 :将要调用的类的配置名字(在config.xml中配置↑↑)
         第四个 :调用的方法名(一个类里可能有多个方法 靠这个参数区分)
         第五个 :传递的参数  以json的格式
         */
        show: function(message) {
            exec(null, null, "ToastPlugin", "show", [message]);
        },
        showlong: function(message) {
            exec(null, null, "ToastPlugin", "showlong", [message]);
        }
    };

});

注:js里两个方法,分别对应类中的两个方法

 

第四步:修改 cordova_plugins.js 引用 tocas.js

在 module.exports = [ ] 中追加如下代码:

    {
        "file": "plugins/toast.js",
        "id": "cn.xuetang.plugin.ToastPlugin",
        "merges": [
            "navigator.toast"
        ]
    }

 

最后:调用

       navigator.toast.show("再点击一次退出");

       navigator.toast.showlong("再点击一次退出");

 

 

 

20148 月28

Cordova:连续按两次返回键退出程序

/**
 * Created by Wizzer on 14-8-28.
 */
var num = 0;
var login = {
    initialize: function () {
        this.bindEvents();
    },
    bindEvents: function () {
        document.addEventListener('backbutton', this.eventBackButton, false);
    },
    eventBackButton: function () {
        num++;
        if (num > 1) {
            navigator.app.exitApp();
        }
        navigator.toast.show("再点击一次退出");
        // 3秒后重新计数
        var intervalID = window.setInterval(function() {
            num=0;
            window.clearInterval(intervalID);
        }, 3000);
    }
};

浮动提示插件见:
/?p=3026

20148 月26

Java:乱码字符不能插入MySQL的解决办法

 

 

.replaceAll(“[^a-zA-Z_\u4e00-\u9fa5]”, “”)

 

只剩下中文和英文字母了,悲催。

 

 

Caused by: java.sql.SQLException: Incorrect string value: ‘\xF0\x9F\x98\xB7’ for column ‘description’ 

20147 月8

JAVA:网易微博模拟登陆

网易微博登陆验证,第一次请求使用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;
    }
}
20146 月9

CSS:限制图片最大宽度

img{max-width:800px;width:expression(this.width > 800 ? 800: true);height:auto;}

20146 月8

Nutz:下载文件(输出文件)

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;

20146 月5

帝国CMS:头部导航栏当前栏目高亮

/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>
20145 月28

Windows :Nginx + PHP 配置虚拟目录

首先配置好运行环境:

windows下配置nginx+php环境

其次修改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;
        }
}

注意虚拟目录配置要在根目录上面。。

20145 月21

PHP:POST发送JSON字符串

/**  
 * 发送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);  
?>
20145 月16

Nutz:单机负载均衡或启动多实例注意事项

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 拷贝到项目类路径下,修改相应的配置,文件夹不冲突即可。

20145 月16

Linux:后台执行Java类

编写执行文件 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 &

20145 月16

Linux:解决多个Tomcat Session冲突的问题

<Context path=”” docBase=”/usr/local/tomcat8080/webapps/ROOT” reloadable=”true” sessionCookiePath=”/” sessionCookieName=”BB_SESSION”/>

更改SESSION名称。