NutzCN Logo
问答 @At 读取配置文件问题
发布于 1892天前 作者 Hamming 1561 次浏览 复制 上一个帖子 下一个帖子
标签:

@At 读取配置文件问题
列如 我要注解请求 前缀从配置文件读取 这样 有没有方法能实现呢

@At(value ="${api.version1}/api/applyInspection")
9 回复

目测要改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();

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

    protected MappingNode<ActionInvoker> root;
    
    protected String prefix;

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

    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();
        if (prefix != null)
            path = path.substring(prefix.length());
        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 [%s] path=%s : NOT Action match", ac.getRequest().getMethod(), path);
        return null;
    }
    
    public void add(String path, ActionInvoker invoker) {
    	root.add(path, invoker);
    	map.put(path, invoker);
    }
    
    protected void printActionMapping(ActionInfo ai) {
        print(ai);
    }

    protected void print(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 = genMethodDesc(ai);
            else
                throw Lang.impossible();
            log.debugf("%s >> %50s | @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());
        }
    }
    
    protected String genMethodDesc(ActionInfo ai) {
        Method method = ai.getMethod();
        String prefix = "";
        if (ai.getLineNumber() != null && ai.getLineNumber() > 0) {
            prefix = String.format("(%s.java:%d).%s",
                                 method.getDeclaringClass().getSimpleName(),
                                 ai.getLineNumber(),
                                 method.getName());
        } else {
            prefix = String.format("%s.%s(...)",
                                   method.getDeclaringClass().getSimpleName(),
                                   method.getName());
        }
        return String.format("%-37s : %-10s", 
                             prefix,
                             method.getReturnType().getSimpleName());
    }
}

要么改add,在启动时转化

要么改get,运行时匹配,更复杂的样子

nutz 如何获取配置文件呢

获取配置文件? conf对象呀

@UrlMappingBy(args="ioc:myUrlMappingImpl")

@IocBean
public class MyUrlMappingImpl extends UrlMappingImpl {
         @Inject PropertiesProxy conf;
}

启动失败

[ERROR] 15:45:54.829 org.nutz.mvc.impl.NutLoading.load(NutLoading.java:125) - Error happend during start serivce!
org.nutz.ioc.IocException: IocBean[myUrlMappingImpl] For object [myUrlMappingImpl] - type:[class org.nutz.mvc.impl.UrlMappingImpl]
	at org.nutz.ioc.impl.NutIoc.get(NutIoc.java:250)
	at org.nutz.ioc.impl.NutIoc.get(NutIoc.java:271)
	at org.nutz.mvc.impl.Loadings.evalObj(Loadings.java:334)
	at org.nutz.mvc.impl.NutLoading.createUrlMapping(NutLoading.java:258)
	at org.nutz.mvc.impl.NutLoading.evalUrlMapping(NutLoading.java:157)
	at org.nutz.mvc.impl.NutLoading.load(NutLoading.java:108)
	at org.nutz.boot.starter.nutz.mvc.NbMvcLoading.load(NbMvcLoading.java:28)
	at org.nutz.mvc.ActionHandler.<init>(ActionHandler.java:19)
	at org.nutz.mvc.NutFilter._init(NutFilter.java:91)
	at org.nutz.mvc.NutFilter.init(NutFilter.java:69)
	at org.eclipse.jetty.servlet.FilterHolder.initialize(FilterHolder.java:136)
	at org.eclipse.jetty.servlet.ServletHandler.lambda$initialize$0(ServletHandler.java:750)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
	at java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:742)
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
	at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:744)
	at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:369)
	at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1497)
	at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1459)
	at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:854)
	at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:278)
	at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
	at org.eclipse.jetty.server.Server.start(Server.java:418)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
	at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
	at org.eclipse.jetty.server.Server.doStart(Server.java:382)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.nutz.boot.starter.jetty.JettyStarter.start(JettyStarter.java:140)
	at org.nutz.boot.AppContext.startServers(AppContext.java:310)
	at org.nutz.boot.NbApp.execute(NbApp.java:210)
	at org.nutz.boot.NbApp.run(NbApp.java:182)
	at io.nutz.nutzsite.MainLauncher.main(MainLauncher.java:135)
Caused by: org.nutz.ioc.ObjectLoadException: Object 'myUrlMappingImpl' without define!
	at org.nutz.ioc.loader.combo.ComboIocLoader.load(ComboIocLoader.java:157)
	at org.nutz.ioc.impl.NutIoc.get(NutIoc.java:195)
	... 34 more
[ERROR] 15:45:54.831 org.nutz.mvc.impl.NutLoading.load(NutLoading.java:127) - try to depose ioc
package org.nutz.mvc.impl;

import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
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.ActionInfo;
import org.nutz.mvc.NutConfig;
import org.nutz.mvc.annotation.BlankAtException;

/**
 *
 * @Author: Haimming
 * @Date: 2019-10-18 15:40
 * @Version 1.0
 */
@IocBean
public class MyUrlMappingImpl  extends UrlMappingImpl {
    private static final Log log = Logs.get();
    @Inject
    private PropertiesProxy conf;

    @Override
    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()) {
            if(path.contains("${")){
                String key = path.substring(path.indexOf("${"),path.indexOf("}"));
                String value =conf.get(key);
                if(Strings.isNotBlank(value)){
                    path = value + path.substring(path.indexOf("}"));
                }
            }
            // 尝试获取,看看有没有创建过这个 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]);
        }
    }
}

package写你自己的呀

感谢兽总解答
代码如下 给以后需要的朋友

package io.nutz.nutzsite.common.mvc;

import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
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.ActionInfo;
import org.nutz.mvc.NutConfig;
import org.nutz.mvc.annotation.BlankAtException;
import org.nutz.mvc.impl.ActionInvoker;
import org.nutz.mvc.impl.UrlMappingImpl;

/**
 * 从配置文件获取配置
 * 使用方法  @At(value ="${api.version1}/api/applyInspection")
 * 
 * @Author: Haimming
 * @Date: 2019-10-18 15:40
 * @Version 1.0
 */
@IocBean(name="myUrlMappingImpl")
public class MyUrlMappingImpl  extends UrlMappingImpl {
    private static final Log log = Logs.get();
    @Inject
    private PropertiesProxy conf;

    @Override
    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.contains("${")){
                String key = path.substring(path.indexOf("${")+2,path.indexOf("}"));
                String value =conf.get(key);
                if(Strings.isNotBlank(value)){
                    path = value + path.substring(path.indexOf("}") + 1);
                }
            }
            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]);
        }
    }
}

添加回复
请先登陆
回到顶部