您的位置:首页 > 其它

Nutz MVC 识别后缀

2016-01-16 00:00 387 查看
摘要: Nutz MVC 不过滤后缀

在nutz的使用过程中我们会发现nutz其实是过滤后缀后才会再去通过@At注解寻找合适的入口。但是很多时候我们是需要区分这个后缀的。那么该怎么实现呢?
其实nutz提供了一个@UrlMappingBy注解。在nutz的文档里貌似没有明确的体现。我的用法未必就是正确的。但是能解决这个问题。
第一个步: 自定义一个urlMapping的实现类
public class TestUrlMapping implements UrlMapping {

}


第二步:把默认的urlMappingImpl实现复制过来
package org.nutz.mvc.impl;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.ActionChain;
import org.nutz.mvc.ActionChainMaker;
import org.nutz.mvc.ActionContext;
import org.nutz.mvc.ActionInfo;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.NutConfig;
import org.nutz.mvc.RequestPath;
import org.nutz.mvc.UrlMapping;
import org.nutz.mvc.annotation.BlankAtException;

public class UrlMappingImpl implements UrlMapping {

private static final Log log = Logs.get();

private Map<String, ActionInvoker> map;// 这个对象有点多余,考虑换成AtMap吧!!

private MappingNode<ActionInvoker> root;

public UrlMappingImpl() {
this.map = new HashMap<String, ActionInvoker>();
this.root = new MappingNode<ActionInvoker>();
}

public void add(ActionChainMaker maker, ActionInfo ai, NutConfig config) {

// 检查所有的path
String[] paths = ai.getPaths();
for (int i = 0; i < paths.length; i++) {
String path = paths[i];
if (Strings.isBlank(path))
throw new BlankAtException(ai.getModuleType(), ai.getMethod());

if (path.charAt(0) != '/')
paths[i] = '/' + path;
}

ActionChain chain = maker.eval(config, ai);
for (String path : ai.getPaths()) {

// 尝试获取,看看有没有创建过这个 URL 调用者
ActionInvoker invoker = map.get(path);

// 如果没有增加过这个 URL 的调用者,为其创建备忘记录,并加入索引
if (null == invoker) {
invoker = new ActionInvoker();
map.put(path, invoker);
root.add(path, invoker);
// 记录一下方法与 url 的映射
config.getAtMap().addMethod(path, ai.getMethod());
} else if (!ai.isForSpecialHttpMethod()) {
log.warnf("Duplicate @At mapping ? path=" + path);
}

// 将动作链,根据特殊的 HTTP 方法,保存到调用者内部
if (ai.isForSpecialHttpMethod()) {
for (String httpMethod : ai.getHttpMethods())
invoker.addChain(httpMethod, chain);
}
// 否则,将其设置为默认动作链
else {
invoker.setDefaultChain(chain);
}
}

printActionMapping(ai);

// TODO 下面个IF要不要转换到NutLoading中去呢?
// 记录一个 @At.key
if (!Strings.isBlank(ai.getPathKey()))
config.getAtMap().add(ai.getPathKey(), ai.getPaths()[0]);
}

public ActionInvoker get(ActionContext ac) {
RequestPath rp = Mvcs.getRequestPathObject(ac.getRequest());
String path = rp.getPath();
ac.setSuffix(rp.getSuffix());
ActionInvoker invoker = root.get(ac, path);
if (invoker != null) {
ActionChain chain = invoker.getActionChain(ac);
if (chain != null) {
if (log.isDebugEnabled()) {
log.debugf("Found mapping for [%s] path=%s : %s",
ac.getRequest().getMethod(),
path,
chain);
}
return invoker;
}
}
if (log.isDebugEnabled())
log.debugf("Search mapping for path=%s : NOT Action match", path);
return null;
}

protected void printActionMapping(ActionInfo ai) {

/*
* 打印基本调试信息
*/
if (log.isDebugEnabled()) {
// 打印路径
String[] paths = ai.getPaths();
StringBuilder sb = new StringBuilder();
if (null != paths && paths.length > 0) {
sb.append("   '").append(paths[0]).append("'");
for (int i = 1; i < paths.length; i++)
sb.append(", '").append(paths[i]).append("'");
} else {
throw Lang.impossible();
}
// 打印方法名
Method method = ai.getMethod();
String str;
if (null != method)
str = String.format("%-30s : %-10s",
Lang.simpleMetodDesc(method),
method.getReturnType().getSimpleName());
else
throw Lang.impossible();
log.debugf("%s >> %s | @Ok(%-5s) @Fail(%-5s) | by %d Filters | (I:%s/O:%s)",
Strings.alignLeft(sb, 30, ' '),
str,
ai.getOkView(),
ai.getFailView(),
(null == ai.getFilterInfos() ? 0
: ai.getFilterInfos().length),
ai.getInputEncoding(),
ai.getOutputEncoding());
}
}
}


第三步:改动ActionInvoker get方法为:
public ActionInvoker get(ActionContext ac) {
RequestPath rp = Mvcs.getRequestPathObject(ac.getRequest());
String url = ac.getRequest().getPathInfo();
if (null == url)
url = ac.getRequest().getServletPath();
String path = url;
ac.setSuffix(rp.getSuffix());
ActionInvoker invoker = root.get(ac, path);
if (invoker != null) {
ActionChain chain = invoker.getActionChain(ac);
if (chain != null) {
if (log.isDebugEnabled()) {
log.debugf("Found mapping for [%s] path=%s : %s",
ac.getRequest().getMethod(),
path,
chain);
}
return invoker;
}
}
if (log.isDebugEnabled())
log.debugf("Search mapping for path=%s : NOT Action match", path);
return null;
}

第四步:在MainModule添加注解
@UrlMappingBy(value=TestUrlMapping.class)

打完收工!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: