如何将angular与spring boot集成在一起以查看spring boot port上的angular web界面? [英] How to integrate angular with spring boot to see angular web interface on spring boot port?
问题描述
我有使用spring4开发的后端Spring Boot应用程序和前端.由于这两个在部署时在不同的端口(8080,4200)上运行,因此不会显示任何UI.在本地,使用以下代码启动Angular服务器在localhost:4200上绝对可以正常工作,并显示Web界面:
I have backend spring boot app and front-end developed using angular4. Since these 2 operate on different ports(8080,4200) when deploying, it isn't showing any UI. In local, starting angular server using below works absolutely fine on localhost:4200 and shows web interface:
ng serve --proxy-config proxy.conf.json
其中proxy.conf.json具有内容:
where proxy.conf.json has contents:
{
"*": {
"target": "http://localhost:8080",
"secure": false,
"logLevel": "debug"
}
}
但是在尝试与springboot应用程序(localhost:8080)集成时不可以.可能需要在部署之前先烘焙ng业务逻辑(节点/npm安装等).
But not when trying to integrate with springboot app(localhost:8080). Probably, it requires ng business logic(node/npm install etc.) to be baked before deployment.
所以我用ng build
将生成的文件复制到输出目录-src/main/resources/static,现在它位于spring-boot应用程序路径中.启动tomcat仍在localhost:8080上未显示任何UI.我在chrome标签上确实看到了Angular符号/图标,但是html页面上没有任何显示.
So I used ng build
which copied generated files to a output dir - src/main/resources/static and now it's in spring-boot app path. Starting tomcat still shows no UI on localhost:8080. I do see Angular symbol/icon on chrome tab but nothing shown on html page.
我还添加了一个控制器方法来返回index.html,以便它可以在路径中提供静态文件.
I also added a controller method to return index.html so that it can serve static files in path.
@GetMapping("/")
public String index() {
return "forward:/index.html";
}
但是这样做只会显示"forward:/index.html"字符串,而不是网页上的html内容.
我是否需要更改此index.html中的内容,以便它可以路由到我创建的ng组件?
不知道在index.html中更改选择器是否重要.由于我的主要组件不是应用程序组件(默认情况下是根组件),而是登录组件,因此在index.html中,我将<app-root></app-root>
更改为登录组件的选择器<app-login></app-login>
;在用户界面中仍然没有任何显示.
But doing this just displays "forward:/index.html" string instead of html content on webpage.
Do I need to change something in this index.html so that it can route to ng components that I have created?
Don't know if it matters to change selector in index.html. Since my main component is not app component(which is by default the root component) rather a login component so in index.html I changed <app-root></app-root>
to login component's selector <app-login></app-login>
; still nothing shows up in UI.
好像spring-boot似乎无法理解棱角分明的东西以及如何路由到主要ng组件.
Seems like spring-boot isn't able to understand angular stuff and how to route to main ng components.
下面是index.html:
Below is index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello App</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body>
</html>
项目结构:
-src
-main
-java
- backend
- AppController
- AppService
- Main.java
- frontend
- src
- index.html
- app
-login
- login.component.html
- login.component.css
- login.component.ts
etc..
- resources
- static
- index.html
- application.properties
- ...
部署时如何使前端与后端服务器一起使用?我是否需要在application.properties中添加任何参数或配置,以便应用程序在启动时从/resources提供静态内容?是否添加任何resourceLocationHandler来为其提供服务?
How can I have the frontend work with backend server when deployment? Do I need to add any argument or configuration in application.properties for the app to serve static content from /resources on startup ? Do I add any resourceLocationHandler for serving it?
任何帮助,非常感谢!
推荐答案
您可以使用maven和 frontend-maven-plugin
You can do it by using maven and the frontend-maven-plugin
首先,我完全同意将前端与后端分开
First od all I agree about the fact to have the frontend separated by the backend
因此,我将创建此项目结构:
So i would create this project structure:
parentDirectory
- frontend
- angular src files
- pom.xml
- backend
- spring boot based backend
- pom.xml
- pom.xml
父级pom.xml
为:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>apringangular</artifactId>
<packaging>pom</packaging>
<name>Spring angular</name>
<modules>
<module>backend</module>
<module>frontend</module>
</modules>
</project>
前端pom为:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>test</groupId>
<artifactId>springangular</artifactId>
<version>1.0</version>
</parent>
<artifactId>frontend</artifactId>
<packaging>jar</packaging>
<name>frontend</name>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>frontend_project_properties.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<filesets>
<fileset>
<directory>dist</directory>
<includes>
<include>*</include>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v8.11.3</nodeVersion>
<npmVersion>6.3.0</npmVersion>
<arguments>${http_proxy_config}</arguments>
<arguments>${https_proxy_config}</arguments>
<arguments>run build</arguments>
<npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>${http_proxy_config}</arguments>
<arguments>${https_proxy_config}</arguments>
<arguments>run build</arguments>
<npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
在文件frontend_project_properties.properties
中,我具有节点和npm的代理配置.像这样:
Inside the file frontend_project_properties.properties
I have my proxy configuration for node and npm. Something like this:
http_proxy_config=config set proxy http://USERNAME_PROXY:PASSWORD_PROXY@PROXY_HOST:PROXY_PORT
https_proxy_config=config set https-proxy http://USERNAME_PROXY:PASSWORD_PROXY@PROXY_HOST:PROXY_PORT
后端pom是经典的Spring Boot后端.您必须告诉maven前端在哪里,以便maven能够创建唯一的Web应用程序.在后端pom.xml中,您应该添加以下内容:
The backend pom is a classical spring boot backend. You must tell maven where the frontend is so maven is able in creating a unique webapplication. In the backend pom.xml you should add something like this:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>it.eng.tz.area.vasta.mev</groupId>
<artifactId>appmgr</artifactId>
<version>1.0</version>
</parent>
<artifactId>appmgrbackend</artifactId>
<packaging>war</packaging>
<name>Application manager backend</name>
<description>
Lato backend del sistema di gestione
</description>
<dependencies>
<!-- Your dependencies -->
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<excludes>
<exclude>**/*.*</exclude>
</excludes>
</testResource>
</testResources>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<webResources>
<resource>
<directory>../frontend/dist</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
这样,您可以告诉maven-war-plugin
HTML和静态代码位于前端项目的dist
目录中
请注意,在开发过程中,node.js在4200端口上提供资源,而spring使用其他端口.因此,您将遇到一个跨站点的问题.通过使用spring security,yuo可以通过以下方式配置spring security来解决此问题:
In this way you tell the maven-war-plugin
that the HTML and static code is locate in the dist
directory of frontend project
Note that during the development node.js serves resource on 4200 port while spring uses a different port. So you'll have a cross-site issue. By using spring security yuo can solve this issue bu configuring, in the backend side, spring security in this way:
@Configuration
@EnableWebSecurity
@Import(value= {AppMgrWebMvcConfig.class})
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled=true)
public class AppMgrWebSecConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("oauthUsrDetailSvc")
UserDetailsService userDetailsService;
@Autowired
@Qualifier("userPwdEnc")
private PasswordEncoder pwdEncoder;
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.httpFirewall(this.allowUrlEncodedSlashHttpFirewall());
}
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall()
{
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
firewall.setAllowSemicolon(true);
return firewall;
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService);
auth.authenticationProvider(authenticationProvider());
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationProvider.setPasswordEncoder(pwdEncoder);
return authenticationProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/resources/**")
.permitAll()
.antMatchers("/rest/protected/**")
.access("hasAnyRole('ADMIN','USER','SUPER_ADMIN')")
.and()
.authorizeRequests()
.antMatchers("/rest/public/**")
.permitAll()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.usernameParameter("username")
.passwordParameter("password")
.defaultSuccessUrl("http://localhost:8100/", true)
.failureUrl("/login?error")
.loginProcessingUrl("/login")
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/login?logout")
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.cors().configurationSource(corsConfigurationSource())
.and()
.exceptionHandling()
.accessDeniedPage("/pages/accessDenied");
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200","http://localhost:8080"));
configuration.setAllowedMethods(Arrays.asList("GET","POST", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("x-requested-with"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
这将使您仅使用maven即可开发和编译所有内容
This will let you to develope and compile all just only by using maven
安吉洛
这篇关于如何将angular与spring boot集成在一起以查看spring boot port上的angular web界面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!