Spring boot - image upload failed - file

Im working on uploading images with spring but I get error when I try save file in one of my projects folder.
Errors:
java.nio.file.NoSuchFileException: \resources\images\photo001.png
There was an unexpected error (type=Internal Server Error, status=500).
\resources\images\photo001.png
I have this path:
String path = "\\resources\\images\\";
String path2 = "c:\\temp\\";
Path2 works but I would like to save my files in project without passing whole path starting from C:...
What pass should I pass to save it in resources/images in my project?
My project looks like that:
https://i.imgur.com/Dn6wXAK.png

Try 'images/'
All files in src/main/resources are copied into classes/ so in your jar or war there is no folder /resources.
You also should not use the windows specific backslash '\' instead use the
Use /images/ instead this makes your build portable so it can run on Linux also.

Senio, if you are using Spring Boot then there is a project called Spring Content that will allow you to create an image store in very few lines of code.
All you would need to do is add the following Spring Content dependencies (assuming maven):-
<dependencies>
<!-- Standard Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
</dependency>
<!-- Spring Content -->
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-fs-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.0.10</version>
</dependency>
</dependencies>
In your Spring Boot Application class, create an ImageStore interface. Annotate it as a REST resource. This causes Spring Content to inject an implementation (of this interface for the filesystem) as well as REST endpoints saving you from having to write any this code yourself:-
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#StoreRestResource(path="images")
public interface ImageStore extends Store<String> {}
}
By default Spring Content FS will create a store under java.io.tmpdir. So you will also need to set the SPRING_CONTENT_FS_FILESYSTEM_ROOT environment variable to point to the root of your "store"; c:\temp\resources\images.
Start the application and you will be able to upload images by POSTing (or PUTting) to:-
/images/some/path/image-1.jpg
(This also supports GET (download) and DELETE.)
You'll find uploaded images under c:\temp\resources\images\some\path\image-1.jpg
HTH

Related

spring authentication using react.js sends gibberish response

