Odd behavior with URL encoded string when used with RestTemplate.delete() - java

I have a Java Spring Boot application (Java 8 JDK) that makes calls to a REST service. For the delete resource case, I need to specify the path as follows: /api/v4/projects/<URL encoded project path>, where the project path is typically represented as a parent "group" followed by the project name. For example: my-group/my-project. So, when I invoke the delete case, the example path needs to be my-group%2Fmy-project.
I am using java.net.URLEncoder.encode(value, StandardCharsets.UTF_8.toString()) to do the encoding and it converts the example path to what it needs to be (the group is test and the project is test-cold-storage):
https://<removed>/api/v4/projects/test%2Ftest-cold-storage
When I invoke the call, however, it fails. I have an interceptor that prints out the details of the request being made. It's showing something unexpected.
2022-07-18 15:49:18.030 INFO 21888 --- [ main] c.b.d.c.c.CustomRequestInterceptor : Request:
2022-07-18 15:49:18.030 INFO 21888 --- [ main] c.b.d.c.c.CustomRequestInterceptor : URI: https://<removed>/api/v4/projects/test%252Ftest-cold-storage
2022-07-18 15:49:18.030 INFO 21888 --- [ main] c.b.d.c.c.CustomRequestInterceptor : Method: DELETE
It looks like it's being encoded again (maybe?). 0x25 = '%' and 0x2F = '/'. If I do it without encoding the group/path, no encoding occurs and it fails again.
2022-07-19 07:47:02.146 INFO 5200 --- [ main] c.b.d.c.c.CustomRequestInterceptor : Request:
2022-07-19 07:47:02.147 INFO 5200 --- [ main] c.b.d.c.c.CustomRequestInterceptor : URI: https://<removed>/api/v4/projects/test/test-cold-storage
2022-07-19 07:47:02.147 INFO 5200 --- [ main] c.b.d.c.c.CustomRequestInterceptor : Method: DELETE
Has anyone else run into this? Is there some setting in the configuration of the RestTemplate object that affects this?
UPDATE
I have managed to trace execution in the debugger and found that it is encoding the URL. This is happening in org.springframework.web.util.DefaultUriBuilderFactory.createURI().
I don't know if this information is helpful.

Figured it out. I needed to pass the project path (i.e. test/test-cold-storage) as a URI variable instead of tacking it on the end of the URL. The endpoint URL need to change as follows:
String endpointURL = baseURL + GITLAB_REST_API + "projects/{path}";
and the delete call changed to add URI variable (projectPath):
template.delete(endpointURL, projectPath);, where in this example projectPath is test/test-cold-storage.

Related

Spring Webflux doOnCancel is not invoked when an app is deployed to Kubernetes

I have a controller with an endpoint that provide a flux like this reported below.
When the app is deployed to kubernetes, methods doOnCancel and doOnTerminate are not invoked.
Locally instead, it works like a charm (when the tab of the browser is closed as instance).
#Slf4j
#RestController
public class TestController {
...
#GetMapping(value = "/test", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> testStream() {
log.info("Requested test streaming");
return mySink.asFlux()
.startWith("INIT TEST")
.doOnCancel(() -> log.info("On cancel"))
.doOnTerminate(() -> log.info("On terminate"));
}
...
}
2022-08-06 18:25:42.115 INFO 3685 --- [ main] com.wuase.sinkdemo.SinkDemoApplication : Starting SinkDemoApplication using Java 1.8.0_252 on aniello-pc with PID 3685 (/home/pc/eclipse-workspace/sink-demo/target/classes started by pc in /home/pc/eclipse-workspace/sink-demo)
2022-08-06 18:25:42.124 INFO 3685 --- [ main] com.wuase.sinkdemo.SinkDemoApplication : No active profile set, falling back to 1 default profile: "default"
2022-08-06 18:25:44.985 INFO 3685 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port 8080
2022-08-06 18:25:45.018 INFO 3685 --- [ main] com.wuase.sinkdemo.SinkDemoApplication : Started SinkDemoApplication in 3.737 seconds (JVM running for 5.36)
2022-08-06 18:26:09.706 INFO 3685 --- [or-http-epoll-3] com.wuase.sinkdemo.TestController : Requested test streaming
2022-08-06 18:26:14.799 INFO 3685 --- [or-http-epoll-3] com.wuase.sinkdemo.TestController : On cancel
Has anyone encountred the same problem?
Any idea about that?

