今天我们来学习一下有关开源地图服务geoserver的源代码。首先学习这个源代码还是挺有用的,geoserver是关于spring、写的一个java服务,此外代码里面应用到很多编程套路(设计模式)方面的知识,geoserver地图服务实现OGC(开放地理信息联盟)wms、wfs等地图服务,因此对于想深入了解OGC地图服务方面相关原理与编码实现,无疑学习源代码是不错的方式。大家可以从github下载geoserver源代码。如下图所示,链接地址为https://github.com/geoserver/geoserver,从github上给geoserver的星数,可见其具有一定的影响力。

geoserver怎么发布mysql视图数据 geoserver开发_System

当然了,大家也可以从geoserver的官网上下载源代码。链接地址如下。http://geoserver.org/release/2.14.0/。下载完后整个工程的源代码目录如下。我们使用的是src目录下的代码。

geoserver怎么发布mysql视图数据 geoserver开发_java_02

进入到src目录,如下图所示。进入到src目录,如下图所示。

geoserver怎么发布mysql视图数据 geoserver开发_System_03

源代码是应该是使用maven构建的多个module。使用pox.xml配置jar包。我们使用intelliJ IDEA2017打开工程。

geoserver怎么发布mysql视图数据 geoserver开发_System_04

geoserver怎么发布mysql视图数据 geoserver开发_System_05

geoserver怎么发布mysql视图数据 geoserver开发_eclipse_06

geoserver怎么发布mysql视图数据 geoserver开发_eclipse_07

geoserver怎么发布mysql视图数据 geoserver开发_eclipse_08

geoserver怎么发布mysql视图数据 geoserver开发_eclipse_09

geoserver怎么发布mysql视图数据 geoserver开发_eclipse_10

geoserver怎么发布mysql视图数据 geoserver开发_eclipse_11

geoserver怎么发布mysql视图数据 geoserver开发_eclipse_12

好了,如上图所示,整个工程的源代码就导入进来了。下面,如下图所示,idea开始下载jar包,这中间过程有点漫长,大家可以做点其他的事情。

geoserver怎么发布mysql视图数据 geoserver开发_eclipse_13

等所有的jar包都下载好后,我们来运行一下geoserver工程。选择web目录start.jar运行。

geoserver怎么发布mysql视图数据 geoserver开发_java_14

最后在浏览器中输入: http://localhost:8080/geoserver/web/,浏览器中出现如下图的界面。

geoserver怎么发布mysql视图数据 geoserver开发_System_15

输入用户名:admin,密码:geoserver,出现如下的界面。

 

geoserver怎么发布mysql视图数据 geoserver开发_java_16

至此,工程就导入成功了。

下面在导入的时候的遇到问题。

一、报如下的错误。

geoserver怎么发布mysql视图数据 geoserver开发_System_17

不知道为啥,github上面没有提供该部分的源代码,还是哪里没有设置成功,具体没有研究。这里主要出现在wcs_1.1,wcs_2.0中报的错误,需要将该部分给删除掉。

二、运行Start.java文件出现错误。

geoserver怎么发布mysql视图数据 geoserver开发_System_18

需要改一下109的路径,我这里改成如下,来看一下代码。

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
 * (c) 2001 - 2013 OpenPlans
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.web;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.springframework.security.web.authentication.preauth.x509.SubjectDnX509PrincipalExtractor;

/**
 * Jetty starter, will run geoserver inside the Jetty web container.<br>
 * Useful for debugging, especially in IDE were you have direct dependencies between the sources of
 * the various modules (such as Eclipse).
 *
 * @author wolf
 */
public class Start {
    private static final Logger log =
            org.geotools.util.logging.Logging.getLogger(Start.class.getName());

