Spring Boot: Dynamically change the static resource handler? - java

I have the following in configuration for my Spring Boot project that serves static files from the local filesystem:
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
System.out.println("adding resource handler");
registry.addResourceHandler("/myfiles/**").addResourceLocations("file:///C:/Users/Pepria/Downloads/static_files/");
}
}
Above config works fine but I want to change the resource location dynamically at runtime. As I understand, above code runs before any of my logic executes. How can I go about doing this ?

You can add a ResourceHandler with your desired path like this:
registry.addResourceHandler("/myfiles/**").addResourceLocations("file:" + Strings.filePath);
You can set Strings.filePath in you application at any time.
public class Strings {
public static String filePath;
//or maybe setters getters
}

Related

How to serve static resource in springboot having custom path from Controller?

I have this resource handler, and I am able to call the static web page located in different location , but I am trying to call from controller class I am not able to get the page
#Configuration
public class Static_ResourceHandler implements WebMvcConfigurer {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/system/files/**").addResourceLocations("file:/home/niteshb/Documents/data");
}
}
This is what I am calling
http://localhost:8080/system/files/test.html
but how to call it from controller , I was trying something like this but its not working
This is my controller class call ..
#GetMapping("/")
public String getfile() {
return "test.html";
}
Create a Get mapping for /system/files/, for which you had created the resource handler,
and return the file in the newly created method.
#GetMapping("/system/files/")
public String getStaticfile() {
return "/system/files/test.html";
}
Hope that should work.

Externalize properties and logback Spring

I'm using Spring (without spring-boot). I want to build standalone application that can be run with default configuration (logback.xml and application.properties in resource folder) or with -Dconfig.folder=/path/to/custom/external/directory
(logback.xml and application.properties in /path/to/custom/external/directory). When application will be run with -Dconfig.folder param AppConfig should load both logback and properties from external directory.
Is there anyway to make external folder act like a resource folder?
If not, what is a common solution for this?
My current implementation (using default resource folder only):
App.java
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
SampleAction p = context.getBean(SampleAction.class);
p.performTask();
}
}
AppConfig.java
#ComponentScan
#PropertySource("classpath:application.properties")
class AppConfig {
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
SampleAction.java
#Component
public class SampleAction {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
#Value("${sample.prop}")
private String sampleProp;
public void performTask(){
logger.debug(sampleProp);
}
}
logback.xml and application.properties are not relevant to the problem
Unlike the other answer suggests, if you use file prefix in #PropertySource, you're screwed because it won't be able to load the default application.properties from the jar. What you should do is the following:
#PropertySource("${config.folder:'classpath:'}/application.properties")
public class AppConfig
For logback.xml:
#Value("${config.folder}:")
private String configFolder;
InputStream = Optional.of(new ClassPathResource(configFolder + "/logback.xml"))
.filter(r -> r.exists())
.orElse(new ClassPathResource("classpath:/logback.xml"))
.getInputStream();
In both cases, I gave preference to the command line argument over the default packaged files. Of course, I didn't compile the above, so there may be typos or minor errors, but you get the idea.
Edit:
Since OP claims to not understand where to run the above code -
public class AppConfig {
#PostConstruct
void init() {
// init logback here
}
}
For log4j.xml
-Dlog4j.configuration=C:\neon\log4j.xml as VM argument
In main() method:
String filename = System.getProperty("log4j.configuration");
DOMConfigurator.configure(filename);
For external properties file:
-Dext.prop.dir=C:\neon as VM argument
Change in your AppConfig class will be like
#PropertySource("file:///${ext.prop.dir}/application.properties")
public class AppConfig{
}
Run App class with VM arguments as below and both file will be use from external location
-Dlog4j.configuration=C:\neon\log4j.xml -Dext.prop.dir=C:\neon

Spring Boot Maven webapp folder and ResourceHandler

In my Maven project with Spring Boot I have a following folder with a static content(Html, CSS, JavaScript files):
/src/main/webapp/docs/
this is my application properties:
server.port: 8080
server.contextPath: /admin-api
When a user access a following url: http://localhost:8080/admin-api/docs I want to show him a static content from /src/main/webapp/docs/ folder.
I'm trying to configure ResourceHandler in my WebMvcConfigurerAdapter but it doesn't work:
#EnableWebMvc
#Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String[] staticResourceMappingPath = { "/docs/", "classpath:/docs/" };
registry.addResourceHandler("/docs").addResourceLocations(staticResourceMappingPath);
}
...
}
http://localhost:8080/admin-api/docs returns 404 Not Found.
What am I doing wrong and how to properly configure it ?
Your addResourceHandlers method should be like below.
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/docs/**").addResourceLocations("/docs/");
}
Now if you have a static page say index.html in docs folder then you can access it using http://localhost:8080/admin-api/docs/index.html

Cannot Use InterceptorRegistry While the Application Extend Neo4jConfiguration

I am using spring boot application mvc with graphDb (Neo4j) as my database.
And I have problem when I have to do internationalization for my app.
I have this code on my application.java
public class Application extends Neo4jConfiguration {
#Autowired
GraphDatabase graphDatabase;
#Bean
GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase("my-graphdb");
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
When I tried to implement internationalization, the tutor says that I need to implement:
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
This code above need the class is extended by WebMvcConfigurerAdapter.
This is the problem, I didn't use WebMvcConfigurerAdapter so I cannot add the method above.
Do I have another option to make my internationalization work well with Neo4jConfiguration?
I just found out how to make it work.
I just have to add new file that extend WebMvcConfigurerAdapter and put the addInterceptors module into that new file.
Which tutorial are you referring to?
you can also create your own Neo4jConfiguration subclass and #Import it onto your boot application context

How can I map a Spring Boot #RepositoryRestResource to a specific url?

I cannot seem to be able to map my Repository in any location other than the following:
#RepositoryRestResource(collectionResourceRel = "item", path = "item")
public interface ItemRepository extends PagingAndSortingRepository<Item, Long> {
I thought I can use:
path = "/some/other/path/item"
but the mapping does not resolve. I get:
HTTP ERROR 404
Problem accessing /some/other/path/item. Reason:
Not Found
In spring-data javadoc path is defined as: "The path segment under which this resource is to be exported."
What am I doing wrong?
To change the base URI, you can also just add this to application.properties:
spring.data.rest.base-path=/my/base/uri
You need to extend the RepositoryRestMvcConfiguration and override the configureRepositoryRestConfiguration(RepositoryRestConfiguration config) to set yours baseUri. e.g.
#Configuration
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {
private static final String MY_BASE_URI_URI = "/my/base/uri";
#Override
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
super.configureRepositoryRestConfiguration(config);
config.setBaseUri(URI.create(MY_BASE_URI_URI));
}
}
Correct application property is the following:
spring.data.rest.base-path=/my/base/path (base-path instead of base-uri)
In spring boot 2
#Configuration
public class RepositoryConfiguration extends RepositoryRestConfigurerAdapter
{
#Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config)
{
config.setBasePath("/my/base/uri");
}
}
I think the path attribute is used to specify a path segment (so no slashes). The "/some/other/path" would have to be the servlet path or the context path (i.e. nothing to do with Spring Data).

Categories

Resources