Below is what I see when I run my code.
Thymeleaf code I am using:
<div>
<img th:scr="@{/uploads/${image}}" alt="Uploaded Image" width="200px" height="200px"/>
</div>
The directory path starts with the file of my complete Java project... GEM/uploads/(what's stored).
When I run my controller code and I print it, I have a list of String and it prints correctly how the file should be.
@GetMapping("/images")
public String viewUserImages(Model model, User user) {
user = userService.getCurrentUser();
if (user != null) {
List<ImageMetaData> img = imageService.getImagesByUser(user);
List<String> images = ImageMetaData.filePathStartFromDate(img);
for (String i : images) {
System.out.println(i);
}
model.addAttribute("images", images); // Add images to the template
} else {
model.addAttribute("error", "You need to be logged in to view images.");
}
return "imageGallery";
}
my console prints... (which is stored by date and a random generated file name)
2025/02/23/e2ac3061-e334-4dec-9a08-4298475edc08.jpg
2025/02/23/e533359f-e8f1-46a7-90d2-c921299d10dc.jpg
These images are being stored correctly because I can see them in the folders. I tired to update permissions on my mac, but not exactly sure if I did it correctly. Can anyone experienced please help me figure out why my photos aren't displaying?
Thanks to ChatGPT! It helped but I just summarise our discussion:
th:scr
-> th:src
<div>
<img th:scr="@{/uploads/{image}(image=${image})}" alt="Uploaded Image" width="200px" height="200px"/>
</div>
src/main/resources/static
/GEM
│── /src
│ ├── /main
│ │ ├── /java/...
│ │ ├── /resources
│ │ │ ├── /static
│ │ │ │ ├── /uploads
│ │ │ │ │ ├── /2025
│ │ │ │ │ │ ├── /02
│ │ │ │ │ │ │ ├── /23
│ │ │ │ │ │ │ │ ├── e2ac3061-e334-4dec-9a08-4298475edc08.jpg
│ │ │ │ │ │ │ │ ├── e533359f-e8f1-46a7-90d2-c921299d10dc.jpg
│ │ │ ├── /templates
│ │ │ │ ├── imageGallery.html
│ │ ├── /application.properties
│── /target
│── pom.xml
Simple example:
If you have image GEM/src/main/resources/static/image1.jpg
then you can access it from Thymeleaf
like that:
<img th:scr="@{image1.jpg)}"
If you have image GEM/src/main/resources/static/nestedFolder/image2.jpg
then next way works:
<img th:scr="@{nestedFolder/image2.jpg)}"
BUT if you want to have images under project root, something like that:
/GEM
│── /uploads
│ ├── /2025
│ │ ├── /02
│ │ │ ├── /23
│ │ │ │ ├── e2ac3061-e334-4dec-9a08-4298475edc08.jpg
│ │ │ │ ├── e533359f-e8f1-46a7-90d2-c921299d10dc.jpg
│── /src
│ ├── /main
│ │ ├── /java/...
│ │ ├── /resources
│ │ │ ├── /templates
│ │ │ │ ├── imageGallery.html
│ │ ├── /application.properties
│── /target
│── pom.xml
then you should tell it Spring explicitly:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String uploadDir = Paths.get("uploads").toUri().toString();
registry.addResourceHandler("/uploads/**").addResourceLocations(uploadDir);
}
}
which means:
"If a browser requests http://localhost/uploads/**
, look for this file in the uploads/
folder in the project root (because by default Spring looks for this file in src/main/resources/static/
)"