Spring Boot React in separate packages - java

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)

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?

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

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.

Java Spark takes a long time to create a session

I am switching from python pandas to Java Spark for data analytics and new to it. In my project I'm not using hadoop, just fetching data from mysql db.
The code is like this:
List<QtStkDailyRehabilitation> qtStkDailyRehabilitations = qtStkDailyRehabilitationSelfMapper.getStockDailyKData(stockCode);
SparkSession spark = SparkSession.builder().appName("sparkTest").config("spark.master","local")
.getOrCreate();
StructField field1 = DataTypes.createStructField("date", DataTypes.DateType, false);
StructField field2 = DataTypes.createStructField("close", DataTypes.FloatType, false);
StructType stockInfo = DataTypes.createStructType(Lists.newArrayList(field1, field2));
...
So I didn't install a hadoop on my computer. But I found when I create a SparkSession, it takes a long time - around 20 seconds, and it comes out with a warning.
The log shows below:
2020-05-26 18:45:02.507 DEBUG 15880 --- [nio-8031-exec-1] c.e.d.q.d.Q.getStockDailyKData : ==> Preparing: SELECT * FROM qt_stk_daily_rehabilitation WHERE (stock_code='002241') ORDER BY trade_date DESC
2020-05-26 18:45:02.520 DEBUG 15880 --- [nio-8031-exec-1] c.e.d.q.d.Q.getStockDailyKData : ==> Parameters:
2020-05-26 18:45:02.873 DEBUG 15880 --- [nio-8031-exec-1] c.e.d.q.d.Q.getStockDailyKData : <== Total: 2921
2020-05-26 18:45:12.199 INFO 15880 --- [nio-8031-exec-1] org.apache.spark.SparkContext : Running Spark version 2.4.3
2020-05-26 18:45:21.335 WARN 15880 --- [nio-8031-exec-1] org.apache.hadoop.util.NativeCodeLoader : Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
2020-05-26 18:45:21.406 INFO 15880 --- [nio-8031-exec-1] org.apache.spark.SparkContext : Submitted application: sparkTest
2020-05-26 18:45:21.456 INFO 15880 --- [nio-8031-exec-1] org.apache.spark.SecurityManager : Changing view acls to: edz
As you can see. Running Spark version 2.4.3 shows 10s after sql returns results, and then after 9s it prints a warning about hadoop.
Following codes works ok and I can use DataFrame to calculate, but every time I run into this session create code it will take 20s. I guess it tries to access hadoop server which I don't have one. Is it normal and how to make it faster? Or can I disable hadoop for now just to enjoy it's MLlib features?
Thanks.

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

how to fix 'resource not found' when trying to download file in spring boot REST API?

I'm new to spring framework and REST, and now trying to migrate REST from jersey to spring boot 2.1
The controller works fine with jax-rs, however, I don't want to use jax-rs in spring boot. So, I tried spring Mvc and I get 'resource not found' error. Please I'd really appreciate any help.
I tried this
#GetMapping(value ="/generic/download_file/{path:[^\\.+]*}", consumes ="application/vnd.X-FileContent")
public ResponseEntity<?> downloadFile(#PathVariable("path") String filePath){
String actualFilePath = "";
try {
actualFilePath = filePath.replaceAll("\\/", "\\\\");
File file = new File(actualFilePath);
if (file.exists()) {
return ResponseEntity.ok().header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"").body(file);
} else {
return errorHandling.errorResponseFactory("1.0.0", Thread.currentThread().getStackTrace()[1], "",
RecommendedSolution.UseValidDirectoryPath, "File not exist.");
}
} catch (Exception ex) {
ActionLog.writeLog("program_library_v510", "1.0.0", "Exception occur during gettig generic package file",
ActionLogType.DebugLog);
ActionLog.writeLog("program_library_v510", "1.0.0", "Exception occur during getting generic package file",
ActionLogType.ErrorLog);
return errorHandling.errorResponseFactory("1.0.0", Thread.currentThread().getStackTrace()[1], "",
RecommendedSolution.UnexpectedErrorMsg, "");
}
}
2019-01-07 17:17:23.930 INFO 13664 --- [nio-9090-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 10 ms
2019-01-07 17:17:23.947 DEBUG 13664 --- [nio-9090-exec-2] o.s.web.servlet.DispatcherServlet : GET "/packages/download_file/D:/xfolder/test.txt", paramete
rs={}
2019-01-07 17:17:24.002 DEBUG 13664 --- [nio-9090-exec-2] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/
resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2019-01-07 17:17:24.006 DEBUG 13664 --- [nio-9090-exec-2] o.s.w.s.r.ResourceHttpRequestHandler : Resource not found
2019-01-07 17:17:24.007 DEBUG 13664 --- [nio-9090-exec-2] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2019-01-07 17:17:24.015 DEBUG 13664 --- [nio-9090-exec-2] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters={}
2019-01-07 17:17:24.029 DEBUG 13664 --- [nio-9090-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServ
letRequest)
2019-01-07 17:17:24.077 DEBUG 13664 --- [nio-9090-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [/] and supported [applic
ation/json, application/+json, application/json, application/+json]
2019-01-07 17:17:24.078 DEBUG 13664 --- [nio-9090-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Mon Jan 07 17:17:24 SGT 2019, status=40
4, error=Not Found, message=No message available, path=/packages/download_file/D:/xfolder/test.txt}]
2019-01-07 17:17:24.146 DEBUG 13664 --- [nio-9090-exec-2] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
I suspect two things here. Let me clarify this.
What is the API url you are calling?
/generic/download_file/{path:[^\\.+]*} or /packages/download_file/D:/xfolder/test.txt
both are looks different. Please see generic and packages
The better way to pass filenames in URL is using #RequestParam instead of #PathVariable
#GetMapping(value ="/generic/download_file/", consumes ="application/vnd.X-FileContent")
public ResponseEntity downloadFile(#RequestParam("path") String filePath){

Categories

Resources