TT随笔五 Nutz自定义视图以及提示信息的统一管理

7 篇文章 0 订阅
6 篇文章 0 订阅

首先先来讲讲上个章节的,修正了2个bug:1、自读字段不用disabled而是用readonly;2、修正了parseAttr默认值覆盖当前值的bug。

上个章节的效果图补在这:



 

 

 

 

 

这个章节,由于我考虑到的是,我在后台进行操作时可能需要给后台反馈许多信息,例如操作的成功与否、是否出现程序异常等,而这些信息都需要通过CtrlResult的实例返回,这样才能够正确的与我前台封装的控件挂上勾来。但是如果我们每次都手动的new一个CtrlResult的实例,然后去设置值,未免显得有些太粗糙了,在加上异常信息的处理,每次都去try catch之后再包裹信息,多烦啊。

因此,nutz默认为我们提供的json视图已经不能满足我的需求了。于是我用了nutz的自定义视图。我写的时候,其实只是把nutz源码中的json的视图拿过来做做修改而已。

我定义了两个视图(只贴主要部分):

    public void render(HttpServletRequest req, HttpServletResponse resp, Object obj)
            throws IOException {
    	if(obj!=null){//如果不为空
    		if(obj instanceof TPager) {//分页数据
    			CtrlResult cr = new CtrlResult();
    			cr.setValue(obj);
    			Mvcs.write(resp, cr, format);
    		}else {//直接返回当前数据。
    			Mvcs.write(resp, obj, format);
    		}
    	}else{//void形式时,返回提示信息“操作成功!”
    		CtrlResult cr = new CtrlResult();
    		cr.setMsg("操作成功!");
            Mvcs.write(resp, cr, format);
    	}
    }

 

    public void render(HttpServletRequest req, HttpServletResponse resp, Object obj)
            throws IOException {
    	if(obj!=null){
    		CtrlResult cr = new CtrlResult();
    		if(obj instanceof RuntimeException){//运行时异常
        		cr.setMsgType(CtrlResult.MSG_TYPE_ERR);
        		cr.setValue(obj);
        		RuntimeException re = (RuntimeException) obj;
        		cr.setMsg(re.getMessage());
    		}else{
        		cr.setMsgType(CtrlResult.MSG_TYPE_ERR);
        		cr.setValue(obj);
        		Exception re = (Exception) obj;
        		cr.setMsg(re.getMessage());
    		}
            Mvcs.write(resp, cr, format);
    	}else{
            Mvcs.write(resp, data, format);
    	}
    }

 

	public View make(Ioc ioc, String type, String value) {
        type = type.toLowerCase();
        if (VIEW_EXCEPTION.equals(type))//异常
        	 if (Strings.isBlank(value)) 
                 return new ExceptionView(JsonFormat.compact());
             else
                 return new ExceptionView(Json.fromJson(JsonFormat.class, value));
        else if (VIEW_SUCCESS.equals(type))//成功
	       	 if (Strings.isBlank(value)) 
	             return new SuccessView(JsonFormat.compact());
	         else
	             return new SuccessView(Json.fromJson(JsonFormat.class, value));
        return null;
	}

 然后在MainModule中修改annotation配置:

@Modules(scanPackage=true)
@Views(TViewMaker.class)
@Ok("success")
@Fail("exception")
@IocBy(type=ComboIocProvider.class, args={
	"*org.nutz.ioc.loader.json.JsonLoader", "cfg/ioc/",
	"*org.nutz.ioc.loader.annotation.AnnotationIocLoader", "com.tt"
})
@SetupBy(value=TSetup.class)
public class MainModule {
	
}

 这样,在成功情况下,我的ctrl可以不设置返回值,那么前台默认提示“操作成功!”

	@At("/create")
	public void create(@Param("..")Curd curd){
		//插入操作
	}

 如果返回值为TPager,我将视为分页数据,因此为自动为其包裹在CtrlResult实例中:

	@At("/query4Page")
	public TPager query4Page(){
		List<Curd> list = new ArrayList<Curd>();
		for(int i = 0; i < 10; i++){
			Curd curd = new Curd(i, "name" + i, "address" + i, i);
			list.add(curd);
		}
		return new TPager(list, list.size());
	}

 除以上情况,我将直接将对象返回给前台。

