How to retrieve an image from a Spring RestController using Angular and store it in the

Currently, I am working on a Client-Server application that utilizes SpringBoot and Angular2. One of the functionalities I have implemented successfully is loading an image from the server based on its filename.

At the client-side, I store the attribute image:string and display it in the template. However, there is a concern with return res.url;, as it does not utilize the actual resource, which may not be the correct approach.

My main goal is to implement image caching. As far as I know, web browsers can cache images automatically. Despite this, my current setup does not seem to be working in terms of caching. If anyone has any suggestions or insights on what adjustments are needed, please feel free to share them.

On the Server side (SpringBoot):

public class ImageRestController {
    @RequestMapping(value = "/getImage/{filename:.+}", method = RequestMethod.GET)
    public ResponseEntity<Resource> getImage(@PathVariable String filename) {

        try {
            String path = Paths.get(ROOT, filename).toString();
            Resource loader = resourceLoader.getResource("file:" + path);
            return new ResponseEntity<Resource>(loader, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<Resource>(HttpStatus.NOT_FOUND);
        }
    }
}   

On the Client side (Angular2):

@Component({
  selector: 'my-image',
  template: `
    <img src="{{image}}"/>
  `
})

export class MyComponent {

  image:string;
  constructor(private service:MyService) {}

  showImage(filename:string) {
    this.service.getImage(filename)
      .subscribe((file) => {
          this.image = file;
        });
      }
}

export class MyService() {
  getImage(filename:String):Observable<any> {
    return this.http.get(imagesUrl + "getImage/" + filename)
      .map(this.extractUrl)
      .catch(this.handleError);
  }
  extractUrl(res:Response):string {
    return res.url;
  }
}

Answer №1

To improve server-side performance, consider implementing the following code snippet and including an ETag or Last-Modified header if applicable:

return ResponseEntity
            .ok()
            .cacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
            .body(loader);

For more information on HTTP caching mechanisms in Spring, refer to the relevant section of the official documentation.

If your goal is simply to serve resources without additional processing, execute the following steps:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/getImage/**")
                .addResourceLocations("classpath:/path/to/root/")
                .setCacheControl(CacheControl.maxAge(1, TimeUnit.DAYS).cachePublic());
    }

}

Explore this segment of the documentation for more insights. Additionally, you can apply transformations and utilize cache busting techniques (refer to this section as well).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the method to activate a click event on an input file when a button is clicked in Angular 2?

<input type="file" accept="image/*"> <button>Upload file</button> Is there a way to activate the input type=file click event using the button's click event in Angular 2? ...

Deciding if one of two strings concludes the other string

As I take on codingbat tasks for my class, I find that my experience level exceeds that of my classmates. This leads me to challenge myself by optimizing my code, avoiding loops, and adopting different strategies. My current focus lies on tackling the end ...

Steps for building a custom component using MUI as a foundation

My current approach: import React from "react"; import {useHistory} from "react-router-dom"; import {Button, ButtonProps} from "@mui/material"; type Props = { label?: string } & ButtonProps; export const NavBackButton = ...

"Angular 2: Organize and refine data with sorting and

Sorting and filtering data in Angularjs 1 can be done using the following syntax: <ul ng-repeat="friend in friends | filter:query | orderBy: 'name' "> <li>{{friend.name}}</li> </ul> I have not been able to find any ex ...

ag-grid's onGridReady function is not functioning properly

I am trying to dynamically load ag-grid when a button is clicked, but I have encountered issues with both of my approaches. Here is my code for the first method: onBtnClick(){ this.gridOptions ={ onGridReady : function(){ console ...

React: Issue accessing URL parameters using useParams() within a nested component

In my demo application, there are two components - QuoteDetail and Comments. Both require URL parameters, but I am only able to access them in the parent component. App.tsx: <Switch> // ... <Route path="/quotes" exact> <Al ...

When using Angular server-side pagination with ngrx and Express in Node.js, I often encounter discrepancies in the indexing across different stacks

After successfully implementing server-side pagination in Angular, I encountered an issue where the page was set to 1 initially, but the mat-paginator component started at index 2. Despite functioning correctly when changing pages, this discrepancy puzzled ...

Display or conceal specific elements within the ngFor loop

Looking for a way to show/hide part of a component in Angular2? Here's an example: <li *ngFor=" #item of items " > <a href="#" (onclick)="hideme = !hideme">Click</a> <div [hidden]="hideme">Hide</div> </li> If ...

Angular 14 - Issue with passing values through props - Error: Uncaught (in promise): InvalidCharacterError occurs when attempting to set attribute with 'setAttribute' method

I am a beginner with Angular and encountering an issue when trying to pass props from a parent component to a child component. The specific error I am facing is related to an invalid attribute name while using Angular version 14.2.5. core.mjs:7635 ERROR ...

I am facing an issue with my MainActivity.java file, where the OnStart() method does not trigger the CheckUserExistence() function when I include the FirebaseRecycler Adapter within OnStart()

In my MainActivity.java code, I am facing an issue related to FirebaseRecyclerAdapter in the onStart() method. When I include FirebaseRecyclerAdapter in the onStart() method, it doesn't call the CheckUserExistence() method present in the OnStart() met ...

Can someone provide a description for a field within typedoc documentation?

Here is the code snippet: /** * Description of the class */ export class SomeClass { /** * Description of the field */ message: string; } I have tested it on the TSDoc playground and noticed that there is a summary for the class, but not for it ...

Previewing Printed Forms in JSF

I am working with a JSF form on a view *.jspx page that contains approximately 20 fields. The form includes a print preview button that opens a new browser window and displays the form in read-only mode. To achieve this, I have utilized a workaround invol ...

How to Properly Parse JSON in Java?

I have a JSON array that is producing the following output: print json_decode($array); The output string looks like this: {"dbonline":true,"success":true,"action":"geturls","authorized":true, "urls":[ {"url":"http:\/\/www.namhost.com"}, ...

Is there a converter in Express similar to Spring MVC?

Is there a plugin in Express that allows for the assembly of custom objects from request parameters, similar to how "@RequestParam CustomeObject customObject" works in Spring MVC? ...

Angular 7's Cross-Origin Resource Sharing (CORS) Configuration

Hey there! I've been struggling with getting the CORS to work. I stumbled upon this helpful post that pointed me in the right direction. Following the link provided in that post to angular.io, I implemented the solution suggested. Let me describe my ...

What is the best way to incorporate a JavaScript function into an Angular 2 template?

I need a slider for my project and I am using AdminLTE <input type="text" value="" class="slider form-control" data-slider-min="-200" data-slider-max="200" data-slider-step="5" data-slider-orientation="horizontal" data-slider-sele ...

Adjust Column Title in Table

Is it possible to customize the column headers in a mat-table and save the updated value in a variable? I've been looking for a solution to this but haven't found one yet. ...

I am unsure why it is displaying these errors

I created an auto-fill form that populates data based on ng-select information automatically. However, I am encountering an issue when attempting to delete selected data as it is throwing a Cannot read property 'pincode' of null error. Any help i ...

Mastering the art of connecting content within Prismic

I have been working on creating a mega menu for my website header, but I am encountering a type error. Has anyone else faced this issue before and how did you resolve it? I am currently importing the generated types from @/prismicio-types. Here is an exam ...

Disallow the use of properties in a nested interface

Is there a way to define an interface or type that restricts a specific key in a child of the interface when used in union types? I am looking for the correct definition for Abc: type Abc = { someField: { prohibited?: never, }, }; type Use ...