I have a application in react.js and it's server is in spring boot.
Now I want to implement OAuth2 for user authentication. If user is authenticated, then app can get response from the server.
In my application.properties I have added these:
spring.security.oauth2.client.registration.github.client-id=somekey
spring.security.oauth2.client.registration.github.client-secret=somekeyhere`
In pom.xml I have added these:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
I have create WebSecurityConfiguration like this:
#Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.oauth2Login();
}
}
When I try to get any requests like /user in browser it redirects me to login or to create account and everything works fine.
But the problem is I can't use the react.js application anymore, so how can I make the authentication in client portion?

Deploying Spring Boot WAR to Tomcat 8 - HTTP 404 when accessing resources

I'm new to Spring Boot and struggling to deploy a simple HTML web app (AngularJS) to Tomcat 8. This web app simply serves some HTML/CSS/JS content with no REST calls to a backend. It has been "compiled" using Webpack -- this produces JS/CSS bundles and a single index.html file that points to them via <script> / <link> tags -- and has been tested on ExpressJS and Spring Boot w/ Embedded tomcat and works as expected. But going down the path of a stand-alone WAR and deploying to Tomcat 8 does not seem to work properly.
For the Spring Boot project, I've included all the HTML/CSS/JS files in the src/main/resources/public folder (no subfolders) and have also configured the pom.xml as follows (basic config):
<?xml version="1.0" encoding="UTF-8"?>
<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>com.example.my-app</groupId>
<artifactId>my-app</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<name>my-app</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
"Main" class:
package com.example.my.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
#SpringBootApplication
public class MyAppApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyAppApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MyAppApplication.class, args);
}
}
Here are the steps I used to do the Tomcat deployment:
mvn clean package to generate the WAR
Copy the WAR to path/to/tomcat8/webapp
Start Tomcat
http://localhost:8080/my-app => auto-loads index.html
Unfortunately all I see are 404 errors because it couldn't find some JS/CSS file. Is there a config I'm missing?
Updated:
Here is the index.html file (auto-generated via Webpack):
<!doctype html>
<html>
<head>
<base href="/">
<meta charset="utf-8">
<title>My App</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="icon" type="image/png" href="./assets/images/favicon.ico" />
<link href="/main-aa49893f83cc830596563d81f09a9611.css" rel="stylesheet"><link href="/main-5949f1f257a55a77e48bc4ab62fbc99a.css" rel="stylesheet"></head>
<body ng-app="myapp">
<ui-view></ui-view>
<script type="text/javascript" src="vendor-353ddb48f4ffe6546d59.js"></script><script type="text/javascript" src="app-353ddb48f4ffe6546d59.js"></script></body>
</html>
Here are the errors I'm seeing in Chrome Web Inspector when visiting localhost:8080/my-app/index.html:
http://localhost:8080/main-5949f1f257a55a77e48bc4ab62fbc99a.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-aa49893f83cc830596563d81f09a9611.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/vendor-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/app-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/vendor-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/app-4ba9083ed9802279c207.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-aa49893f83cc830596563d81f09a9611.css Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:8080/main-5949f1f257a55a77e48bc4ab62fbc99a.css Failed to load resource: the server responded with a status of 404 (Not Found)
One more thing I forgot to mention. When I generate the war using mvn clean package, all the files that are under src/main/resources/public are placed into the WEB-INF/classes/resource subfolder. According to research, these files are not publicly visible (i.e. if I try to access localhost:8080/my-app/foo.css, it'll give 404). Is this why the index.html file is unable to "see" the JS/CSS files it depends on?
I ended up figuring it out but not using Spring Boot to package the WAR file. There was another project lying around on my local that used plain old Maven + pom.xml + web.xml to create WARs, which I used as a reference to figure out why the current project was not working. There were multiple issues:
When you deploy onto Tomcat 8 using default config, it will append the name of the WAR file (what they refer to as Context) to its path. In this case, it was http://localhost:8080/my-app. The "compiled" AngularJS app's index.html had a <base href="/"> tag that needed to point to /my-app/ instead of /. This was the main reason why the JS/CSS files were not visible in Web Inspector > Sources.
<link> tag's src attribute was not supposed to contain a leading /
In the case of the Spring Boot App I posted above, it comes with an Embedded Tomcat and deploys the app at the Root Context so there's no need to change any paths in the index.html file.
Similar to Spring Boot, I also had no issues running the app in ExpressJS since a "sub-context" was not created. Again, there was no need to modify any files in this case.
There were other errors related to finding resources like .ttf files but at least the app was able to run.
Update:
Looks like its possible to serve the WAR file from the Tomcat 8 root by adding the following near the bottom of the server.xml file:
<Context path="" docBase="my-app" debug="0" reloadable="true"></Context>
This will prevent the need to modify the index.html file.
Awesome :)
The most common issue with the setup you have described, without more context, is that you are most likely using absolute URLs to point at your js / css files. As such when you put them into the servlet container under /my-app they no longer reference properly as they are trying to go to the root /. You need to use relative URLs when describing the location of the resource files on the path.
I had the same problem, and it is related to Webpack more than to Spring-boot.
In your webpack.common.js / webpack.prod.js you have to set :
metada.baseUrl = './';
and inject this in your <base> link in index.html
And you also have to set
output.publicPath: './'
With both variable set, this worked for me.
Uhmm i've tried some of this on my spring-boot project.
First i'd add a dependency on my project pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
then i'd add an index.html on src/main/resources/templates
after that you should add a controller to point to that index
#Controller
public class AppController {
#RequestMapping("/")
String index() {
return "index";
}
}
For more information see this guide. Spring-boot and Thymeleaf

Hosting angular JS / HTML 5 web app on google app engine?

I am looking at Hosting angular JS / HTML 5 web app on google app engine as a single page app. All my services are also on google app engine within the same project.
I have generated the basic directory structure for angularJS using yeoman generator.
Just created a directory under the /war/ folder of app engine project and placed the angular code in that.
EVERYTHING IS WORKING FINE !!!
Then Question ?
Is this the right way to place a HTML page directly in the WAR folder of an App engine ? Or should I be placing HTML files under the SRC folder of an app engine project and pull them into war during deploy time ?
Lets say million users try to access this single page web app, will such a hosting model help in scaling up ? Will app engine create more instances to serve this page.html ?
Note: I am 'NOT' using anything GWT for UI. Its just a single page app under a war folder !
Appreciate your inputs.
Srik
I believe this is entirely up to your preferences. I put my angular apps in /src/main/node and copy the output of grunt during maven package phase like so:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<archiveClasses>true</archiveClasses>
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
<resource>
<directory>${basedir}/src/main/node/dist</directory>
<filtering>false</filtering>
<targetPath>/</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
While this seems the cleanest solution for me, you may not feel the same way. It really doesn't matter how your static content gets into your war as long as it does.
There will be no instances for this. Static content (like html, js, css files) are served through Google's static content proxy, which is a content delivery network. So yes it will scale but you don't need instances for static content.

camel component 'velocity' not found

I implement *.vm template in my routing application (Servicemix)
but after deploying JAR archive I get this error
karaf#root> Exception in thread "SpringOsgiExtenderThread-38" org.apache.camel.RuntimeCamelException: org.apache.camel.FailedToCreateRouteException:
Failed to create route route14 at: >>> To[velocity:getPayments.vm] <<< in route: Route(route14)[[From[direct:start]] -> [To[velocity:getPayme...
because of Failed to resolve endpoint: velocity://getPayments.vm due to:
No component found with scheme: velocity
I followed this manual
http://camel.apache.org/tutorial-example-reportincident-part4.html
and pointed camel-velocity in pom.xml with same camel-core version
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.13.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-velocity</artifactId>
<version>2.13.1</version>
</dependency>
Does anybody know, what the matter is ?
As you are using Karaf you need to add the velocity feature:
feature:install camel-velocity
Or if using Karaf 4.x
feature:install camel-velocity
nothing changed even after ServiceMix restarting, but I found solution.
after init-ing of CamelContext I add camel components manually.
import org.apache.camel.component.velocity.*;
import org.apache.camel.component.spring.ws.*;
....
private CamelContext camel;
.....
camel = new DefaultCamelContext();
camel.addComponent("velocity", new VelocityComponent());
camel.addComponent("spring-ws",new SpringWebserviceComponent());

Can DropWizard serve assets from outside the jar file?

In looking at the documentation, it appears that DropWizard is only able to serve static content living in src/main/resources. I'd like to keep my static files in a separate directory outside the jar file. Is that possible? Or do most people use nginx/Apache for their static content?
yes, it can, using this plugin - https://github.com/bazaarvoice/dropwizard-configurable-assets-bundle
Working off of Marcello Nuccio's answer, it still took me the better part of my day to get it right, so here is what I did in a bit more detail.
Let's say I have this directory structure:
my-dropwizard-server.jar
staticdocs
assets
image.png
Then this is what you have to do to make it work:
1) In your dropwizard Application class, add a new AssetsBundle. If you want your assets to be served from a different URL, change the second parameter.
#Override
public void initialize(Bootstrap<AppConfiguration> bootstrap) {
bootstrap.addBundle(new AssetsBundle("/assets/", "/assets/"));
}
2) Add the document root to your classpath by configuring the maven-jar-plugin like this. (Getting the "./staticdocs/" in the correct form took me a while. Classpaths are unforgiving.)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>./staticdocs/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
3) This step is entirely optional. If you want to serve your Jersey REST Resources from a different root path (e.g. "app"), add the following to your configuration YML:
server:
rootPath: /app/*
Now you can access your static content like this, for example:
localhost:8080/assets/image.png
The user manual says:
use an extended AssetsBundle constructor to serve resources in the assets folder from the root path.
i.e. the files are loaded as resources from the classpath. Then you only need to properly set the classpath for the service.
With the default configuration, this means that you need to call the document root assets, and put the parent folder of the document root in the classpath. Then, for example, assets/foo.html will be available at
http://localhost:8080/assets/foo.html
There is a upto-date dropwizard-configurable-assets-bundle maintained at official dropwizard-bundles. You can find it at github https://github.com/dropwizard-bundles/dropwizard-configurable-assets-bundle. Current version supports dropwizard 0.9.2
This can be used to serve static files from arbitrary file system path.
The vast majority of websites that serve static content do so through a dedicated webserver, or, at larger scale, a CDN.
Occasionally, you might want to deploy an application as a self-contained unit complete with all assets which is where Dropwizard comes in.
It is possible to get Dropwizard to serve up assets from outside the classpath, but the easiest way to do this is to write your own asset endpoint that reads from an externally configured file path.
To complement craddack's answer: Correct, you can use the regular AssetsBundle as long as you add the assets to your classpath.
If you use gradle and oneJar, you can add a directory to the classpath in the oneJar task:
task oneJar(type: OneJar) {
mainClass = '...'
additionalDir = file('...')
manifest {
attributes 'Class-Path': '.. here goes the directory ..'
}
}
see https://github.com/rholder/gradle-one-jar

Resources