• GeoServer之kvpParser解析器&KvpRequestReader


    参考1:https://blog.csdn.net/eternity_xyf/article/details/78531834

    /**
    * Parses a key-value pair into a key-object pair.
    *
    * <p>This class is intended to be subclassed. Subclasses need declare the key in which they parse,
    * and the type of object they parse into.
    *
    * <p>Instances need to be declared in a spring context like the following:
    *
    * <pre>
    * <code>
    * &lt;bean id="myKvpParser" class="org.xzy.MyKvpParser"/&gt;
    * </code>
    * </pre>
    *
    * Where <code>com.xzy.MyKvpParser</code> could be something like:
    *
    * <pre>
    * <code>
    * public class MyKvpParser extends KvpParser {
    *
    * public MyKvpParser() {
    * super( "MyKvp", MyObject.class )l
    * }
    *
    * public Object parse( String value ) {
    * return new MyObject( value );
    * }
    * }
    * </code>
    * </pre>
    *
    * <p><b>Operation Binding</b>
    *
    * <p>In the normal case, a kvp parser is engaged when a request specifies a name which matches the
    * name declared by the kvp parser. It is also possible to attach a kvp parser so that it only
    * engages on a particular operation. This is done by declaring the one or more of the following:
    *
    * <ul>
    * <li>service
    * <li>version
    * <li>request
    * </ul>
    *
    * <p>When a kvp parser declares one or more of these properties, it will only be engaged if an
    * incoming request specicfies matching values of the properties.
    *
    * <p>The following bean declaration would create the above kvp parser so that it only engages when
    * the service is "MyService", and the request is "MyRequest".
    *
    * <pre>
    * <code>
    * &lt;bean id="myKvpParser" class="org.xzy.MyKvpParser"&gt;
    * &lt;property name="service"&gt;MyService&lt;/property&gt;
    * &lt;property name="request"&gt;MyRequest&lt;/property&gt;
    * &lt;bean&gt;
    * </code>
    * </pre>
    *
    * @author Justin Deoliveira, The Open Planning Project, jdeolive@openplans.org
    */

    可以看出,这其实是一个虚函数。。

    一个实现它的类FormatOptionsKvpParser extends KvpParser,主要是实现parse()方法。

    @Override
    public Object parse(String value) throws Exception {
    Map<String, Object> formatOptions = new CaseInsensitiveMap<>(new TreeMap<>());
    List<String> kvps = KvpUtils.escapedTokens(value, ';');
    List parsers = GeoServerExtensions.extensions(KvpParser.class, applicationContext);
    for (String kvp : kvps) {
    List<String> kv = KvpUtils.escapedTokens(kvp, ':', 2);
    String key = kv.get(0);
    String raw = kv.size() == 1 ? "true" : KvpUtils.unescape(kv.get(1));

    Object parsed = null;

    for (Object o : parsers) {
    KvpParser parser = (KvpParser) o;
    if (key.equalsIgnoreCase(parser.getKey())) {
    parsed = parser.parse(raw);
    if (parsed != null) {

    break;
    }
    }
    }

    if (parsed == null) {
    if (LOGGER.isLoggable(Level.FINER))
    LOGGER.finer(
    "Could not find kvp parser for: '" + key + "'. Storing as raw string.");
    parsed = raw;
    }

    formatOptions.put(key, parsed);
    }

    return formatOptions;
    }

    可以看出,这里调用GeoServerExtensions.extensions(KvpParser.class, applicationContext)注册KvpParser类到扩展中。这样做的好处是,下次就可以直接调用,不需要重新初始化了吗?(工厂模式的Registry)。那为什么不直接getbean。。

    >>KvpRequestReader

    findKvpRequestReader(Class<?> type):寻找KvpRequestReader,可以接收任意类型的类为参数,这里以Message.class为例。

    首先调用loadKvpRequestReaders,加载所有的KvpRequestReaders。。

    public static Collection<KvpRequestReader> loadKvpRequestReaders() {
    Collection<KvpRequestReader> kvpReaders =
    GeoServerExtensions.extensions(KvpRequestReader.class);

    if (!(new HashSet<>(kvpReaders).size() == kvpReaders.size())) {
    String msg = "Two identical kvp readers found";
    throw new IllegalStateException(msg);
    }

    return kvpReaders;
    }

    当然在查找之前,肯定要先加载bean。。也就是applicationContext.xml,

    URL url = getClass().getResource("applicationContext.xml");
    FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(url.toString())
    Dispatcher dispatcher = (Dispatcher) context.getBean("dispatcher");

    所以是怎么在extensions中通过KvpRequestReader找到MessageKvpRequestReader的?

    public class MessageKvpRequestReader extends KvpRequestReader {
    public MessageKvpRequestReader() {
    super(Message.class);
    }

    @Override
    public Object createRequest() {
    return new Message();
    }
    }

    可以看出MessageKvpRequestReader是KvpRequestReader的子类。。

    context.getBeanNamesForType(extensionPoint);
  • 相关阅读:
    Android px,dp,pt,sp的差别
    C 八皇后
    线性表
    android 推断手机是否支持前置摄像头
    C/C++易错难点笔记01
    Java日志记录的5条规则
    hdoj-1312-Red and Black
    oracle 11g sql developer安装后无法使用
    显示指定时间的秒数
    云端自动化测试方案
  • 原文地址:https://www.cnblogs.com/2008nmj/p/15817651.html
Copyright © 2020-2023  润新知