Serving static resources

So far, we have seen that every request goes through the Controller and returns a corresponding View file for the request, and most of the time these View files contain dynamic content. By dynamic content, I mean that, during the request processing, the model values are dynamically populated in the View file. For example, if the View file is of the type JSP, then we populate the model values in the JSP file using the JSTL notation ${}.

But what if we have some static content that we want to serve to the client? For example, consider an image that is static content; we don't want to go through Controllers in order to serve (fetch) an image, as there is nothing to process or update in terms of values in the model—we simply need to return the requested image.

Let's say we have a directory (/resources/images/) that contains some product images and we want to serve those images upon request. For example, if the requested URL is http://localhost:8080/webstore/img/P1234.png, then we will like to serve the image with the name P1234.png. Similarly, if the requested URL is http://localhost:8080/webstore/img/P1236.png, then an image with the name P1236.png needs to be served.

Time for action - serving static resources

Let's see how to serve static images with Spring MVC:

  1. Put some images under the directory src/main/webapp/resources/images/; I put three product images in: P1234.png, P1235.png, and P1236.png.
  2. Override the addResourceHandlers method from our WebApplicationContextConfig.java web application context configuration file as follows:
          @Override 
          public void addResourceHandlers(ResourceHandlerRegistry 
          registry) { 
             registry.addResourceHandler("/img/**") 
                    .addResourceLocations("/resources/images/"); 
          } 
    
  3. Now run our application and enter the URL http://localhost:8080/webstore/img/P1234.png (change the image name in the URL based on the images you put in the directory in step 1).
  4. You will be able to view the image you requested in the browser.

What just happened?

What just happened was simple. In step 1, we put some image files under the src/main/webapp/resources/images/ directory. And in step 2, we just overrode the addResourceHandlers method from our web application context configuration file, WebApplicationContextConfig.java, to tell Spring where those image files are located in our project, so that Spring can serve those files upon request:

@Override 
public void addResourceHandlers(ResourceHandlerRegistry registry) { 
   registry.addResourceHandler("/img/**") 
         .addResourceLocations("/resources/images/"); 
} 

The addResourceLocations method from ResourceHandlerRegistry defines the base directory location of the static resources that you want to serve. In our case, we want to serve all the images that are available under the src/main/webapp/resources/images/ directory; you may wonder then why we have only given /resources/images as the location value instead of src/main/webapp/resources/images/. This is because, during our application build and deployment time, Spring MVC will copy everything available under the src/main/webapp/ directory to the root directory of our web application. So during resource look up, Spring MVC will start looking up from the root directory.

The other method—addResourceHandler—just indicated the request path that needs to be mapped to this resource directory. In our case, we assigned /img/** as the mapping value. So if any web request comes with the request path /img, then it will be mapped to the resources/images directory, and the /** symbol indicates to recursively look for any resource files underneath the base resource directory.

That is why, if you noticed in step 3, we formed the URL as follows: http://localhost:8080/webstore/img/P1234.png. So while serving this web request, Spring MVC will consider /img/P1234.png as the request path, so it will try to map /img to the resource base directory resources/images. From that directory, it will try to look for the remaining path of the URL, which is /P1234.png. Since we have the images directory under the resources directory, Spring can easily locate the image file from the images directory.

So in our application, if any request comes with the request path prefix /img in its URL, then Spring will look into the location directory that is configured in ResourceHandlerRegistry and will return the requested file to the browser. Remember Spring allows you to not only host images, but also any type of static files such as PDFs, Word documents, Excel sheets, and so in this fashion.

It is good that we are able to serve product images without adding any extra request mapping methods in our Controller.

Pop quiz - static view

Consider the following resource configuration:

@Override 
public void addResourceHandlers(ResourceHandlerRegistry registry) { 
   registry.addResourceHandler("/resources/**") 
          .addResourceLocations("/pdf/"); 
} 

Under the pdf directory, if I have a sub-directory such as product/manuals/, which contains a PDF file called manual-P1234.pdf, how can I form the request path to access that PDF file?

  1. /pdf/product/manuals/manual-P1234.pdf
  2. /resources/product/manuals/manual-P1234.pdf
  3. /product/manuals/manual-P1234.pdf
  4. /resource/pdf/product/manuals/manual-P1234.pdf

Time for action - adding images to the product detail page

Let's extend this technique to show the product images in our product listing page and in the product detail page. Perform the following steps:

  1. Open products.jsp, which you can find under the /src/main/webapp/WEB-INF/views/ directory in your project, and add the following <img> tag after the <div class="thumbnail"> tag:
          <img src="<c:url value="/img/${product.productId}.png">
          </c:url>" alt="image"  style = "width:100%"/> 
    
  2. Similarly open product.jsp and add the following <img> tag after the <div class="row"> tag:
          <div class="col-md-5"> 
             <img src="<c:url value="/img/${product.productId}.png">
             </c:url>" alt="image"  style = "width:100%"/> 
          </div> 
    
  3. Now run our application and enter http://localhost:8080/webstore/market/products. You will be able to see a product list page with every product displaying a product image, as shown in the following screenshot:
    Time for action - adding images to the product detail page

    Product listings with images

  4. Now click on the Details button of any product, and you will be able to see the corresponding View of the product details with an image attached to the details page, as follows:
    Time for action - adding images to the product detail page

    Product detail page with image attached

What just happened?

What we did was simple. You learned how we can serve static resources, and you saw how to host product images. During this exercise, you learned that, in our application, if any request comes with the request path prefix /img, it will get mapped to the base resource directory and any further remaining URL path will lead to the static file.

We leveraged this fact and formed the image's src URL accordingly; notice the src attribute of the <img> tag we added in step 1:

<img src="<c:url value="/img/${product.productId}.png"></c:url>" alt="image"  style = "width:100%"/> 

The src attribute value that we are forming in this <img> tag has an expression to fetch the product ID. After getting the product ID, we simply concatenate it to the existing value to form a valid request path, as follows:

"/img/${product.productId}.png 

For example, if the product ID is P1234, then we will get an image request URL as /img/P1234.png, which is nothing but one of the image file names that we already put in the /resources/images directory. So Spring can easily return that image file, which we showed using the <img> tag in steps 1 and 2.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.255.44