2013年12月 的存档
201312 月25

Nutz:上传文件的配置项扩展,实现对文件类型的限制及分类

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 extOption;

    public Map 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 hm=upload.getContext().getExtOption();
        String str = StringUtil.null2String(suffixname).toLowerCase();
        Set<Map.Entry> set = hm.entrySet();
        for (Iterator<Map.Entry> it = set.iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) 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 hm=upload.getContext().getExtOption();
        String str = StringUtil.null2String(filetype).toLowerCase();
        if(!"".equals(str)){
            Set<Map.Entry> set = hm.entrySet();
            for (Iterator<Map.Entry> it = set.iterator(); it.hasNext();) {
                Map.Entry entry = (Map.Entry) 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));

    }

 

如上所述,在限制文件上传类型的同时,还可以将文件分类保存在不同类型的目录下。

201312 月25

CDMA iPhone 4 iOS7.0.4/7.1 越狱并解决联系人括号问题的办法

1、先使用evasi0n7越狱; 2、进入Cydia按照提示更新Cydia到最新版; 3、Cydia软件源添加 http://apt.weiphone.com; 4、Cydia搜索afc2add选择威锋源安装; 5、使用同步助手或其他工具浏览iPhone文件系统: 浏览至目录 /System/Library/PrivateFrameworks/AppSupport.framework 用压缩包里的 Default.phoneformat 替换之,重启后即可。 为防万一最好备份此文件。

绿色evasi0n7及Default.phoneformat 文件下载:http://pan.baidu.com/s/1nt16UgD

 

PS:CDMA iPhone 4 用了快三年了,有些毛病,坚持到明年iPhone6再换。。

201312 月20

Nutz:通过URL路径查找对应的类及入口函数

由于Nutz是零配置的,所以通过URL找到处理类以及跳转的页面,就显得很麻烦,不方便维护。

于是,我在大神兽的指导下,实现如下功能:在项目启动时,将URL路径、类、方法、以及跳转页面写入项目中的一个文件中,方便查看。

@UrlMappingBy(value=UrlMappingSet.class)
public class MainModule { 
}

在Nutz入口类,加入 @UrlMappingBy。

UrlMappingSet.java 实现在 /WEB-INF/ 目录下生成 paths.txt 文件,记录路径,文件格式如下:
       QQ截图20131220094847
UrlMappingSet.java 源码:
package com.hits.core;

import java.io.File;
import java.lang.reflect.Method;

import org.nutz.lang.Files;
import org.nutz.lang.Lang;
import org.nutz.mvc.ActionChainMaker;
import org.nutz.mvc.ActionInfo;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.NutConfig;
import org.nutz.mvc.impl.UrlMappingImpl;

/**
 * 类描述: 创建人:Wizzer 联系方式:www.wizzer.cn 创建时间:2013-12-19 下午10:36:17
 * 
 * @version
 */
public class UrlMappingSet extends UrlMappingImpl {
    private static int count = 0;

    public void add(ActionChainMaker maker, ActionInfo ai, NutConfig config) {
        super.add(maker, ai, config);
        printActionMappingThis(ai);

    }

    protected void printActionMappingThis(ActionInfo ai) {

        String[] paths = ai.getPaths();
        StringBuilder sb = new StringBuilder();
        if (null != paths && paths.length > 0) {
            sb.append(paths[0]);
            for (int i = 1; i < paths.length; i++)
                sb.append(",").append(paths[i]);
        } else {
            throw Lang.impossible();
        }
        sb.append("\n");
        // 打印方法名
        Method method = ai.getMethod();
        String str;
        if (null != method)
            str = String.format("%-30s : %-10s", Lang.simpleMetodDesc(method),
                    method.getReturnType().getSimpleName());
        else
            throw Lang.impossible();

        sb.append("\t" + ai.getModuleType().getName());
        sb.append("\n\r");
        sb.append("\t" + str);
        sb.append("\n");
        String filepath = Mvcs.getServletContext().getRealPath("/WEB-INF/")
                + "/paths.txt";
        File f = new File(filepath);
        if (count == 0) {
            Files.write(f, sb.toString());
        } else {

            Files.appendWrite(f, sb.toString());
        }
        count++;
    }
}
201312 月15

