Open In App

Serve Static Resources With Spring

Last Updated : 21 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

It’s essential to know about static resources, which are the resources that do not change frequently on a web page. To serve these static resources, Spring Boot comes with an inbuilt class called ResourceHttpRequestHandler in conjunction with the ResourceHandlerRegistry class. You can keep these static resources under specific paths like ‘/public’, ‘/static’, ‘resources’, and ‘META-INF/resources/’. To change the default locations that serve the static resources, define them in the resources folder with

spring.resources.static-locations=/html, /css, /js

Sample Folder Structure:

Screenshot-2024-02-13-at-33213-PM

sample folder structure

Guide to Serving Static Pages

We can customize the resource handling by configuring it with ResourceHandlerRegistry. We typically configure how our Spring Boot app deals with web stuff in a special class. This class can either be an old-style one called WebMvcConfigurerAdapter (which is a bit outdated but still commonly used) or directly implement WebMvcConfigurer. Here is the sample code

Java




@Configuration
public class WebConfig implements WebMvcConfigurer {
  
    @Override
    public void
    addResourceHandlers(ResourceHandlerRegistry registry)
    {
        registry.addResourceHandler("/static/**")
            .addResourceLocations("classpath:/static/")
            .setCachePeriod(3900)//mention in seconds
            .resourceChain(true)
            .addResolver(new PathResourceResolver());
    }
}


Lets get to know what the ResourceHandlerRegistry does,

  • It is responsible for configuring how static resources are handled by Spring MVC Appl.
  • Mapping URLs to Resources
  • Setting Cache Periods
  • Enabling Resource Chains : You can add a special code in the resource’s web address, making sure that browsers know when it changes. This helps in controlling how long the browser keeps a copy and ensures users always see the latest version of the resource. Lets see how we do this,

Java




import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.VersionResourceResolver;
  
@Configuration
public class WebConfig implements WebMvcConfigurer {
  
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(3600)
                .resourceChain(true)
                .addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
    }
}


Sample Output:

Highcompressed_780624975

sample output

Here we are using Thymeleaf here, you can use any other

<!– Thymeleaf example –>

<link rel=”stylesheet” th:href=”@{/static/css/style.css}” />

Let’s get to know what the PathResourceResolver does,

  • Resource Resolution : helps find the actual resource on the server that corresponds to the requested URL.
  • Support for Versioned Resources
  • Fallback Mechanism : If the requested file is not found, the PathResourceResolver tries to be helpful by looking for a similar file with a different type or in another location.

You may also have a question what will happen after the cache period? Let me tell you,

  • Conditional GET Request :
    • The client browser sends a conditional GET request to the server, including an If-Modified-Since header with the timestamp of when it originally cached the resource.
  • Server Response :
    • If the resource has not been modified since the provided timestamp, the server responds with a 304 Not Modified status code and an empty body. This indicates to the browser that the cached version is still valid.
  • Using Cached Resource :
    • If the server indicates that the resource hasn’t been modified, the browser continues to use the cached version. This helps in reducing unnecessary data transfer and improves performance.
  • If Resource is Modified :
    • If the server determines that the resource has been modified since the provided timestamp, it sends the updated resource with a 200 OK status code. The browser then replaces the old cached version with the new one.

Guide to serving dynamic pages

Let’s get into a step-by-step guide on this demo for generating dynamic content using Thymeleaf where data are processed from the server.

Java




@Controller
public class studentController {
    @Autowired 
      studentService service;
  
    // handler method to handle studnts
    @GetMapping("/students")
    public String listStudents(Model model)
    {
        model.addAttribute("index",
                           service.getAllStudents());
        return "index";
    }
  
    @GetMapping("/students/new")
    public String addStudents(Model model)
    {
        // object to hold the data of new student
        Student student = new Student();
        model.addAttribute("student", student);
        return "add_students";
    }
    @PostMapping("/students")
    public String
    saveStudent(@ModelAttribute("student") Student student)
    {
        service.saveStudent(student);
        return "redirect:/students";
    }
    @GetMapping("students/edit/{id}")
    public String editStudent(@PathVariable("id") Long id,
                              Model model)
    {
        model.addAttribute("student",
                           service.getStudentById(id));
        return "edit_student";
    }
}


In this piece of code that I’ve written you should know about Model Interface which is present in the package of org.springframework.ui.Model and Controller annotation and not RestController.

Model interface is used in controllers to pass data to views. It holds attributes that need to be displayed in the user interface. Controllers add data to the model, and views access and display that data. It’s a way to share information between the backend and frontend components of a web application.

Genrally the @RestController annotation is used to create a webservice that returns JSON/XML data, @Controller annotation that is used to create web controllers that returns views. You may have a question what views are, simply we could say the user interface output to the user request. To work completely with the dynamic content, just write the HTML pages using Thymeleaf and serve it through the controller, where the server sends the data to the view.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads