文章标签 ‘nutz’
2014一月2

Nutz:使用第三方JS控件实现多文件上传的方法

适用于 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>
2013十二月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<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));

	}

 

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

2013十二月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++;
	}
}
2013十二月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 <T> QueryResult listPage(Dao dao, Class<T> obj, Condition cnd,Pager pager) { 
		List<T> 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);
	}
2013十二月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<String, Object> jsonobj = new HashMap<String, Object>();
            jsonobj.put("total", pager.getRecordCount());
            jsonobj.put("rows", sql.getList(Map.class));
            return Json.toJson(jsonobj);
       }
2013十一月26

Nutz开发日志

计划基于Nutz开发一套全新的系统管理-权限框架。界面演示:/?p=2586
之前尝试Nutz做过一个demo,但有很多不足,比如没有做防SQL注入、不能兼容多数据库、列表没有实现Ajax等。

基于多年来开发过程接触的各式各样的框架,想整一套开发方便UI简洁的框架,要求有如下功能:
1.开发简便、框架结构清晰
2.性能优越、兼容主流数据库、兼容各版本浏览器
3.UI简洁、开发简单、主流JS插件集成、全Ajax
4.集成权限框架、单点登陆、登陆日志、操作日志
5.工作流引擎、表单自定义
6.代码生成器

JS引入:
jquery-1.10.2.min.js
ueditor-1.2.6.1
My97Datepicker-4.8 Beta4
zDialog-2.0
ztree-3.5.15

框架引入:
Nutz-1.49.r2
log4j-1.2.17
json-1.0
c3p0-0.9.1.2
classes12
mysql-connector-java-5.1.14
ojdbc14
slf4j-api-1.6.1
slf4j-log4j12-1.6.1
sqljdbc4
velocity-1.7
velocity-tools-2.0
velocity-tools-generic-2.0
velocity-tools-view-2.0
json-lib-2.4-jdk15
ezmorph-1.0.6
commons-beanutils-1.7.0
commons-chain-1.1
commons-collections-3.2
commons-digester-1.8
commons-lang-2.2
commons-logging-1.1
commons-validator-1.3.1
待更新。

——————————————————–
在Eclipse中处理图片,需要引入两个包:
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
报错:
Access restriction: The type JPEGImageEncoder is not accessible due to restriction on required library C:\Java\jre1.6.0_07\lib\rt.jar

此时解决办法:
Eclipse默认把这些受访问限制的API设成了ERROR。只要把Windows-Preferences-Java-Complicer-Errors/Warnings里面的Deprecated and restricted API中的Forbidden references(access rules)选为Warning就可以编译通过。

—————————————————————
Nutz开发说明:

您一定了解SSH,还有Strust1+Velocity框架

2013年11月30日(星期六) 晚上7:03给我写信

您一定了解SSH,还有Strust1+Velocity框架。前者配置文件实在是太多,多层架构,开发一个功能模块涉及很多类、很多关系,一方面上手非常难另外开发效率也不高。后者随着技术发展,对前端技术支持不太友好,比如AjaxJS框架等,需要中间跳转页面进行输出,再者也需要配置。

根据项目开发中实际遇到的各种问题,研究各种框架优缺点之后,决定选择Nutz国产开源框架作为基础来构建本开发框架。选择Nutz有如下优点:

1URL“零”配置

您再也不用为繁琐的配置文件烦恼了,Nutz-Mvc使用全注解的方式来封装URL,使用简单的@At 在类或方法上实现URL映射。

2、灵活的多数据源支持

通过Nutz.Ioc您只要在数据库配置文件datasource.json中配置对象,如dao1dao2,那么在Action类中,

@Inject

    protected Dao dao1;

@Inject

protected Dao dao2;

即可使用daoCtl的方法直接操作这两个数据库。daoCtl里集成了常用的添加、修改、查询、分页等方法。

3、功能强大的视图

Nutz-Mvc使用@Ok @Fail 注解,来实现执行成功或失败后的输出,可以外部重定向、内部重定向、返回字符串、返回JSON等等,总之您想要什么结果就能给您返回什么,再也不用使用单独的Action类来封装JSON数据了,您想要随时都可以有。

4、功能强大的数据库操作

Nutz.Dao封装了常用的数据库操作,减少自定义SQL的编写,提高开发效率和安全性,通过工具类

Cnd.where(“loginname”, “=”,
user.getLoginname())

        Sql sql = Sqls.create("DELETE FROM $table WHERE name=@name");

sql.vars().set(“table”,”t_abc”);

sql.params().set(“name”,”Peter”);

中的sql.params().set() 方法,可以有效的防止SQL注入。

更多使用方法请参考本目录下的nutz开发手册。

5Velocity

对于大家常用的Velocity模板语言,本框架也进行了整合。

req.setAttribute(“menulist”,
menulist);

将对象输出到页面,在页面上即可直接使用模板语言输出。

 

UI表现层上面,本次框架也进行了调整,原则上支持纯Ajax开发。后台集成jQuery EasyUIzDialogEasyUI.DataGridztreeMy97DatePickerJS组件。

1、兼容主流浏览器

您再也不用考虑浏览器兼容性问题,只要您的JS全部使用jQuery来编写,那么还用担心什么呢,本框架目前在IE6/IE7/IE8/IE9/IE10/IE11ChromeFrieFox360测试通过。

2zDialog的使用更加简便

通过使用Ajax以及对zDialog的优化,您再也不需要写中间页面进行页面跳转了。您可以在弹出框的父页面进行弹出表单的提交,在父页面写弹出框按钮的事件。

通过$DW.$(“#form1”).serialize();  获取弹出窗口表单内容

         $DW.$Z(“name”).focus();     操作弹出框内容,赋值等

         $D.close();                                  关闭弹出窗口

让我们看一个完成的示例:

function addSave(){ 



if($DW.Verify.hasError()){


return;


}


jQuery.ajax({


type:
‘POST’,


url :
“/private/sys/unit/addSave” ,


data :
$DW.$(“#form1”).serialize(),


success :
function (res) {


if(res!=””){


$D.close();


Dialog.alert(“
添加成功!“);


initTree();


view(res);


}else{


Dialog.alert(“
添加失败!“);


}



return
false;


},


fail :
function(res) {


Dialog.alert(“
系统错误?!”);


}


});


}

3Ajax分页支持

集成jQuery.Easyui.DataGrid,从后台封装的JSON数据格式,到前台展示,分页查询从来没有如此简便过。

daoCtl.getListPageJson()
封装了easyui.datagrid分页所需格式数据,更不用您手动写烦人的JSON了。

4、权限控制到按钮

您只需要在JS中使用

              Page.initBtn();


$!initBtn

即可控制页面按钮是否可用,当然,在此之前,您需要在资源菜单管理中添加按钮ID,在角色管理中对用户分配按钮权限。

 

 

2013三月25

Nutz:Java开发框架搭建基本完成

一直想拥有一个开发快捷、界面美观、用户体验好的java开发框架,网罗不来只好自己动手,现在框架基础功能已完成,界面还需要美工优化一下。(以下图片点击查看全图)

1

 

购买咨询Q:11624317
验证信息:框架

技术:Nutz + Velocity + c3p0 + zDialog +  jQuery + zTree

环境:JDK + Eclipse +Tomcat + Oracle/MySQL

1、系统采用国产开源Nutz框架,实现项目的“零配置”(这可比SSH轻松多了),Nutz在一个类中可以随意定义访问地址,返回String、JSON、对象或跳转到具体页面,也可以利用Velocity打印结果;
2、系统集成泽元CMS1.0系统中的弹出窗口及页面验证、控制JS,并结合jquery easyui实现标签页;
3、系统无缝集成jQuery,jquery和nutz真是天作之合,可方便的实现ajax功能,另外你也可以使用velocity在页面输出内容,比较灵活;
4、已完成系统管理模块,数据表设计合理,权限控制到按钮级,可按机构建用户角色等。

下面是一段简单的Nutz类实现,Nutz更多介绍可以访问官网:http://nutzam.com/

@IocBean
@At("/private")//访问路径
@Filters({ @By(type = GlobalsFilter.class) })
public class LoginAction extends BaseAction {

	@At //访问路径,不指定则为方法名称,即:/private/logout
	@Ok(">>:/private/login")//外连接,跳转到 /private/login
	public void logout(HttpSession session) {
		session.removeAttribute("userSession");
	}

	@At("/login")
	@Ok("->:/private/login.html")//内连接,输出到 /private/login.html
	public void login(HttpServletRequest req) {
		req.setAttribute("menulist", "helloworld");//页面可以用velocity语言输出
	}
	@At
	@Ok("raw") //返回字符串类型,也可以是json、对象等
	public int Online(@Param("loginname") String loginname,HttpSession session) { 
		Sys_user user = (Sys_user) session.getAttribute("userSession");
		if(user==null){ 
			return -2;
		}
		if (loginname != null&&!"".equals(loginname)) {
			OnlineUtil.addUser(loginname, String.valueOf(1));
		} 
		return OnlineUtil.getOnlineCount(String.valueOf(1));
	} 

}

2

 

3

 

4

5