    public static void main(String[] args) {
        final Server jettyServer = new Server();

        try {
            HttpConfiguration httpConfig = new HttpConfiguration();

            ServerConnector http =
                    new ServerConnector(jettyServer, new HttpConnectionFactory(httpConfig));
            http.setPort(Integer.getInteger("jetty.port", 8080));
            http.setAcceptQueueSize(100);
            http.setIdleTimeout(1000 * 60 * 60);
            http.setSoLingerTime(-1);

            // Use this to set a limit on the number of threads used to respond requests
            // BoundedThreadPool tp = new BoundedThreadPool();
            // tp.setMinThreads(8);
            // tp.setMaxThreads(8);
            // conn.setThreadPool(tp);

            // SSL host name given ?
            String sslHost = System.getProperty("ssl.hostname");
            ServerConnector https = null;
            if (sslHost != null && sslHost.length() > 0) {
                Security.addProvider(new BouncyCastleProvider());
                SslContextFactory ssl = createSSLContextFactory(sslHost);

                HttpConfiguration httpsConfig = new HttpConfiguration(httpConfig);
                httpsConfig.addCustomizer(new SecureRequestCustomizer());

                https =
                        new ServerConnector(
                                jettyServer,
                                new SslConnectionFactory(ssl, HttpVersion.HTTP_1_1.asString()),
                                new HttpConnectionFactory(httpsConfig));
                https.setPort(8443);
            }

            jettyServer.setConnectors(
                    https != null ? new Connector[] {http, https} : new Connector[] {http});

            /*Constraint constraint = new Constraint();
            constraint.setName(Constraint.__BASIC_AUTH);;
            constraint.setRoles(new String[]{"user","admin","moderator"});
            constraint.setAuthenticate(true);

            ConstraintMapping cm = new ConstraintMapping();
            cm.setConstraint(constraint);
            cm.setPathSpec("/*");

            SecurityHandler sh = new SecurityHandler();
            sh.setUserRealm(new HashUserRealm("MyRealm","/Users/jdeolive/realm.properties"));
            sh.setConstraintMappings(new ConstraintMapping[]{cm});

            WebAppContext wah = new WebAppContext(sh, null, null, null);*/
            WebAppContext wah = new WebAppContext();
            wah.setContextPath("/geoserver");
            wah.setWar("web/app/src/main/webapp");

            jettyServer.setHandler(wah);
            wah.setTempDirectory(new File("target/work"));
            // this allows to send large SLD's from the styles form
            wah.getServletContext().getContextHandler().setMaxFormContentSize(1024 * 1024 * 2);

            String jettyConfigFile = System.getProperty("jetty.config.file");
            if (jettyConfigFile != null) {
                log.info("Loading Jetty config from file: " + jettyConfigFile);
                (new XmlConfiguration(new FileInputStream(jettyConfigFile))).configure(jettyServer);
            }

            long start = System.currentTimeMillis();
            log.severe("GeoServer starting");

            jettyServer.start();

            long end = System.currentTimeMillis();
            log.severe("GeoServer startup complete in " + (end - start) / 1000. + "s");

            /*
             * Reads from System.in looking for the string "stop\n" in order to gracefully terminate
             * the jetty server and shut down the JVM. This way we can invoke the shutdown hooks
             * while debugging in eclipse. Can't catch CTRL-C to emulate SIGINT as the eclipse
             * console is not propagating that event
             */
            Thread stopThread =
                    new Thread() {
                        @Override
                        public void run() {
                            BufferedReader reader =
                                    new BufferedReader(new InputStreamReader(System.in));
                            String line;
                            try {
                                while (true) {
                                    line = reader.readLine();
                                    if ("stop".equals(line)) {
                                        jettyServer.stop();
                                        System.exit(0);
                                    }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                System.exit(1);
                            }
                        }
                    };
            stopThread.setDaemon(true);
            stopThread.run();

            // use this to test normal stop behaviour, that is, to check stuff that
            // need to be done on container shutdown (and yes, this will make
            // jetty stop just after you started it...)
            // jettyServer.stop();
        } catch (Exception e) {
            log.log(Level.SEVERE, "Could not start the Jetty server: " + e.getMessage(), e);

            if (jettyServer != null) {
                try {
                    jettyServer.stop();
                } catch (Exception e1) {
                    log.log(
                            Level.SEVERE,
                            "Unable to stop the " + "Jetty server:" + e1.getMessage(),
                            e1);
                }
            }
        }
    }

    private static SslContextFactory createSSLContextFactory(String hostname) {
        String password = "changeit";

        File userHome = new File(System.getProperty("user.home"));
        File geoserverDir = new File(userHome, ".geoserver");
        if (!geoserverDir.exists()) {
            geoserverDir.mkdir();
        }

        File keyStoreFile = new File(geoserverDir, "keystore.jks");
        try {
            assureSelfSignedServerCertificate(hostname, keyStoreFile, password);
        } catch (Exception e) {
            log.log(Level.WARNING, "NO SSL available", e);
            return null;
        }
        SslContextFactory ssl = new SslContextFactory();
        ssl.setKeyStorePath(keyStoreFile.getAbsolutePath());
        ssl.setKeyStorePassword(password);

        File javaHome = new File(System.getProperty("java.home"));
        File cacerts = new File(javaHome, "lib").toPath().resolve("security/cacerts").toFile();

        if (!cacerts.exists()) {
            return null;
        }

        ssl.setTrustStorePath(cacerts.getAbsolutePath());
        ssl.setTrustStorePassword("changeit");

        return ssl;
    }

    private static void assureSelfSignedServerCertificate(
            String hostname, File keyStoreFile, String password) throws Exception {

        KeyStore privateKS = KeyStore.getInstance("JKS");
        if (keyStoreFile.exists()) {
            FileInputStream fis = new FileInputStream(keyStoreFile);
            privateKS.load(fis, password.toCharArray());
            if (keyStoreContainsCertificate(privateKS, hostname)) return;
        } else {
            privateKS.load(null);
        }

        // create a RSA key pair generator using 1024 bits

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair KPair = keyPairGenerator.generateKeyPair();

        // cerate a X509 certifacte generator
        X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator();

        // set validity to 10 years, issuer and subject are equal --> self singed certificate
        int random = new SecureRandom().nextInt();
        if (random < 0) random *= -1;
        v3CertGen.setSerialNumber(BigInteger.valueOf(random));
        v3CertGen.setIssuerDN(
                new X509Principal("CN=" + hostname + ", OU=None, O=None L=None, C=None"));
        v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30));
        v3CertGen.setNotAfter(
                new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365 * 10)));
        v3CertGen.setSubjectDN(
                new X509Principal("CN=" + hostname + ", OU=None, O=None L=None, C=None"));

        v3CertGen.setPublicKey(KPair.getPublic());
        v3CertGen.setSignatureAlgorithm("MD5WithRSAEncryption");

        X509Certificate PKCertificate = v3CertGen.generateX509Certificate(KPair.getPrivate());

        // store the certificate containing the public key,this file is needed
        // to import the public key in other key store.
        File certFile = new File(keyStoreFile.getParentFile(), hostname + ".cert");
        FileOutputStream fos = new FileOutputStream(certFile.getAbsoluteFile());
        fos.write(PKCertificate.getEncoded());
        fos.close();

        privateKS.setKeyEntry(
                hostname + ".key",
                KPair.getPrivate(),
                password.toCharArray(),
                new java.security.cert.Certificate[] {PKCertificate});

        privateKS.setCertificateEntry(hostname + ".cert", PKCertificate);

        privateKS.store(new FileOutputStream(keyStoreFile), password.toCharArray());
    }

    private static boolean keyStoreContainsCertificate(KeyStore ks, String hostname)
            throws Exception {
        SubjectDnX509PrincipalExtractor ex = new SubjectDnX509PrincipalExtractor();
        Enumeration<String> e = ks.aliases();
        while (e.hasMoreElements()) {
            String alias = e.nextElement();
            if (ks.isCertificateEntry(alias)) {
                Certificate c = ks.getCertificate(alias);
                if (c instanceof X509Certificate) {
                    X500Principal p =
                            (X500Principal) ((X509Certificate) c).getSubjectX500Principal();
                    if (p.getName().contains(hostname)) return true;
                }
            }
        }
        return false;
    }
}

                                                                              更多内容,请关注公众号