【问题标题】:why can't spring boot angularjs gateway app read from ui app?为什么 spring boot angularjs gateway 应用程序不能从 ui 应用程序读取?
【发布时间】:2016-03-18 01:36:34
【问题描述】:

我正在使用以下链接中的教程了解 Spring 的可扩展性功能。具体来说,part 6 of the tutorial 使用网关应用程序来管理对其他服务器上运行的应用程序的访问。

我完全按照以下步骤操作,但是当我启动所有三个应用程序,然后在我的网络浏览器中输入 localhost:8080/ui 时,我得到的只是没有 id 或 hello world 的单词“Greeting”,也没有 css .

当我在 Firefox 中打开请求的开发人员工具时,我看到对 css 和 js 资源的 GET 请求出现 404 错误,指向像 http://localhost:8080/js/hello.js 这样的 url 而不是 指向 @987654325 @,正如the test section of the tutorial 建议的那样。 如何更改此设置以便在浏览器中显示问候语?

这是我一步一步完成的,按照教程的第六步,首先从第一部分重新创建 ui 起点和从第三部分重新创建 resource 起点:


创建 UI 示例启动应用


# mkdir ui 
# chmod -R 777 ui
# cd ui
# curl https://start.spring.io/starter.tgz -d style=web -d style=security -d name=ui | tar -xzvf -

Eclipse > 文件 > 导入 > 现有 Maven 项目 > 导航到 ui 文件夹 > 完成

src/main/resources/static 中创建index.html 并添加以下内容:

<!doctype html>
<html>
<head>
<title>Hello AngularJS</title>
<link href="css/angular-bootstrap.css" rel="stylesheet">
<style type="text/css">
[ng\:cloak], [ng-cloak], .ng-cloak {
  display: none !important;
}
</style>
</head>

<body ng-app="hello">
  <div class="container">
    <h1>Greeting</h1>
    <div ng-controller="home" ng-cloak class="ng-cloak">
      <p>The ID is {{greeting.id}}</p>
      <p>The content is {{greeting.content}}</p>
    </div>
  </div>
  <script src="js/angular-bootstrap.js" type="text/javascript"></script>
  <script src="js/hello.js"></script>
</body>
</html>

将以下行添加到src/main/resources/application.properties

security.user.password=some.password
server.port: 8081
security.sessions: NEVER  // The "security.sessions" setting means that Spring Security will accept cookies as authentication tokens but won’t create them unless they already exist.

将以下内容添加到pom.xml,以便使用 wro4j 下载和集成 angular 和 bootstrap 等:

<build>
  <resources>
    <resource>
      <directory>${project.basedir}/src/main/resources</directory>
    </resource>
    <resource>
      <directory>${project.build.directory}/generated-resources</directory>
    </resource>
  </resources>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    <plugin>
      <artifactId>maven-resources-plugin</artifactId>
      <executions>
        <execution>
          <!-- Serves *only* to filter the wro.xml so it can get an absolute
            path for the project -->
          <id>copy-resources</id>
          <phase>validate</phase>
          <goals>
            <goal>copy-resources</goal>
          </goals>
          <configuration>
            <outputDirectory>${basedir}/target/wro</outputDirectory>
            <resources>
              <resource>
                <directory>src/main/wro</directory>
                <filtering>true</filtering>
              </resource>
            </resources>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>ro.isdc.wro4j</groupId>
      <artifactId>wro4j-maven-plugin</artifactId>
      <version>1.7.6</version>
      <executions>
        <execution>
          <phase>generate-resources</phase>
          <goals>
            <goal>run</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <wroManagerFactory>ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory</wroManagerFactory>
        <cssDestinationFolder>${project.build.directory}/generated-resources/static/css</cssDestinationFolder>
        <jsDestinationFolder>${project.build.directory}/generated-resources/static/js</jsDestinationFolder>
        <wroFile>${project.build.directory}/wro/wro.xml</wroFile>
        <extraConfigFile>${basedir}/src/main/wro/wro.properties</extraConfigFile>
        <contextFolder>${basedir}/src/main/wro</contextFolder>
      </configuration>
      <dependencies>
        <dependency>
          <groupId>org.webjars</groupId>
          <artifactId>jquery</artifactId>
          <version>2.1.1</version>
        </dependency>
        <dependency>
          <groupId>org.webjars</groupId>
          <artifactId>angularjs</artifactId>
          <version>1.3.8</version>
        </dependency>
        <dependency>
          <groupId>org.webjars</groupId>
          <artifactId>bootstrap</artifactId>
          <version>3.2.0</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

Eclipse > 文件 > 新建 > 源文件夹 > (创建 src/main/wro)

将以下内容添加到src/main/wro/wro.properties(将从less编译css并缩小javascript):

preProcessors=lessCssImport
postProcessors=less4j,jsMin

将以下内容添加到 src/main/wro/wro.xml(声明一个引用 css、js 和 main.less 的单组 angular-bootstrap):

<groups xmlns="http://www.isdc.ro/wro">
  <group name="angular-bootstrap">
  <css>webjar:bootstrap/3.2.0/less/bootstrap.less</css>
    <css>file:${project.basedir}/src/main/wro/main.less</css>
    <js>webjar:jquery/2.1.1/jquery.min.js</js>
    <js>webjar:angularjs/1.3.8/angular.min.js</js>
  </group>
</groups>

创建src/main/wro/main.less 并暂时将其留空。 main.less 可用于自定义引导默认值。

创建src/main/resources/static/js/hello.js 并添加以下内容:

