从 Jhipster (java 和 angular 6) 中的 URL 中删除哈希 (#) [英] Remove hash (#) from URL in Jhipster (both java and angular 6)

查看:24
本文介绍了从 Jhipster (java 和 angular 6) 中的 URL 中删除哈希 (#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Jhipster Spring boot + angular 6.但是由于 URL 中的哈希(#),我遇到了麻烦.它正在影响 SEO.

我尝试在 app-routing-module.ts 中设置 useHash: false.但是当我通过 npm start 运行项目时,API 不起作用.

我认为在 Java 文件的某个地方我必须更改配置以从 URL 中删除 #.

这是我的 WebConfigurer 代码,

@Configuration公共类 WebConfigurer 实现了 ServletContextInitializer、WebServerFactoryCustomizer<WebServerFactory>{私有最终记录器日志 = LoggerFactory.getLogger(WebConfigurer.class);私人最终环境环境;私人最终 JHipsterProperties jHipsterProperties;私有 MetricRegistry metricRegistry;公共 WebConfigurer(环境环境,JHipsterProperties jHipsterProperties){this.env = env;this.jHipsterProperties = jHipsterProperties;}@覆盖public void onStartup(ServletContext servletContext) 抛出 ServletException {如果 (env.getActiveProfiles().length != 0) {log.info("Web 应用程序配置,使用配置文件:{}", (Object[]) env.getActiveProfiles());}EnumSetdisps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);initMetrics(servletContext,disps);log.info("Web 应用程序完全配置");}/*** 自定义 Servlet 引擎:Mime 类型、文档根目录、缓存.*/@覆盖公共无效定制(WebServerFactory服务器){setMimeMappings(服务器);/** 为 Undertow 启用 HTTP/2 - https://twitter.com/ankinson/status/829256167700492288* HTTP/2 需要 HTTPS,因此 HTTP 请求将回退到 HTTP/1.1.* 查看 JHipsterProperties 类和您的 application-*.yml 配置文件* 想要查询更多的信息.*/if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&UndertowServletWebServerFactory 的服务器实例) {((UndertowServletWebServerFactory)服务器).addBuilderCustomizers(builder ->builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));}}私有无效 setMimeMappings(WebServerFactory 服务器){如果(ConfigurableServletWebServerFactory 的服务器实例){MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);//IE问题,见https://github.com/jhipster/generator-jhipster/pull/711mappings.add("html", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());//CloudFoundry 问题,参见 https://github.com/cloudfoundry/gorouter/issues/64mappings.add("json", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) 服务器;servletWebServer.setMimeMappings(mappings);}}/*** 初始化指标.*/private void initMetrics(ServletContext servletContext, EnumSet disps) {log.debug("初始化指标注册表");servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE,metricRegistry);servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY,metricRegistry);log.debug("注册指标过滤器");FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter",新仪器过滤器());metricsFilter.addMappingForUrlPatterns(disps, true, "/*");metricsFilter.setAsyncSupported(true);log.debug("注册指标 Servlet");ServletRegistration.Dynamic metricsAdminServlet =servletContext.addServlet("metricsServlet", new MetricsServlet());metricsAdminServlet.addMapping("/management/metrics/*");metricsAdminServlet.setAsyncSupported(true);metricsAdminServlet.setLoadOnStartup(2);}@豆角,扁豆公共 CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = jHipsterProperties.getCors();if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {log.debug("注册 CORS 过滤器");source.registerCorsConfiguration("/api/**", config);source.registerCorsConfiguration("/management/**", config);source.registerCorsConfiguration("/v2/api-docs", config);}返回新的 CorsFilter(source);}@Autowired(必需=假)公共无效 setMetricRegistry(MetricRegistry metricRegistry) {this.metricRegistry = metricRegistry;}}

这是我的 AngularRouteFilter servlet 代码,

public class AngularRouteFilter extends OncePerRequestFilter {//添加要重定向的值private static final Pattern PATTERN = Pattern.compile("^/((api|swagger-ui|management|swagger-resources)/|favicon\\.ico|v2/api-docs).*");@覆盖protected void doFilterInternal(HttpServletRequest 请求,HttpServletResponse 响应,FilterChain filterChain)抛出 ServletException,IOException {如果(isServerRoute(请求)){filterChain.doFilter(请求,响应);} 别的 {RequestDispatcher rd = request.getRequestDispatcher("/");rd.forward(请求,响应);}}protected static boolean isServerRoute(HttpServletRequest request) {if (request.getMethod().equals("GET")) {String uri = request.getRequestURI();if (uri.startsWith("/app")){返回真;}返回 PATTERN.matcher(uri).matches();}返回真;}}

这是我的 Swagger index.html(swagger-ui/index.html)

<头><meta charset="UTF-8"><title>Swagger UI</title><link rel="icon" type="image/png" href="images/favicon-32x32.png" size="32x32"/><link rel="icon" type="image/png" href="images/favicon-16x16.png" size="16x16"/><link href='./dist/css/typography.css' media='screen' rel='stylesheet' type='text/css'/><link href='./dist/css/reset.css' media='screen' rel='stylesheet' type='text/css'/><link href='./dist/css/screen.css' media='screen' rel='stylesheet' type='text/css'/><link href='./dist/css/reset.css' media='print' rel='stylesheet' type='text/css'/><link href='./dist/css/print.css' media='print' rel='stylesheet' type='text/css'/><script src='./dist/lib/object-assign-pollyfill.js' type='text/javascript'></script><script src='./dist/lib/jquery-1.8.0.min.js' type='text/javascript'></script><script src='./dist/lib/jquery.slideto.min.js' type='text/javascript'></script><script src='./dist/lib/jquery.wiggle.min.js' type='text/javascript'></script><script src='./dist/lib/jquery.ba-bbq.min.js' type='text/javascript'></script><script src='./dist/lib/handlebars-4.0.5.js' type='text/javascript'></script><script src='./dist/lib/lodash.min.js' type='text/javascript'></script><script src='./dist/lib/backbone-min.js' type='text/javascript'></script><script src='./dist/swagger-ui.min.js' type='text/javascript'></script><script src='./dist/lib/highlight.9.1.0.pack.js' type='text/javascript'></script><script src='./dist/lib/highlight.9.1.0.pack.js' type='text/javascript'></script><script src='./dist/lib/jsoneditor.min.js' type='text/javascript'></script><script src='./dist/lib/marked.js' type='text/javascript'></script><script src='./dist/lib/swagger-oauth.js' type='text/javascript'></script><!-- 一些基本翻译--><!-- <script src='lang/translator.js' type='text/javascript'></script>--><!-- <script src='lang/ru.js' type='text/javascript'></script>--><!-- <script src='lang/en.js' type='text/javascript'></script>--><script type="text/javascript">$(函数(){var springfox = {baseUrl":函数(){var urlMatches =/(.*)\/swagger-ui\/index.html.*/.exec(window.location.href);返回 urlMatches[1];},安全配置":功能(CB){$.getJSON(this.baseUrl() + "/swagger-resources/configuration/security", function(data) {CB(数据);});},uiConfig":函数(cb){警报(CB);$.getJSON(this.baseUrl() + "/swagger-resources/configuration/ui", function(data) {CB(数据);});}};window.springfox = springfox;window.oAuthRedirectUrl = springfox.baseUrl() + './dist/o2c.html'window.springfox.uiConfig(函数(数据){window.swaggerUi = 新 SwaggerUi({dom_id: "swagger-ui-container",验证器网址:data.validatorUrl,支持的提交方法: ['get', 'post', 'put', 'delete', 'patch'],onComplete:函数(swaggerApi,swaggerUi){初始化 Springfox();如果(window.SwaggerTranslator){window.SwaggerTranslator.translate();}$('pre code').each(function(i, e) {hljs.highlightBlock(e)});},onFailure:功能(数据){log("无法加载 SwaggerUI");},docExpansion:无",apisSorter:阿尔法",showRequestHeaders: 假});initializeBaseUrl();$('#select_baseUrl').change(function() {window.swaggerUi.headerView.trigger('update-swagger-ui', {网址:$('#select_baseUrl').val()});addApiKeyAuthorization();});函数 addApiKeyAuthorization() {var authToken = JSON.parse(localStorage.getItem("jhi-authenticationtoken") || sessionStorage.getItem("jhi-authenticationtoken"));var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", "Bearer" + authToken, "header");window.swaggerUi.api.clientAuthorizations.add("bearer", apiKeyAuth);}函数 getCSRF() {var name = "XSRF-TOKEN=";var ca = document.cookie.split(';');for(var i=0; i<body class="swagger-section"><div id='header'><div class="swagger-ui-wrap"><a id="logo" href="http://swagger.io">swagger</a><form id='api_selector'>

<select id="select_baseUrl" name="select_baseUrl"></select>

<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/>

</表单>

<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div><div id="swagger-ui-container" class="swagger-ui-wrap"></div></html>

这里是 docs.component.html

<iframe src="swagger-ui/index.html" width="100%" height="900" 无缝target="_top" title="Swagger UI" class="border-0"></iframe>

这里我的服务器代码运行完美@ localhost:6060.但是 localhost:6060/api/docs 打开一个空白页面.

这是屏幕截图,

请告诉我哪里做错了.

解决方案

使用 servlet 过滤器的解决方案

第一步是配置客户端,在app-routing-module.ts

中设置useHash: false

index.html中,将改为

但这还不够,因为它不支持深层链接,这意味着从外部链接(如邮件消息或其他网站)链接到客户端路由,或者在浏览器中刷新页面时使用 veen.

深度链接时,服务器首先收到请求,如果该 URL 必须由客户端处理,则不会被找到,因此我们的服务器应用程序必须检测该 URL 是否必须由服务器按原样提供(例如所有 API 调用)或转发到 index.html 以便 javascript 应用程序可以解释它.

一种解决方案是在我们在 WebConfigurer.java 中注册的 servlet 过滤器 (Html5RouteFilter) 中使用模式匹配

WebConfigurer.java

<前>@豆角,扁豆公共 Html5RouteFilter html5RouteFilter() {返回新的 Html5RouteFilter();}

Html5RouteFilter.java

<前>包 com.mycompany.myapp.web;导入 org.slf4j.Logger;导入 org.slf4j.LoggerFactory;导入 org.springframework.web.filter.OncePerRequestFilter;导入 javax.servlet.FilterChain;导入 javax.servlet.RequestDispatcher;导入 javax.servlet.ServletException;导入 javax.servlet.http.HttpServletRequest;导入 javax.servlet.http.HttpServletResponse;导入 java.io.IOException;导入 java.util.regex.Pattern;/*** 在客户端路由中不使用#"时区分客户端路由和服务器路由的过滤器.*/公共类 Html5RouteFilter 扩展 OncePerRequestFilter {私有记录器日志 = LoggerFactory.getLogger(getClass());//这些是应该在服务器端处理的 URIprivate static final Pattern PATTERN = Pattern.compile("^/((api|content|i18n|management|swagger-ui|swagger-resources)/|error|h2-console|swagger-resources|favicon\\.ico|v2/api-docs).*");@覆盖protected void doFilterInternal(HttpServletRequest 请求,HttpServletResponse 响应,FilterChain filterChain)抛出 ServletException,IOException {如果(isServerRoute(请求)){filterChain.doFilter(请求,响应);} 别的 {RequestDispatcher rd = request.getRequestDispatcher("/");rd.forward(请求,响应);}}protected static boolean isServerRoute(HttpServletRequest request) {if (request.getMethod().equals("GET")) {String uri = request.getRequestURI();if (uri.startsWith("/app")) {返回真;}返回 PATTERN.matcher(uri).matches();}返回真;}}

I am using Jhipster Spring boot + angular 6. But i'm having trouble because of the hash(#) in URL. It is affecting SEO.

I tried setting useHash: false in app-routing-module.ts. But then the API is not working when I run the project via npm start.

I think somewhere in Java files I have to change a configuration to remove # from the URL.

Here is my WebConfigurer code,

@Configuration
public class WebConfigurer implements ServletContextInitializer, WebServerFactoryCustomizer<WebServerFactory> {

    private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);

    private final Environment env;

    private final JHipsterProperties jHipsterProperties;

    private MetricRegistry metricRegistry;

    public WebConfigurer(Environment env, JHipsterProperties jHipsterProperties) {

        this.env = env;
        this.jHipsterProperties = jHipsterProperties;
    }

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        if (env.getActiveProfiles().length != 0) {
            log.info("Web application configuration, using profiles: {}", (Object[]) env.getActiveProfiles());
        }
        EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
        initMetrics(servletContext, disps);
        log.info("Web application fully configured");
    }

    /**
     * Customize the Servlet engine: Mime types, the document root, the cache.
     */
    @Override
    public void customize(WebServerFactory server) {
        setMimeMappings(server);

        /*
         * Enable HTTP/2 for Undertow - https://twitter.com/ankinson/status/829256167700492288
         * HTTP/2 requires HTTPS, so HTTP requests will fallback to HTTP/1.1.
         * See the JHipsterProperties class and your application-*.yml configuration files
         * for more information.
         */
        if (jHipsterProperties.getHttp().getVersion().equals(JHipsterProperties.Http.Version.V_2_0) &&
            server instanceof UndertowServletWebServerFactory) {

            ((UndertowServletWebServerFactory) server)
                .addBuilderCustomizers(builder ->
                    builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
        }
    }

    private void setMimeMappings(WebServerFactory server) {
        if (server instanceof ConfigurableServletWebServerFactory) {
            MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
            // IE issue, see https://github.com/jhipster/generator-jhipster/pull/711
            mappings.add("html", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());
            // CloudFoundry issue, see https://github.com/cloudfoundry/gorouter/issues/64
            mappings.add("json", MediaType.TEXT_HTML_VALUE + ";charset=" + StandardCharsets.UTF_8.name().toLowerCase());
            ConfigurableServletWebServerFactory servletWebServer = (ConfigurableServletWebServerFactory) server;
            servletWebServer.setMimeMappings(mappings);
        }
    }

    /**
     * Initializes Metrics.
     */
    private void initMetrics(ServletContext servletContext, EnumSet<DispatcherType> disps) {
        log.debug("Initializing Metrics registries");
        servletContext.setAttribute(InstrumentedFilter.REGISTRY_ATTRIBUTE,
            metricRegistry);
        servletContext.setAttribute(MetricsServlet.METRICS_REGISTRY,
            metricRegistry);

        log.debug("Registering Metrics Filter");
        FilterRegistration.Dynamic metricsFilter = servletContext.addFilter("webappMetricsFilter",
            new InstrumentedFilter());

        metricsFilter.addMappingForUrlPatterns(disps, true, "/*");
        metricsFilter.setAsyncSupported(true);

        log.debug("Registering Metrics Servlet");
        ServletRegistration.Dynamic metricsAdminServlet =
            servletContext.addServlet("metricsServlet", new MetricsServlet());

        metricsAdminServlet.addMapping("/management/metrics/*");
        metricsAdminServlet.setAsyncSupported(true);
        metricsAdminServlet.setLoadOnStartup(2);
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = jHipsterProperties.getCors();
        if (config.getAllowedOrigins() != null && !config.getAllowedOrigins().isEmpty()) {
            log.debug("Registering CORS filter");
            source.registerCorsConfiguration("/api/**", config);
            source.registerCorsConfiguration("/management/**", config);
            source.registerCorsConfiguration("/v2/api-docs", config);
        }
        return new CorsFilter(source);
    }

    @Autowired(required = false)
    public void setMetricRegistry(MetricRegistry metricRegistry) {
        this.metricRegistry = metricRegistry;
    }
}

Here is my AngularRouteFilter servlet code,

public class AngularRouteFilter extends OncePerRequestFilter {

    // add the values you want to redirect for
    private static final Pattern PATTERN = Pattern.compile("^/((api|swagger-ui|management|swagger-resources)/|favicon\\.ico|v2/api-docs).*");

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain)
        throws ServletException, IOException {
        if (isServerRoute(request)) {
            filterChain.doFilter(request, response);
        } else {
            RequestDispatcher rd = request.getRequestDispatcher("/");
            rd.forward(request, response);
        }
    }

    protected static boolean isServerRoute(HttpServletRequest request) {
        if (request.getMethod().equals("GET")) {
            String uri = request.getRequestURI();
        if (uri.startsWith("/app")){

                return true;
            }
            return PATTERN.matcher(uri).matches();
        }
        return true;
    }
}

here is my Swagger index.html(swagger-ui/index.html)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Swagger UI</title>
    <link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
    <link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
    <link href='./dist/css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
    <link href='./dist/css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
    <link href='./dist/css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
    <link href='./dist/css/reset.css' media='print' rel='stylesheet' type='text/css'/>
    <link href='./dist/css/print.css' media='print' rel='stylesheet' type='text/css'/>
    <script src='./dist/lib/object-assign-pollyfill.js' type='text/javascript'></script>
    <script src='./dist/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
    <script src='./dist/lib/jquery.slideto.min.js' type='text/javascript'></script>
    <script src='./dist/lib/jquery.wiggle.min.js' type='text/javascript'></script>
    <script src='./dist/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
    <script src='./dist/lib/handlebars-4.0.5.js' type='text/javascript'></script>
    <script src='./dist/lib/lodash.min.js' type='text/javascript'></script>
    <script src='./dist/lib/backbone-min.js' type='text/javascript'></script>
    <script src='./dist/swagger-ui.min.js' type='text/javascript'></script>
    <script src='./dist/lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
    <script src='./dist/lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
    <script src='./dist/lib/jsoneditor.min.js' type='text/javascript'></script>
    <script src='./dist/lib/marked.js' type='text/javascript'></script>
    <script src='./dist/lib/swagger-oauth.js' type='text/javascript'></script>

    <!-- Some basic translations -->
    <!-- <script src='lang/translator.js' type='text/javascript'></script> -->
    <!-- <script src='lang/ru.js' type='text/javascript'></script> -->
    <!-- <script src='lang/en.js' type='text/javascript'></script> -->

    <script type="text/javascript">
        $(function() {
            var springfox = {
                "baseUrl": function() {
                    var urlMatches = /(.*)\/swagger-ui\/index.html.*/.exec(window.location.href);
                    return urlMatches[1];
                },
                "securityConfig": function(cb) {
                    $.getJSON(this.baseUrl() + "/swagger-resources/configuration/security", function(data) {
                        cb(data);
                    });
                },
                "uiConfig": function(cb) {
                                    alert(cb);

                    $.getJSON(this.baseUrl() + "/swagger-resources/configuration/ui", function(data) {
                        cb(data);
                    });
                }
            };
            window.springfox = springfox;
            window.oAuthRedirectUrl = springfox.baseUrl() + './dist/o2c.html'

            window.springfox.uiConfig(function(data) {
                window.swaggerUi = new SwaggerUi({
                    dom_id: "swagger-ui-container",
                    validatorUrl: data.validatorUrl,
                    supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
                    onComplete: function(swaggerApi, swaggerUi) {
                        initializeSpringfox();
                        if (window.SwaggerTranslator) {
                            window.SwaggerTranslator.translate();
                        }
                        $('pre code').each(function(i, e) {
                            hljs.highlightBlock(e)
                        });
                    },
                    onFailure: function(data) {
                        log("Unable to Load SwaggerUI");
                    },
                    docExpansion: "none",
                    apisSorter: "alpha",
                    showRequestHeaders: false
                });

                initializeBaseUrl();

                $('#select_baseUrl').change(function() {
                    window.swaggerUi.headerView.trigger('update-swagger-ui', {
                        url: $('#select_baseUrl').val()
                    });
                    addApiKeyAuthorization();
                });

                function addApiKeyAuthorization() {
                    var authToken = JSON.parse(localStorage.getItem("jhi-authenticationtoken") || sessionStorage.getItem("jhi-authenticationtoken"));
                    var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", "Bearer " + authToken, "header");
                    window.swaggerUi.api.clientAuthorizations.add("bearer", apiKeyAuth);
                }

                function getCSRF() {
                    var name = "XSRF-TOKEN=";
                    var ca = document.cookie.split(';');
                    for(var i=0; i<ca.length; i++) {
                        var c = ca[i];
                        while (c.charAt(0)==' ') c = c.substring(1);
                        if (c.indexOf(name) !== -1) return c.substring(name.length,c.length);
                    }
                    return "";
                }

                function log() {
                    if ('console' in window) {
                        console.log.apply(console, arguments);
                    }
                }

                function oAuthIsDefined(security) {
                    return security.clientId
                    && security.clientSecret
                    && security.appName
                    && security.realm;
                }

                function initializeSpringfox() {
                    var security = {};
                    window.springfox.securityConfig(function(data) {
                        security = data;
                        if (typeof initOAuth === "function" && oAuthIsDefined(security)) {
                            initOAuth(security);
                        }
                    });
                }
            });

            function maybePrefix(location, withRelativePath) {
                var pat = /^https?:\/\//i;
                if (pat.test(location)) {
                    return location;
                }
                return withRelativePath + location;
            }

            function initializeBaseUrl() {
                var relativeLocation = springfox.baseUrl();

                $('#input_baseUrl').hide();

                $.getJSON(relativeLocation + "/swagger-resources", function(data) {

                    var $urlDropdown = $('#select_baseUrl');
                    $urlDropdown.empty();
                    $.each(data, function(i, resource) {
                        var option = $('<option></option>')
                        .attr("value", maybePrefix(resource.location, relativeLocation))
                        .text(resource.name + " (" + resource.location + ")");
                        $urlDropdown.append(option);
                    });
                    $urlDropdown.change();
                });

            }

        });
    </script>
</head>


<body class="swagger-section">
<div id='header'>
    <div class="swagger-ui-wrap">
        <a id="logo" href="http://swagger.io">swagger</a>

        <form id='api_selector'>
            <div class='input'>
                <select id="select_baseUrl" name="select_baseUrl"></select>
            </div>
            <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/>
            </div>
        </form>
    </div>
</div>

<div id="message-bar" class="swagger-ui-wrap" data-sw-translate>&nbsp;</div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>

here is docs.component.html

<iframe src="swagger-ui/index.html" width="100%" height="900" seamless
    target="_top" title="Swagger UI" class="border-0"></iframe>

here my server code is running perfectly @ localhost:6060. Butm localhost:6060/api/docs opening a blank page.

here is the screen shot,

Please suggest me where i am doing wrong.

解决方案

Solution using a servlet filter

First step is to configure client, set useHash: false in app-routing-module.ts

In index.html, change <base href="./" /> to <base href="/" />

But it's not enough because it does not support deep linking which means linking to a client route from an external link like from a mail message or from another web site, or veen when refreshing page in browser.

When deep linking, the server receives the request first and if the URL has to be handled by client side, it will not be found so our server app must detect whether the URL has to be served as-is by server (e.g. all API calls) or forwarded to index.html so that the javascript app can interpret it.

One solution is to use pattern matching in a servlet filter (Html5RouteFilter) that we register in WebConfigurer.java

WebConfigurer.java

    @Bean
    public Html5RouteFilter html5RouteFilter() {
        return new Html5RouteFilter();
    }

Html5RouteFilter.java

package com.mycompany.myapp.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Pattern;

/**
 * Filter that distinguishes between client routes and server routes  when you don't use '#' in client routes.
 */
public class Html5RouteFilter extends OncePerRequestFilter {

    private Logger log = LoggerFactory.getLogger(getClass());


    // These are the URIs that should be processed server-side
    private static final Pattern PATTERN = Pattern.compile("^/((api|content|i18n|management|swagger-ui|swagger-resources)/|error|h2-console|swagger-resources|favicon\\.ico|v2/api-docs).*");

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain)
        throws ServletException, IOException {
        if (isServerRoute(request)) {
            filterChain.doFilter(request, response);
        } else {
            RequestDispatcher rd = request.getRequestDispatcher("/");
            rd.forward(request, response);
        }
    }

    protected static boolean isServerRoute(HttpServletRequest request) {
        if (request.getMethod().equals("GET")) {
            String uri = request.getRequestURI();
            if (uri.startsWith("/app")) {
                return true;
            }
            return PATTERN.matcher(uri).matches();
        }
        return true;
    }
}

这篇关于从 Jhipster (java 和 angular 6) 中的 URL 中删除哈希 (#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
Java开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