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

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.

Related

SpringBoot with RequestMapping on Application and another RequestMapping in controller classes, is that possible?

I am learing SpringBoot and Rest api just now and in all examples I have seen, in every controller classes they have a #RequestMapping("/api/v1") and then some #GetMapping or simular.
But it feels like why am I writing a RequestMapping for every controller if the first URI mapping is the same for all controllers.
Is it possible to have a #RequestMapping in the SpringBootApplication that maps "/api/v1" and then in the controller classes then have another ®RequestMapping for subfolders like "/products" and simular.
I have tried to solve this, but I cant make it function.
#SpringBootApplication
#RestController
#RequestMapping("/api/v1")
public class CommonApplication {
public static void main(String[] args) {
SpringApplication.run(CommonApplication.class, args);
}
}
#RestController
#RequestMapping()
public class ProductController {
private ProductService productService;
#GetMapping("/products")
public String getProducts()
{
return "Hello from getProducts 12";
}
}
I want this full URI "/api/v1/products" to function and return the String text. But I only get 404.
It is possible to have request mapping in both application and controller class. Go through the documentation which is attached below once for having better understanding.
https://zetcode.com/spring/requestmapping/

Inject UriComponentsBuilder or use static ServletUriComponentsBuilder?

Does it make any difference if I inject UriComponentsBuilder as parameter into the #RestController method, or if I access the uri from static ServletUriComponentsBuilder context (fetching it from RequestContextHolder underneath)?
#RestController
public class MyServlet {
#GetMapping
public List<Person> persons(UriComponentsBuilder uri) {
System.out.println(uri.build().toUriString());
System.out.println(ServletUriComponentsBuilder.fromCurrentContextPath().toUriString());
}
}
The static factory method that Spring calls behind the scene to provide UriComponentsBuilder as method parameter to your class is fromServletMapping
public static ServletUriComponentsBuilder fromServletMapping(HttpServletRequest request) {
ServletUriComponentsBuilder builder = fromContextPath(request);
if (StringUtils.hasText(UrlPathHelper.defaultInstance.getPathWithinServletMapping(request))) {
builder.path(request.getServletPath());
}
return builder;
}
And here is the code for fromContextPath static factory method that you called: (actually fromCurrentContextPath method calls this method with the current request)
public static ServletUriComponentsBuilder fromContextPath(HttpServletRequest request) {
ServletUriComponentsBuilder builder = initFromRequest(request);
builder.replacePath(request.getContextPath());
return builder;
}
So you can see their result are different when you have a request that contains servlet-mapping: In most Spring applications we have a single servlet and the output of these two are the same.
But what if our request belongs to a servlet with servlet-path: first/?
Imagine the following controller:
#RestController
public class MyServlet {
#GetMapping("test")
public void persons(UriComponentsBuilder uri) {
System.out.println(
uri.path("/second/third").build().toUriString());
System.out.println(
ServletUriComponentsBuilder.fromCurrentContextPath().path("/second/third").build().toUriString());
}
}
When you send a request to this path Your output will be like this:
http://localhost:8081/first/second/third
http://localhost:8081/second/third
So the first one includes the servlet-path but the second one ignores it.
To have the same result you can use fromCurrentServletMapping static fatory method.

My own WebPages are not shown on localhost

I have a Spring application with Apache Wicket (Its my first Spring-Application) and its autogenerated. If I run my application and I call it on localhost there is only shown a site with "TestDataManager is running" on it instead of the Site I call in the Main. I figured out that I have in the tests- package a class named ExampleController and its not from me. In this class is witten what is shown on localhost. But in my Main I dont call this Class.
Can Somone say how to fix this.
#SpringBootApplication
#RestController
public class Application extends WebApplication {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public Class<? extends Page> getHomePage() {
return WhatToDoPage.class;
}
}
ExampleController:
#RestController
public class ExampleController {
#Value("TestDataManager is running")
private String message;
#GetMapping("/")
public String indexGet() {
return message;
}
}
Spring Boot scans the classpath, finds ExampleController and registers it as a REST controller bean.
Later when you make a call to / it uses it to return the response. Since you return a String without #GetMapping(produces = ...) it uses text/plain as response content type.
Apache Wicket is not involved in your application. I am not sure why you use/tag it.

Springboot Dynamically modify the ResourceHandlerRegistry mapping

I've a spring boot web application that can serve files from a static file location in server.
I've specified the location in properties file and using it to configure the ResourceHandlerRegistry.
#SpringBootApplication
public class MyWebApplication {
#Value("${targetdirectory}")
private String targetDirectory;
#Bean
WebMvcConfigurer configurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
targetDirectory = StringUtils.appendIfMissing(targetDirectory, "/", "/");
targetDirectory = StringUtils.prependIfMissing(targetDirectory, "file:/", "file:/");
registry.addResourceHandler("/resourcetarget/**").addResourceLocations(targetDirectory);
}
};
}
public static void main(String[] args) {
SpringApplication.run(MyWebApplication.class, args);
}
}
Everything works as expected. Now I have to dynamically set the resource location based on user input.
After the application is loaded, the user triggers an HTTP post request where he can specify the directory by which can be used as the resource location.
So after that any requests to the /resourcetarget/** should be mapped to the directory which the user specified. Following is the controller I have.
#RestController
#RequestMapping(value = "api/locations", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class MyController {
#PostMapping
public ResponseEntity<Object> handleLocationSet(#RequestBody LocationDTO locationDto) {
String newFileLocation = locationDto.getLocation();
// How do I update the ResourceHandlerRegistry mapping for /resourcetarget/**
// with the new location received here?
return ResponseEntity.ok();
}
}
How can I update the mapping for this dynamic location for a static resource url. Please help

Spring Boot: Dynamically change the static resource handler?

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
}

Categories

Resources