0

I use Spring boot to develop a website.I develop a function of uploading avatar image , when I update avatar image and display it but the avatar does not change and the image already has changed in the folder, why?

The problem is http cache?

my simple project:

dropbox link to my project

(note: you need to change the local path in TestingController)

Community
  • 1
  • 1
Devin Iao
  • 13
  • 1
  • 3
  • >"The problem is http cache?" probably - What happens when you reload the the webpage (Press "Ctrl + F5" or press "Ctrl + Shift + R" (Windows,Linux) ) – Ralph Oct 05 '16 at 06:46
  • @Ralph,i try to refresh page and open the url of image,but the image is old image – Devin Iao Oct 05 '16 at 06:49
  • In which folder do you save the image? Inside or outside of your application? – Patrick Oct 05 '16 at 06:59
  • @Patrick I save image in the folder(/static/uploads/images/) and image name is testing.png, when I update a new image, the new image overwrite the old image and the image name does not change. – Devin Iao Oct 05 '16 at 07:11
  • I think the problem is that you save the image as a static resource. So it will not getting refreshed after change until you restart the application. I would try to save the picture outside of your application and get it from there. Is the new picture available after upload and restart of the application? – Patrick Oct 05 '16 at 07:18
  • @Patrick,i save image in this path(/static/uploads/images/)),so i can get image use it (http://localhost:8080/images/testing.png), if i save image outside of my application, how to get the image? – Devin Iao Oct 05 '16 at 13:15
  • Can you show your code where you save and receive the image, please. – Patrick Oct 05 '16 at 13:16
  • @Patrick, I update a simple project to dropbox and you can download(https://www.dropbox.com/s/26tnkuu1q5mrny5/testing.zip?dl=0), you can use the url (http://localhost:8080/images/testing.png) to test the problem. – Devin Iao Oct 06 '16 at 02:13

1 Answers1

3

You are not able to see the uploaded picture instantly because you save the image in the static files of your application. You are able to see the the saved image in your folder but not if you call your url. If you refresh your running project after uploading the file (project root and hit F5) you should be able to see it.

But the better solution would be that you have a @RequestMapping to load the picture and show it in browser.

Build on your project, try to use it like this:

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

import org.json.JSONObject;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class TestingController {

    private final Path p = Paths.get("/Users/devin/Documents/workspace-sts-3.8.1.RELEASE/testing/src/main/resources/static/uploads/images");

    @RequestMapping(value={ "/", "/home"})
    public String home(){
        return "home";
    }

    @RequestMapping(value = "/post_upload_avatar_file", method = RequestMethod.POST)
    @ResponseBody
    public Object uploadAvatarFile(@RequestParam("uploadfile") MultipartFile uploadfile) {
        JSONObject resJsonData=new JSONObject();
        try {
            if(uploadfile.isEmpty()){
                System.out.println("Empty");
            }

            Files.copy(uploadfile.getInputStream(), p.resolve(uploadfile.getOriginalFilename()));

            resJsonData.put("status", 200);
            resJsonData.put("message", "Success!");
            resJsonData.put("data", uploadfile.getOriginalFilename());
        }catch (Exception e) {
            System.out.println(e.getMessage());
            resJsonData.put("status", 400);
            resJsonData.put("message", "Upload Image Error!");
            resJsonData.put("data", "");
        }
        return resJsonData.toString();
    }

    @GetMapping("files/{filename:.+}")
    @ResponseBody
    public ResponseEntity<Resource> serverFile(@PathVariable String filename){
        Resource file = loadAsResource(filename);
        return ResponseEntity
                .ok()
                .body(file);
    }

     public Resource loadAsResource(String filename) {
        try {
            Path file = p.resolve(filename);
            Resource resource = new UrlResource(file.toUri());
            if(resource.exists() || resource.isReadable()) {
                return resource;
            }
            else {
                System.out.println("no file");
            }
        } catch (MalformedURLException e) {
            System.out.println(e);
        }
        return null;
    }

    public Stream<Path> loadAll() {
        try {
            return Files.walk(p, 1)
                    .filter(path -> !path.equals(p))
                    .map(path -> p.relativize(path));
        } catch (IOException e) {
            System.out.println(e);
        }
        return null;
    }
}

In this code I dont implement exception and error handling.

You can upload your picture like it was. And then you can call another url to receive the picture in your browser.

http://localhost:8080/files/testing.png

And the picture should be the response.

Please have a look to those two sources for a complete solution.

Spring file upload - backend

Spring file upload - frontend

Patrick
  • 12,336
  • 15
  • 73
  • 115