在nutz的使用過程當中咱們會發現nutz實際上是過濾後綴後纔會再去經過@At註解尋找合適的入口。可是不少時候咱們是須要區分這個後綴的。那麼該怎麼實現呢?java
其實nutz提供了一個@UrlMappingBy註解。在nutz的文檔裏貌似沒有明確的體現。個人用法未必就是正確的。可是能解決這個問題。mvc
第一個步: 自定義一個urlMapping的實現類app
public class TestUrlMapping implements UrlMapping { }
第二步:把默認的urlMappingImpl實現複製過來ui
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方法爲:this
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添加註解url
@UrlMappingBy(value=TestUrlMapping.class)
打完收工!spa