为了方便返回成功状态下的CtrlResult实例,在TUtils中封装了getOk方法。

 

当系统的提示信息一多时,如果用String写死在每段业务代码中的话,那么后期维护起来肯定会吐血的,所以建议要嘛通过配置文件管理,要嘛通过数据库管理。严禁直接写死在代码中(我目前在写的一些例子可能还是会出现直接写死的情况,1是做测试而已比较懒,你们不能学的哈;2、是为了写博客的时候方便大家直接了解意思,喷我吧~~)。至于是采用文件还是数据库,这个可能就要看具体的项目要求了,因此我定义了一个IMsgLoader接口:

	/**
	 * DESC:通过信息编码获取到对应的提示信息,并为占位符填充相应信息。
	 * @author Small
	 * @Email 536762164@qq.com
	 * @since 2013-5-20
	 *
	 * @param msgCode
	 * @param args
	 * @return
	 */
	public String getMsg(String msgCode, Object... args);

 默认的,我定义了一个通过properties文件配置消息码的,采用了ResourceBundle实现,具体代码我就不贴了。然后在cfg.ioc下面新增一个app.js,用来放置一些注入实例,在其中添加对IMsgLoader的注入:

		msgLoader : {
			type : "com.tt.pub.msg.impl.MsgLoader4Prop"
		}

 如果要切换实现方式,只需要在这个配置中改就可以了。

接着,我将msgLoader缓存在TCache中,设置的代码在TInit中实现。然后在TUtils中实现了getMsg方法,用于公共获取消息。这部分实现之后,我们就可以来设计一个属于自己的异常类了。

异常类我定义为MsgException:

 

public class MsgException extends RuntimeException {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/** 消息码 */
	protected String msgCode = "";
	/** 传参 */
	protected Object[] args;
	/**
	 * @param e				异常类
	 * @param msgCode		消息码
	 * @param args			传参
	 */
	public MsgException(Throwable e, String msgCode, Object... args){
		super(e);
		this.msgCode = msgCode;
		this.args = args;
	}
	/**
	 * @param msgCode		消息码
	 * @param args			传参
	 */
	public MsgException(String msgCode, Object... args){
		this.msgCode = msgCode;
		this.args = args;
	}

	/**
	 * Desc:获取消息。
	 * @author Small
	 * @Email 536762164@qq.com
	 * @since 2013-5-20
	 * 
	 * @return
	 */
	public String getMsg(){
		return TUtils.getMsg(msgCode, args);
	}
	
	public String getMessage(){
		return TUtils.getMsg(msgCode, args);
	}
}
 其实也就是重写了getMessage方法,这时候就与ExceptionView中的内容相结合了。我们用这个异常类来返回我们的业务异常提示信息。

 

通常我们在进行一些业务操作时,会进行一些判断,如果判断不通过则终断并返回给前台信息。在没有这个异常类前,我们可能会这么处理:

 

	public CtrlResult oper(){
		//TODO 业务操作1
		if(用户不存在) return 用户不存在
		//TODO 业务操作2
	    return 成功
	}
 但是这种操作会产生很多问题,代码量多时一回事,有时还得自己做事务回滚操作。

 

于是我们有了通过异常的解决方案:

	public CtrlResult oper(){
		//TODO 业务操作1
		if(用户不存在) throw new MsgException("用户不存在");
		//TODO 业务操作2
	    return 成功
	}

 如此,通过异常我们就可以很容易来操作了。但是这还不满我意。于是我在TUtils中定义了一个pass方法。当第一个参数为ture时表示通过,否则将抛出异常:

	public static void pass(boolean judge, String msgCode, Object... args){
		if(!judge){
			throw new MsgException(msgCode, args);
		}
	}

 获取你们会觉得有些多余,但这是我个人的习惯,觉得这样挺好理逻辑的,个人相对比较喜欢这样的代码:

	public CtrlResult oper(){
		//TODO 业务操作1
		TUtils.pass(用户存在, "用户不存在");
		//TODO 业务操作2
	    return 成功
	}

 当然,你有权不按我这么做,也可以喷我哈~~

 

至此,今天的内容就结束了。值得说的是,nutz的视图实在给力!

 

源码还是传不上去,明天传,睡觉去了,明天还得上班呢~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值