angular.module('hello', [])
  .controller('home', function($scope, $http) {
  $http.get('/resource/').success(function(data) {
    $scope.greeting = data;
  })
});

com.example.UiApplication.java更改为:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
@EnableRedisHttpSession
public class UiApplication {

    public static void main(String[] args) {
        SpringApplication.run(UiApplication.class, args);
    }

}

// 现在将以下内容添加到 ui 应用的 pom.xml:

<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-redis</artifactId>
</dependency>

创建单独的资源服务器


// 导航到工作空间的根目录

# cd /home/username/someworkspace
# mkdir resource 
# chmod -R 777 resource 
# cd resource
# curl https://start.spring.io/starter.tgz -d style=web -d name=resource -d language=java | tar -xzvf -

Eclipse > 导入 > 现有 Maven 项目(导航到刚刚创建的资源文件夹)

// 在resource 应用程序中将以下内容添加到pom.xml

    <dependency>
      <groupId>org.springframework.session</groupId>
      <artifactId>spring-session</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-redis</artifactId>
    </dependency>

// 将com.example.ResourceApplication.java 更改为以下内容:

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@EnableRedisHttpSession
public class ResourceApplication {

  @RequestMapping("/resource")
  public Map<String,Object> home() {
    Map<String,Object> model = new HashMap<String,Object>();
    model.put("id", UUID.randomUUID().toString());
    model.put("content", "Hello World");
    return model;
  }

  public static void main(String[] args) {
    SpringApplication.run(ResourceApplication.class, args);
  }

}

// 将以下内容添加到src/main/resources/application.properties:

server.port: 9000
security.sessions: NEVER

创建网关应用


将终端导航到工作空间的根目录,然后

# cd /home/username/someworkspace
# mkdir gateway 
# chmod -R 777 gateway 
# cd gateway
# curl https://cloud-start.spring.io/starter.tgz -d style=web -d style=security -d style=cloud-zuul -d name=gateway -d style=redis | tar -xzvf -

Eclipse > 文件 > 导入 > 现有 Maven 项目 >(导航到网关目录)

//把GatewayApplication.java改成:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
@EnableRedisHttpSession
@EnableZuulProxy
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

// 将src/main/resources/application.properties 更改为:

zuul.routes.ui.url: http://localhost:8081
zuul.routes.resource.url: http://localhost:9000
security.user.password: password
security.sessions: ALWAYS

.
启动并测试应用程序:

# cd /home/username/someworkspace/ui
# mvn spring-boot:run

然后打开第二个终端并输入

# cd /home/username/someworkspace/resource
# mvn spring-boot:run  

然后打开第三个终端并输入:

# cd /home/username/someworkspace/gateway
# mvn spring-boot: run

// 通过在浏览器中输入 localhost:8080/ui 来测试应用程序

请注意,localhost:8080/ui 的浏览器中仅显示“Greeting”一词,并且没有 id 和内容。此外,firefox 开发者工具会显示 404 错误,例如 http://localhost:8080/js/hello.js 等资源应该是 http://localhost:8080/ui/js/hello.js

但是,当我在浏览器中键入 localhost:8081 时,我得到了 css 样式的“问候语”,后跟“ID 是”和“内容是”,但没有来自资源服务器的动态内容。 localhost:8081 请求的 Firefox 开发人员工具为 http://localhost:8081/resource/ 提供 404。

请注意,要测试对上述内容的任何更改,您只需在相应的控制台中输入 control C,然后输入 kill $(lsof -t -i:8080) 或 8081 或 9000,然后输入 mvn spring-boot:run

那么我对上面的代码进行了哪些更改以获取通过网关加载的 id 和问候语?

【问题讨论】:

    标签: java angularjs spring spring-mvc spring-boot


    【解决方案1】:

    您的 html 页面中似乎存在问题。您应该确保链接是正确的。 Zuul 本质上所做的是将 url 从网关映射到后端。要使您的示例正常工作,您必须将 Angular 应用程序中的 url 更改为 /resource/resource 或将资源应用程序中的控制器更改为 /。还要确保您的所有应用程序都具有 spring-boot-starter-security 作为依赖项,以允许共享 sec 上下文。或者完全禁用安全性以首先调试您的问题。

    【讨论】:

    • 上面的代码明确指出src=js/... 而不是src=/js/...。我对你的理解正确吗?
    • 嗯,是的,但您的帖子也读起来像您复制了操作指南。只是想确定一下。因为当您的 html 正确加载打开 /ui/ 并尝试加载 /js/ 时,它在我看来就像绝对链接。
    • 我在执行过程中仔细记录了每个步骤,然后我在 OP 中发布了我的实际步骤,以便任何人都可以重现我所采取的步骤。根据我在 OP 中记录的实际步骤,您是否有具体建议?
    • 将其更改为 ui/js/... 获取要加载的 css、id 标签和问候标签。但是仍然没有从资源服务器加载数据。此外,这似乎是一个 jerry-rig 解决方案。我们如何为包含文件设置应用程序上下文,以便我们将 ui 应用程序的 url 移动到不同的名称时代码不会中断?
    • 您可以通过属性中的server.contextPath 轻松设置上下文,或者在将服务器作为环境变量或参数启动时设置上下文。这也是我建议尝试的事情。
    猜你喜欢
    • 2018-12-03
    • 2014-01-07
    • 2022-10-23
    • 2018-09-04
    • 1970-01-01
    • 2021-03-13
    • 2022-01-05
    • 2016-01-09
    相关资源
    最近更新 更多