【问题标题】:Change Jetty configuration from code to XML将 Jetty 配置从代码更改为 XML
【发布时间】:2018-03-20 13:24:46
【问题描述】:

我已将 Jetty 嵌入到我的应用程序中。我的要求很简单:使用 HTTP/2,禁用一些加密协议和密码,并使用我自己的处理程序处理一些请求。我是从我的代码中做到的。它工作得很好。但是现在我的客户想要使用 Jetty 中提供的更多 HTTP 功能,例如基本身份验证或重定向。我不想在我的应用程序中添加越来越多的 HTTP 配置,所以我回到了 Jetty XML 配置文件的想法。

出于调试/监控目的,我使用Server.dump(),我可以看到启用/禁用的密码或我的处理程序。是否可以基于工作 Jetty 或基于 Jetty Server.dump() 创建 XML 配置文件?

【问题讨论】:

    标签: java xml configuration jetty


    【解决方案1】:

    您无需(太多)更改当前代码即可开始使用 XML 来修改您的服务器。

    XmlEnhancedServer 为例:

    可通过https://github.com/jetty-project/embedded-jetty-cookbook获得

    package org.eclipse.jetty.cookbook;
    
    import java.io.File;
    import java.net.URI;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.eclipse.jetty.server.HttpConfiguration;
    import org.eclipse.jetty.server.HttpConnectionFactory;
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.ServerConnector;
    import org.eclipse.jetty.server.handler.ContextHandlerCollection;
    import org.eclipse.jetty.server.handler.DefaultHandler;
    import org.eclipse.jetty.server.handler.HandlerList;
    import org.eclipse.jetty.servlet.DefaultServlet;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    import org.eclipse.jetty.util.resource.Resource;
    import org.eclipse.jetty.xml.XmlConfiguration;
    
    /**
     * This is a Server setup in a default way, but is can be enhanced by providing
     * (0 to n) Jetty XML file arguments on the command line.
     * <p>
     *     Run without a command line argument and pay attention to the contextPath for the
     *     default Context. (It should be {@code "/"})
     *     <br/>
     *     Now run with {@code src/test/resources/xml-enhanced/adjust-default-contextpath.xml} and see
     *     that the context path is now {@code "/foobar"}
     * </p>
     * <p>
     *     Run with {@code src/test/resources/xml-enhanced/configure-http.xml} and you will be
     *     adjusting the {@link HttpConfiguration} parameters in use.
     * </p>
     * <p>
     *     Run with {@code src/test/resources/xml-enhanced/add-rewrites.xml} and you will be
     *     adjusting adding rewrite rules to the existing handler tree.
     *     <br/>
     *     Request {@code http://localhost:8080/bar/blah} and you will receive a 302 redirect
     *     to {@code http://localhost:8080/foo}
     * </p>
     * <p>
     *     Run with {@code src/test/resources/xml-enhanced/add-https.xml} and you will be
     *     adding an HTTPS connector with configuration.
     * </p>
     */
    public class XmlEnhancedServer
    {
        public static void main(String[] args) throws Exception
        {
            Server server = new Server();
            HttpConfiguration httpConfig = new HttpConfiguration();
            ServerConnector httpConnector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
            httpConnector.setPort(8080);
            server.addConnector(httpConnector);
    
            // Figure out what path to serve content from
            ClassLoader cl = DefaultServletFileServer.class.getClassLoader();
            // We look for a file, as ClassLoader.getResource() is not
            // designed to look for directories (we resolve the directory later)
            URL f = cl.getResource("static-root/hello.html");
            if (f == null)
            {
                throw new RuntimeException("Unable to find resource directory");
            }
    
            // Resolve file to directory
            URI webRootUri = f.toURI().resolve("./").normalize();
            System.err.println("WebRoot is " + webRootUri);
    
            HandlerList handlers = new HandlerList();
            ContextHandlerCollection contexts = new ContextHandlerCollection();
    
            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
            context.setContextPath("/");
            context.setBaseResource(Resource.newResource(webRootUri));
            contexts.addHandler(context);
    
            ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
            holderPwd.setInitParameter("dirAllowed", "true");
            context.addServlet(holderPwd, "/");
    
            handlers.addHandler(contexts);
            DefaultHandler defaultHandler = new DefaultHandler();
            handlers.addHandler(defaultHandler); // always last in handler list
    
            server.setHandler(handlers);
    
            // apply extra XML (provided on command line)
            if (args.length > 0)
            {
                // Map some well known objects via an id that can be referenced in the XMLs
                Map<String, Object> idMap = new HashMap<>();
                idMap.put("Server", server);
                idMap.put("httpConfig", httpConfig);
                idMap.put("httpConnector", httpConnector);
                idMap.put("Handlers", handlers);
                idMap.put("Contexts", contexts);
                idMap.put("Context", context);
                idMap.put("DefaultHandler", defaultHandler);
    
                // Map some well known properties
                Map<String,String> globalProps = new HashMap<>();
                URI resourcesUriBase = webRootUri.resolve("..");
                System.err.println("ResourcesUriBase is " + resourcesUriBase);
                globalProps.put("resources.location", resourcesUriBase.toASCIIString());
    
                List<Object> configuredObjects = new ArrayList<>();
                XmlConfiguration lastConfig = null;
                for (String xml : args)
                {
                    URL url = new File(xml).toURI().toURL();
                    System.err.println("Applying XML: " + url);
                    XmlConfiguration configuration = new XmlConfiguration(url);
                    if (lastConfig != null)
                        configuration.getIdMap().putAll(lastConfig.getIdMap());
                    configuration.getProperties().putAll(globalProps);
                    configuration.getIdMap().putAll(idMap);
                    idMap.putAll(configuration.getIdMap());
                    configuredObjects.add(configuration.configure());
                    lastConfig = configuration;
                }
    
                // Dump what was configured
                for(Object configuredObject: configuredObjects)
                {
                    System.err.printf("Configured (%s)%n", configuredObject.getClass().getName());
                }
    
                // Dump the resulting idMap
                idMap.forEach((id, obj) -> System.err.printf("IdMap[%s]: (%s)%n", id, obj.getClass().getName()));
            }
    
            server.setDumpAfterStart(true);
            server.start();
            server.join();
        }
    }
    

    这将采用现有的嵌入式 Jetty 服务器、内部标记特定组件和 ID 映射,以及一些属性,以及用户提供的 XML 文件列表来配置此服务器。

    这里有一些可用于此类设置的 XML。

    调整默认上下文路径.xml

    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
      "http://www.eclipse.org/jetty/configure_9_3.dtd">
    <Configure id="Context" class="org.eclipse.jetty.servlet.ServletContextHandler">
      <Set name="contextPath">/foobar</Set>
    </Configure>
    

    配置-http.xml

    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
      "http://www.eclipse.org/jetty/configure_9_3.dtd">
    <Configure id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
      <Set name="secureScheme">https</Set>
      <Set name="securePort">8443</Set>
      <Set name="outputBufferSize">32768</Set>
      <Set name="requestHeaderSize">8192</Set>
      <Set name="responseHeaderSize">8192</Set>
      <Set name="sendServerVersion">true</Set>
    </Configure>
    

    add-rewrites.xml

    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
      "http://www.eclipse.org/jetty/configure_9_3.dtd">
    <Configure id="Server" class="org.eclipse.jetty.server.Server">
      <Call name="insertHandler">
        <Arg>
          <New class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
            <Set name="rewriteRequestURI">true</Set>
            <Set name="rewritePathInfo">false</Set>
            <Set name="originalPathAttribute">requestedPath</Set>
    
            <Set name="dispatcherTypes">
              <Array type="javax.servlet.DispatcherType">
                <Item>
                  <Call class="javax.servlet.DispatcherType" name="valueOf">
                    <Arg>REQUEST</Arg>
                  </Call>
                </Item>
                <Item>
                  <Call class="javax.servlet.DispatcherType" name="valueOf">
                    <Arg>ASYNC</Arg>
                  </Call>
                </Item>
              </Array>
            </Set>
    
            <Get name="ruleContainer">
              <Call name="addRule">
                <Arg>
                  <New class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule">
                    <Set name="pattern">/bar/*</Set>
                    <Set name="location">/foo</Set>
                  </New>
                </Arg>
              </Call>
            </Get>
          </New>
        </Arg>
      </Call>
    </Configure>
    

    添加-https.xml

    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN"
      "http://www.eclipse.org/jetty/configure_9_3.dtd">
    <Configure id="Server" class="org.eclipse.jetty.server.Server">
    
      <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
        <Set name="KeyStorePath"><Property name="resources.location"/>/ssl/keystore</Set>
        <Set name="KeyStorePassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
        <Set name="KeyStoreType">JKS</Set>
        <Set name="KeyManagerPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
        <Set name="TrustStorePath"><Property name="resources.location"/>/ssl/keystore</Set>
        <Set name="RenegotiationAllowed">false</Set>
      </New>
    
      <New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
        <Arg><Ref refid="httpConfig"/></Arg>
        <Call name="addCustomizer">
          <Arg>
            <New class="org.eclipse.jetty.server.SecureRequestCustomizer">
              <Arg name="sniHostCheck" type="boolean">true</Arg>
              <Arg name="stsMaxAgeSeconds" type="int">-1</Arg>
              <Arg name="stsIncludeSubdomains" type="boolean">false</Arg>
            </New>
          </Arg>
        </Call>
      </New>
    
      <Call  name="addConnector">
        <Arg>
          <New id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
            <Arg name="server"><Ref refid="Server" /></Arg>
            <Arg name="acceptors" type="int">-1</Arg>
            <Arg name="selectors" type="int">-1</Arg>
            <Arg name="factories">
              <Array type="org.eclipse.jetty.server.ConnectionFactory">
                <!-- uncomment to support proxy protocol
                <Item>
                  <New class="org.eclipse.jetty.server.ProxyConnectionFactory"/>
                </Item>-->
              </Array>
            </Arg>
    
            <Set name="port">8443</Set>
            <Set name="idleTimeout">30000</Set>
            <Set name="soLingerTime">-1</Set>
            <Set name="acceptorPriorityDelta">0</Set>
            <Set name="acceptQueueSize">0</Set>
            <Get name="SelectorManager">
              <Set name="connectTimeout">15000</Set>
            </Get>
    
            <Call name="addIfAbsentConnectionFactory">
              <Arg>
                <New class="org.eclipse.jetty.server.SslConnectionFactory">
                  <Arg name="next">http/1.1</Arg>
                  <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
                </New>
              </Arg>
            </Call>
    
            <Call name="addConnectionFactory">
              <Arg>
                <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                  <Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
                  <Arg name="compliance">
                    <Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf">
                      <Arg>RFC7230</Arg>
                    </Call>
                  </Arg>
                </New>
              </Arg>
            </Call>
          </New>
        </Arg>
      </Call>
    </Configure>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多