Nutz:自定义取值区间(可分页查询)

使用示例:

            /**
            你可以自定义取数据区间的值,如下:

            offset=0,count=5     取0到5的记录
            offset=5,count=10    取5到15的记录
            page=3, offset=15,count=20   取15到35的记录
            **/
            int offset=0;
            int count=5;
            ExplicitPager pager=new ExplicitPager(offset,count);
            QueryResult file=daoCtl.listPage(dao, Oa_doc_file.class, cri,pager);

 

ExplicitPager 类源码:

package com.hits.common.page;

import org.nutz.dao.pager.Pager;

/** 
 * 类描述: 
 * 创建人:Wizzer 
 * 联系方式:www.wizzer.cn
 * 创建时间:2013-12-12 下午3:16:21 
 * @version 
 */
public class ExplicitPager extends Pager {

    private static final long serialVersionUID = 1L;
    int offset;
    int count;

    public ExplicitPager(int offset, int count) {
        super();
        this.offset = offset;
        this.count = count;
    }

    public void setOffset( int offset) {
        this.offset = offset;
    }

    public void setSelectCount( int count) {
        this.count = count;
    }

    @Override
    public int getPageSize() {
        return count;
    }

    @Override
    public int getOffset() {
        return offset;
    }

}

分页源代码(可参考上一篇文章,实现自定义SQL多表分页区间取值):

    /**
     * 根据查询条件分页,返回封装好的QueryResult对象
     * 
     * @param dao
     * @param obj
     * @param cnd
     * @param pager
     * @return
     */
    public  QueryResult listPage(Dao dao, Class obj, Condition cnd,Pager pager) { 
        List list = dao.query(obj, cnd, pager);
        pager.setRecordCount(dao.count(obj, cnd));// 记录数需手动设置
        return new QueryResult(list, pager);
    }
    /**
     * 根据自定义SQL分页,返回封装好的QueryResult对象
     * @param dao
     * @param sql
     * @param pager
     * @return
     */
        public 
 QueryResult listPageSql(Dao dao, Sql sql, Pager pager) {
        if(pager==null)
            return null;
        pager.setRecordCount(Daos.queryCount(dao, sql.getSourceSql()));// 记录数需手动设置
        sql.setPager(pager);
        sql.setCallback(Sqls.callback.records());
        dao.execute(sql);  
        return new QueryResult(sql.getList(Map.class), pager);
    }
201312 月15

Nutz:自定义SQL多表多字段分页查询方法

easyui.datagrid 调用示例:

    @At
    @Ok("raw")
    public String test(@Param("page") int curPage, @Param("rows") int pageSize){
        Sql sql=Sqls.create("select a.name,b.loginname From sys_unit a,sys_user b where a.id=b.unitid");
        return daoCtl.listPageJsonSql(dao, sql, curPage, pageSize);
    }

源代码:

    /**
     * 根据自定义SQL分页,返回封装好的QueryResult对象
     * @param dao
     * @param sql
     * @param curPage
     * @param pageSize
     * @return
     */
    public  QueryResult listPageSql(Dao dao, Sql sql, int curPage,int pageSize) {
        Pager pager = dao.createPager(curPage, pageSize);

        pager.setRecordCount(Daos.queryCount(dao, sql.getSourceSql()));// 记录数需手动设置
        sql.setPager(pager);
        sql.setCallback(Sqls.callback.records());
        dao.execute(sql); 
        return new QueryResult(sql.getList(Map.class), pager);
    }
    /**
     * 根据自定义SQL分页,返回封装好的 Easyui.datagrid JSON
     * @param dao
     * @param sql
     * @param curPage
     * @param pageSize
     * @return
     */
    public String listPageJsonSql(Dao dao, Sql sql, int curPage, int pageSize) {
            Pager pager = dao.createPager(curPage, pageSize);
            pager.setRecordCount(Daos.queryCount(dao, sql.toString()));// 记录数需手动设置
            sql.setPager(pager);
            sql.setCallback(Sqls.callback.records());
            dao.execute(sql);
            Map jsonobj = new HashMap();
            jsonobj.put("total", pager.getRecordCount());
            jsonobj.put("rows", sql.getList(Map.class));
            return Json.toJson(jsonobj);
       }