java – How to integrate angular with spring boot to see angular web interface on spring boot port?
java – How to integrate angular with spring boot to see angular web interface on spring boot port?
Please open the jar file with an archive utility and see if the static files are available in it. If they are available, you need to tell Spring that the URLs you are entering into the address bar are actually Angular routes:
@Controller
public class Routing {
@RequestMapping({ , /login, /products/** })
public String gui() {
return forward:/index.html;
}
}
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
The parent pom.xml
would be:
<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>
The frontend pom would be:
<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>
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
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>
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 youll 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;
}
}
This will let you to develope and compile all just only by using maven
Angelo