spring boot - serving images from folder outside src - java

I have a folder named uploads which is at the same level as src folder. I upload images to this folder.
Then I added the following configuration to be able to serve the images in thymeleaf:
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/uploads/**")
.addResourceLocations("/resources/","/../../uploads/")
.setCachePeriod(0);
}
}
I try to serve the images in Thymeleaf like this:
<img class="img-thumbnail img-responsive" src="#" th:src="#{'/uploads/' + ${photo}}" alt="">
where ${photo} is the name file name.
However I get the following error:
The resource path [/../../uploads/rtf_vtvsq1r12q.png] has been normalized to [null] which is not valid.
Apparently the path in my configuration is wrong. Could somebody please tell me what I'm doing wrong?

There is missing file. Add below configuration:
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/images/**")
.addResourceLocations("file:resources/", "file:uploads/")
.setCachePeriod(0);
}
}
here you get details.

Related

How can I read resources file from outside project directory?

Below code works fine if file location is resources folder but when file location is outside the project directory like(c:\file.json) it fails.
How can we load file from outside project directory.
#Bean
public UserInfo readFile() {
String fileName="prop.json";
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
try {
UserInfo info= new ObjectMapper(new JsonFactory()).readValue(file, UserInfo.class);
} catch (Exception e) {
}
return info;
}
You should create a Configuration class that implements WebMvcConfigurer and
override the addResourceHadndler Method to add new resource to spring context.
#Configuration
#EnableWebMvc
public class MvcConfig implements WebMvcConfigurer{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// register you resource here
}
}

How to dynamically load Spring controllers

I have a Spring Boot application that hosts a REST API.
Depending on which files get deployed, I want to be able to have it load additional controllers from what is essentially a "plugin" JAR file.
For example, I'd love to be able to do something like this:
java -jar myapp.jar -Dplugins.directory=/opt/myapp/plugins
Is this possible?
Note: these would not be loaded on the fly; once deployed, the set of plugins will remain fixed. I want one application jar that remains the same in every deployment, and the behavior of the application will be determined by the plugins that are deployed alongside it.
it may not 100% Satisfy your demand.
I have two suggestion.
the easy one.
java -jar stackoverflow-1.0-SNAPSHOT.jar --spring.profiles.active=prod
and put different value "#Profile" on your controller.
#RestController
#Profile("prod")
public class URLOneController {
#PostMapping(value = "/url", consumes="application/json", produces="application/json")
public ResponseEntity<HttpStatus> insertClaim(#RequestBody String messageBody) {
return new ResponseEntity<>(HttpStatus.OK);
}
}
second suggestion ,dynamic load beanDefiniton.
#Configuration
#ConditionalOnProperty(name="external.controller.enable",havingValue = "true")
public class ExternalClassDefinitionProcessor implements
BeanDefinitionRegistryPostProcessor {
#Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
Class<?> aClass = null;
try {
aClass = contextClassLoader.loadClass("com.jin.learn.demo.UrlOneController");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.genericBeanDefinition(aClass);
beanDefinitionBuilder.addPropertyReference("personDao", "personDao");
BeanDefinition personManagerBeanDefinition = beanDefinitionBuilder
.getRawBeanDefinition();
registry.registerBeanDefinition("UrlOneController",
personManagerBeanDefinition);
}
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory
beanFactory) throws BeansException {
}
}
package your controller into normal jar(not use spring-boot-maven-plugin )
run your app like this command line
java -Dloader.path="lib/,config/,/home/jin/Desktop/abc/target/abc-1.0-SNAPSHOT.jar" -jar stackoverflow-1.0-SNAPSHOT.jar --external.controller.enable=true
the extra contorller in abc-1.0-SNAPSHOT.jar and your main app is stackoverflow-1.0-SNAPSHOT.jar
tips:
stackoverflow-1.0-SNAPSHOT.jar should package zip format .
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layout>ZIP</layout>
</configuration>
</plugin>

Typesafe Config: Load configuration from src/test/resources

This is a beginner question. So my app structure looks like
src/main/java/...
src/main/resources/application.conf
src/test/java/...
src/test/resources/module/test.module.conf
application.conf
location: mainLocation
test.module.conf
location: testLocation
In my test, I do
#Test
public void testLoadConfig() {
final Config config = ConfigFactory.parseResources("test.module.conf");
System.out.println(config);
}
and what I see
Config(SimpleConfigObject({}))
Surely something is not right, but I can't spot it
UPDATE
When I do just
#Test
public void testActorForFailure() {
// final Config config = ConfigFactory.load("test.module.conf");
final Config config = ConfigFactory.load();
System.out.println(config.getString("location"));
}
I see
mainLocation
So overriding is not working, why?
If you want to load that test config file try this:
ConfigFactory.load("modules/test.module")
The base ConfigFactory.load() method looks to load 'application.conf'. If you want it to load a different file you need to tell it what that different file is.

own http4 Camel Component with own URI

I want to create my own Camel Component. Based on the Component http4. I want only insert server and port by default. So i can write:
from("myhttp://test1.php")
.to("myhttp://test2.php")
And my Component change the URI to "http:// myhost:8080/test1.php" and "http:// myhost:8080/test2.php" but I can't create my own scheme Name. I test #UriEndpoint(scheme = "myhttp") in the class
public class myhttpEndpoint extends org.apache.camel.component.http4.HttpEndpoint {
}
Can you help me?
What I do:
public class myhttpComponent extends org.apache.camel.component.http4.HttpComponent {
#Override
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
...
...
HttpEndpoint endpoint = new myhttpEndpoint(endpointUriString, this, clientBuilder, localConnectionManager, configurer);
...
...
}
}
#UriEndpoint(scheme = "myhttp")
public class myhttpEndpoint extends org.apache.camel.component.http4.HttpEndpoint {
public myhttpEndpoint(String endpointUriString,
cacheComponent cacheComponent, HttpClientBuilder clientBuilder,
HttpClientConnectionManager localConnectionManager,
HttpClientConfigurer configurer) throws URISyntaxException {
super(endpointUriString, cacheComponent, clientBuilder, localConnectionManager, configurer);
}
The #UriEndpoint annotation is actually optional when creating a custom Camel component and I think it's only used if you want configuration documentation to be automatically generated. More info: http://camel.apache.org/endpoint-annotations.html
To tie your component class to the component name "myhttp", you need to add a file under the META-INF folder in your project. More details: http://camel.apache.org/writing-components.html

Mount an external folder as a resource in Wicket

What I am trying to accomplish is for some image references in a css file to be located in a folder seperate to the actual application.
Is it possible to mount an external folder as a resource in Wicket?
In pseudocode this is what I am trying to do:
public class Application extends WicketApplication
{
init()
{
mountResource(new FolderResource("Path/to/some/folder", "someid"));
}
}
So that the .css class would reference the resources like this:
.someclass
{
url("resources/someid/images/image.png")
}
I'm sure I've seen this somewhere but I just can't seem to be able to find it again...
EDIT
Should also note that im currently running on Wicket 1.4
As simple as following.
MyApplication.java:
public class MyApplication extends WebApplication {
...
public void init() {
...
final String resourceId = "images";
getSharedResources().add(resourceId, new FolderResource(new File(getServletContext().getRealPath("img"))));
mountSharedResource("/image", Application.class.getName() + "/" + resourceId);
}
...
}
FolderResource.java:
public class FolderResource extends WebResource {
private File folder;
public FolderResource(File folder) {
this.folder = folder;
}
#Override
public IResourceStream getResourceStream() {
String fileName = getParameters().getString("file");
File file = new File(folder, fileName);
return new FileResourceStream(file);
}
}
And then you can get any image from "img" folder inside your application by simple URL:
/your-application/app/image?file=any-image.png
Here "/your-application" is the application context path, "/app" is the Wicket servlet mapping in web.xml, and "any-image.png" is the name of the image file.

Categories

Resources