Not starting the JMS listener using jmsListenerEndpointRegistry.start()

I am trying to start the JMS listener using jmsListenerEndpointRegistry.start() which was stopped using jmsListenerEndpointRegistry.stop(). But looks like it is not getting started. When I am trying to consume the messages it is not allowing me to do so as it is still stopped. Please help me how to start it back using start method.
In application.properties I have spring.jms.listener.auto-startup=true
Using Apache ActiveMQ(Version-5.16.3)
2022-01-06 16:27:54.699 INFO 28804 --- [nio-9091-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 22 ms
2022-01-06 16:27:54.726 ERROR 28804 --- [nio-9091-exec-1] com.jms.poc.controller.JmsController : --------- Trying to start JMS using jmsListenerEndpointRegistry.start()----------
2022-01-06 16:27:54.727 ERROR 28804 --- [nio-9091-exec-1] com.jms.poc.controller.JmsController : ----------jmsListenerEndpointRegistry.isRunning()-------- : false
There is no need to change the autoStartup property in startJmsListener - that property only applies when the application context is initialized.
You have no #JmsListeneners - the only one is commented out.
registry.isRunning() only returns true when at least one of its containers is running.

"Unauthorized: Full authentication is required to access this resource" when booting up the app

This is a bit annoying since I've solved the original problem (which was this) but now this is another thing that I can't quite debug myself.
I am using JHispter 6.10 (Spring Boot 2.2.7.RELEASE) + React for my project. I've recently come to the need of using entities as catalogues (so they can be managed easily by an admin) and they need to be used on the register page. My first problem was that they wouldn't the dropdown in the register page, but that problem had to do with SecurityConfiguration.java, so I added the entities to be permitted to All:
.antMatchers("/api/comunidad-famdals").permitAll()
.antMatchers("/api/ciudads").permitAll()
.antMatchers("/api/estados").permitAll()
.antMatchers("/api/ladrillo-famdals").permitAll()
.antMatchers("/api/pais").permitAll()
.antMatchers("/api/**").authenticated()
And that seems to work just fine, but the first time I load the app (in dev mode), it throws the next error:
2020-10-09 02:03:33.337 DEBUG 63312 --- [ XNIO-1 task-9] c.f.m.r.CustomAuditEventRepository : Enter: add() with argument[s] = [AuditEvent [timestamp=2020-10-09T07:03:33.302498Z, principal=anonymousUser, type=AUTHORIZATION_FAILURE, data={details=org.springframework.security.web.authentication.WebAuthenticationDetails#b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null, type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]]
2020-10-09 02:03:33.342 DEBUG 63312 --- [ XNIO-1 task-9] c.f.m.r.CustomAuditEventRepository : Exit: add() with result = null
2020-10-09 02:03:33.473 WARN 63312 --- [ XNIO-1 task-9] o.z.problem.spring.common.AdviceTraits : Unauthorized: Full authentication is required to access this resource
2020-10-09 02:03:33.564 WARN 63312 --- [ XNIO-1 task-9] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.security.authentication.InsufficientAuthenticationException: Full authentication is required to access this resource]
And when trying to register, the dropdown still doesn't show anything:
But if I go home once again, the terminal shows that all the queries have been done correctly, and sure enough, if I go back to the register page:
I would like to know if I am missing something on my SecurityConfiguration.java or if the order of the configuration needs to be different for it to work properly.
you have to give permissions to your endpoint in the Spring Boot Configuration (SecurityConfiguration.java)
add a new antMatchers parameter to the HttpSecurity.authorizeRequests() it should look like this:
http
.authorizeRequests()
.antMatchers("/api/yourEndpoint").permitAll()
of course you have to select who has authority to call this endpoint
Hope it works for you :)

BeanCreationException: Error creating bean with name 'flywayInitializer'

I am trying to run my project tests in a docker container. All of the tests work just fine when running locally. Errors started occurring when I tried to move my testing to docker container.
Here is the error message:
java.lang.IllegalStateException: Failed to load ApplicationContext
[...]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.internal.command.DbMigrate$FlywayMigrateException:
Migration V1__initial_user.sql failed
-------------------------------------
SQL State : 42601
Error Code : 0
Message : ERROR: syntax error at or near "GENERATED"
Position: 45
Location : db/migration/V1__initial_user.sql (/Users/villemossip/Desktop/GRP/GRP-SAS/application/build/resources/main/db/migration/V1__initial_user.sql)
Line : 36
Statement : CREATE TABLE revinfo
(
rev INTEGER GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ),
revtstmp BIGINT,
PRIMARY KEY (rev)
)
From the log we can see that container image was created, but it fails to migrate the sql schema:
[...]
2019-10-10 10:36:18.768 INFO 49547 --- [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 5.2.4 by Boxfuse
2019-10-10 10:36:18.777 INFO 49547 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2019-10-10 10:36:18.795 INFO 49547 --- [ main] 🐳 [postgres:9.6.12] : Creating container for image: postgres:9.6.12
2019-10-10 10:36:19.001 INFO 49547 --- [ main] 🐳 [postgres:9.6.12] : Starting container with ID: a32dd0850baf34770cce9bdc81918cd4db40502188b85dfaa90f74e2900f9fa7
2019-10-10 10:36:19.547 INFO 49547 --- [ main] 🐳 [postgres:9.6.12] : Container postgres:9.6.12 is starting: a32dd0850baf34770cce9bdc81918cd4db40502188b85dfaa90f74e2900f9fa7
2019-10-10 10:36:23.342 INFO 49547 --- [ main] 🐳 [postgres:9.6.12] : Container postgres:9.6.12 started
2019-10-10 10:36:23.426 INFO 49547 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2019-10-10 10:36:23.431 INFO 49547 --- [ main] o.f.c.internal.database.DatabaseFactory : Database: jdbc:postgresql://localhost:32834/test (PostgreSQL 9.6)
2019-10-10 10:36:23.488 INFO 49547 --- [ main] o.f.core.internal.command.DbValidate : Successfully validated 6 migrations (execution time 00:00.024s)
2019-10-10 10:36:23.501 INFO 49547 --- [ main] o.f.c.i.s.JdbcTableSchemaHistory : Creating Schema History table: "public"."flyway_schema_history"
2019-10-10 10:36:23.519 INFO 49547 --- [ main] o.f.core.internal.command.DbMigrate : Current version of schema "public": << Empty Schema >>
2019-10-10 10:36:23.520 INFO 49547 --- [ main] o.f.core.internal.command.DbMigrate : Migrating schema "public" to version 1 - initial user
2019-10-10 10:36:23.542 ERROR 49547 --- [ main] o.f.core.internal.command.DbMigrate : Migration of schema "public" to version 1 - initial user failed! Changes successfully rolled back.
2019-10-10 10:36:23.546 WARN 49547 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.internal.command.DbMigrate$FlywayMigrateException:
Migration V1__initial_user.sql failed
-------------------------------------
[...]
Here is part of the sql script (app/src/main/resources/db/migration):
[...]
constraint user_aud_pkey primary key (id, rev)
);
CREATE TABLE revinfo
(
rev INTEGER GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ),
revtstmp BIGINT,
PRIMARY KEY (rev)
);
CREATE SEQUENCE hibernate_sequence INCREMENT 1 MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
Here is "application.properties" (app/test/java/resources):
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.url=jdbc:tc:postgresql://localhost:5433/test
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=validate
spring.jackson.default-property-inclusion=NON_NULL
spring.flyway.baselineOnMigrate=true
spring.flyway.check-location=true
spring.flyway.locations=classpath:db/migration
spring.flyway.schemas=public
spring.flyway.enabled=true
Also in the same directory I have container-license-acceptance.txt file.
Inside "build.gradle" I added the following lines (app/build.gradle):
dependencies {
[...]
testImplementation "org.testcontainers:junit-jupiter:1.11.3"
testImplementation "org.testcontainers:postgresql:1.11.3"
}
Inside BaseInitTest file, I have the following lines (app/test/java/com):
#Testcontainers
#SpringBootTest
public class BaseIntTest {
#Container
private static final PostgreSQLContainer<?> container = new PostgreSQLContainer<>();
[...]
I don't understand, how can the same tests pass at first, but fail when I move them to docker container?
It looks like the test container with the database has started successfully, so no issue there, you're getting an empty database.
Then you try running the flyway and this fails.
Flyway in spring boot works during the initialization of the spring application context,
so the actual migration runs while the application context gets initialized, so the migration failure looks like a spring failure.
The reason, however, is logged: the migration file has an invalid content:
Migration V1__initial_user.sql failed
-------------------------------------
SQL State : 42601
Error Code : 0
Message : ERROR: syntax error at or near "GENERATED"
Position: 45
Location : db/migration/V1__initial_user.sql (/Users/villemossip/Desktop/GRP/GRP-
SAS/application/build/resources/main/db/migration/V1__initial_user.sql)
Line : 36
Statement : CREATE TABLE revinfo
(
rev INTEGER GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ),
revtstmp BIGINT,
PRIMARY KEY (rev)
)
This GENERATED BY is unsupported.
Why? Probably your docker image includes the version of RDBMS that doesn't support this syntax. So it differs from the DB that you use in a local environment without docker.
In any case it's not about docker, spring or flyway but about the DB and the migration code.
In terms of resolution, I suggest running the docker image of the DB directly (without java, testcontainers and flyway).
When it runs, just run this migration "manually" in pgadmin or something. You're expected to see the same error.
Thank you #M. Deinum and Mark Bramnik!
I found out that the issue is with Postgres version. For some reason by default docker image is created with old version 9.6.12, but sql script GENERATED BY DEFAULT was added to Postgres with version 10.
Solution 1 (Update the sql script to older version):
CREATE TABLE revinfo
(
rev INTEGER PRIMARY KEY NOT NULL,
revtstmp BIGINT
);
Solution 2:
Changed docker image version to 11.2 by creating CustomPostgreSQLContainer file in the project.
import org.testcontainers.containers.PostgreSQLContainer;
public class CustomPostgreSQLContainer extends PostgreSQLContainer<CustomPostgreSQLContainer> {
private static final String IMAGE_VERSION = "postgres:11.2";
private static CustomPostgreSQLContainer container;
CustomPostgreSQLContainer() {
super(IMAGE_VERSION);
}
public static CustomPostgreSQLContainer getInstance() {
if (container == null) {
container = new CustomPostgreSQLContainer();
}
return container;
}
#Override
public void start() {
super.start();
System.setProperty("spring.datasource.url", container.getJdbcUrl());
System.setProperty("spring.datasource.username", container.getUsername());
System.setProperty("spring.datasource.password", container.getPassword());
}
#Override
public void stop() {
//do nothing, JVM handles shut down
}
}
And updating BaseIntTest file:
#Testcontainers
#SpringBootTest
public class BaseIntTest {
#Container
private static final PostgreSQLContainer<?> container = CustomPostgreSQLContainer.getInstance();
And last removing two lines from test application.properties file:
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.url=jdbc:tc:postgresql://localhost:5433/test
In my case I added in my application.properties file
spring.flyway.baselineOnMigrate = true
and I had also to start from version 1.1 instead of 1 otherwise flyway throws an error (flyway 8.0.5)
The problem in my case was because of using spring.datasource.url=jdbc:postgres://localhost:5432/todoListDb
instead of
spring.datasource.url=jdbc:postgresql://localhost:5432/todoListDb
(postgres instead of PostgreSQL) in my application.properties file
So try to use the right URL for your database and verify if there is a typo in your url
One reason for this issue was missing docker DB version: <embedded-database-spring-test.version>2.0.1</embedded-database-spring-test.version>
By adding this specific version, it worked for me.
As mentioned GENERATED BY DEFAUL needs a newer version of postgres image. In your case the postgres image defaults to 9.6.12.
Simple solution is to just update the datasource url in application.properties and point to a newer postgres image there.
spring.datasource.url=jdbc:tc:postgresql:11.2://localhost:5433/test

Spring Boot React in separate packages

I have a spring boot, java 8 API that I wanted to add a React front end to to make API operations easier to navigate and use. I used JHipster generator to generate a React app. Then I just took the web portion and dropped into my app, however whenever I run the Spring Boot application and try to navigate to port :8080 it, I get the following page:
And the following error in the console:
2019-07-15 15:07:21.414 INFO 29145 --- [)-10.15.114.229] o.a.c.c.C.[.[.[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-07-15 15:07:21.414 INFO 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-07-15 15:07:21.414 DEBUG 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet : Detected StandardServletMultipartResolver
2019-07-15 15:07:21.426 DEBUG 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2019-07-15 15:07:21.426 INFO 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet : Completed initialization in 12 ms
2019-07-15 15:07:25.079 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : GET "/", parameters={}
2019-07-15 15:07:25.093 DEBUG 29145 --- [nio-8080-exec-1] s.d.s.w.PropertySourcedRequestMappingHandlerMapping : looking up handler for path: /
2019-07-15 15:07:25.128 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.h.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-07-15 15:07:25.130 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-07-15 15:07:25.131 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : Completed 404 NOT_FOUND
2019-07-15 15:07:25.152 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters={}
2019-07-15 15:07:25.153 DEBUG 29145 --- [nio-8080-exec-1] s.d.s.w.PropertySourcedRequestMappingHandlerMapping : looking up handler for path: /error
2019-07-15 15:07:25.167 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2019-07-15 15:07:25.199 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2019-07-15 15:07:25.208 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
Here is my project structure:
FooApplication
├── build.gradle
├── api/
├── src.main.java.com.foo/
├── FooApplication.java
└── build.gradle
├── web/
├── node_modules/
├── src.main.webapp/
├── app/
├── index.tsx
├── routes.tsx
└── app.tsx
└── index.html
├── webpack/
└── webpack.common.js
└── build.gradle
Here my webpack.common.js file:
const webpack = require('webpack');
const {BaseHrefWebpackPlugin} = require('base-href-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const path = require('path');
const utils = require('./utils.js');
const getTsLoaderRule = env => {
const rules = [
{
loader: 'cache-loader',
options: {
cacheDirectory: path.resolve('build/cache-loader')
}
},
{
loader: 'thread-loader',
options: {
// There should be 1 cpu for the fork-ts-checker-webpack-plugin.
// The value may need to be adjusted (e.g. to 1) in some CI environments,
// as cpus() may report more cores than what are available to the build.
workers: require('os').cpus().length - 1
}
},
{
loader: 'ts-loader',
options: {
transpileOnly: true,
happyPackMode: true
}
}
];
if (env === 'development') {
rules.unshift({
loader: 'react-hot-loader/webpack'
});
}
return rules;
};
module.exports = options => ({
cache: options.env !== 'production',
resolve: {
extensions: [
'.js', '.jsx', '.ts', '.tsx', '.json'
],
modules: ['node_modules'],
alias: {
app: utils.root('src/main/webapp/app/')
}
},
module: {
rules: [
{
test: /\.tsx?$/,
use: getTsLoaderRule(options.env),
include: [utils.root('./src/main/webapp/app')],
exclude: [utils.root('node_modules')]
},
{
test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
loader: 'file-loader',
options: {
digest: 'hex',
hash: 'sha512',
name: 'content/[hash].[ext]'
}
},
{
enforce: 'pre',
test: /\.jsx?$/,
loader: 'source-map-loader'
},
{
test: /\.tsx?$/,
enforce: 'pre',
loader: 'tslint-loader',
exclude: [utils.root('node_modules')]
}
]
},
stats: {
children: false
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: `'${options.env}'`,
VERSION: `'${utils.parseVersion()}'`,
DEBUG_INFO_ENABLED: options.env === 'development',
// The root URL for API calls, ending with a '/' - for example: `"https://www.jhipster.tech:8081/myservice/"`.
// If this URL is left empty (""), then it will be relative to the current context.
// If you use an API server, in `prod` mode, you will need to enable CORS
// (see the `jhipster.cors` common JHipster property in the `application-*.yml` configurations)
SERVER_API_URL: `''`
}
}),
new ForkTsCheckerWebpackPlugin({tslint: true}),
new CopyWebpackPlugin([
{from: './node_modules/swagger-ui/dist/css', to: 'swagger-ui/dist/css'},
{from: './node_modules/swagger-ui/dist/lib', to: 'swagger-ui/dist/lib'},
{from: './node_modules/swagger-ui/dist/swagger-ui.min.js', to: 'swagger-ui/dist/swagger-ui.min.js'},
{from: './src/main/webapp//swagger-ui/', to: 'swagger-ui'},
{from: './src/main/webapp/static/', to: 'content'},
{from: './src/main/webapp/favicon.ico', to: 'favicon.ico'},
{from: './src/main/webapp/manifest.webapp', to: 'manifest.webapp'},
// jhipster-needle-add-assets-to-webpack - JHipster will add/remove third-party resources in this array
{from: './src/main/webapp/robots.txt', to: 'robots.txt'}
]),
new HtmlWebpackPlugin({
template: './src/main/webapp/index.html',
chunksSortMode: 'dependency',
inject: 'body'
}),
new BaseHrefWebpackPlugin({baseHref: '/'}),
]
});
How do I get spring boot to serve up the index.html file when navigating to localhost:8080? I know I'm going to have to override some default spring boot configurations to get this to work but I'm not clear on what configurations.
I can provide details of any more files upon request, just didn't want to overload the post with unnecessary info.
Request mapping for your application's entry point, read the file, and return the content. In my case, the React code is stored at /tmp/build/index.html. Simplified and ignoring errors, it might look something like this:
#RequestMapping(
value = "",
method = RequestMethod.GET)
public ResponseEntity<String> getIndexContent() {
final File file = new File("/tmp/build/index.html");
final String content =
FileUtils.readFileToString(
file,
StandardCharsets.UTF_8);
return ResponseEntity
.ok()
.contentType(MediaType.TEXT_HTML)
.body(content);
}
Spring-boot auto-configures some paths by default as static resource locations: /static, /public or /resources. See the Official Spring Docs
So if you can move your index.html and dependent assets into the static resource paths, Spring Boot should serve them as-is.
Alternatively, as those same docs say, you could add new paths as a static locations by setting the spring.resources.static-locations property.
A nice thing to do would be to build your React application, bundling the resources, and copying the bundled assets + index.html to the Spring project's static location.
You haven't mentioned anything about your build setup, if you're using the Gradle Node Plugin with Webpack, then this shouldn't be hard. This blog post shows how you'd do that (however, not using multiple modules)

Categories

Resources