Tomaž Bizjak
Tomaž Bizjak

Reputation: 65

How to display a local image (saved on C disk) using Spring?

So, I am currently developing a Spring web application that lets you upload an image (valid extensions are: .png, .jpeg, .jpg and .gif) from a form. The image is then saved on a disk and its relative path is stored in a database. I have successfully saved the image to a disk using this code:

@Override
public void saveThumbnail(MultipartFile thumbnailFile) throws Exception {
    String folder = "/bundles/";
    byte[] bytes = thumbnailFile.getBytes();
    Path path = Paths.get(folder + thumbnailFile.getOriginalFilename());
    Files.write(path, bytes);
}

The form looks like that

enter image description here

And here's the code that displays this form

                <form:form method="POST" modelAttribute="eventForm" class="form-signin" enctype="multipart/form-data">
                <spring:bind path="name">
                    <span>Name</span><br>
                    <div class="form-group ${status.error ? 'has-error' : ''}">
                        <form:input type="text" path="name" class="form-control" placeholder="Name"
                                    autofocus="true"></form:input>
                        <form:errors path="name"></form:errors>
                    </div>
                </spring:bind>

                <spring:bind path="price">
                    <span>Price</span><br>
                    <div class="form-group ${status.error ? 'has-error' : ''}">
                        <form:input type="number" path="price" class="form-control"></form:input>
                        <form:errors path="price"></form:errors>
                    </div>
                </spring:bind>

                <spring:bind path="thumbnailFile">
                    <span>Thumbnail image</span><br>
                    <div class="form-group ${status.error ? 'has-error' : ''}">
                        <c:if test="${eventForm.thumbnailUrl != null}">
                            <img src="file:C:${eventForm.thumbnailUrl}">
                        </c:if>
                        <form:input type="file" path="thumbnailFile" class="form-control" name="thumbnailFile"/>
                        <form:errors path="thumbnailFile"></form:errors>
                    </div>
                </spring:bind>

                <spring:bind path="description">
                    <span>Description</span><br>
                    <div class="form-group ${status.error ? 'has-error' : ''}">
                        <form:textarea rows="4" path="description" class="form-control" placeholder="Description"/>
                        <form:errors path="description"></form:errors>
                    </div>
                </spring:bind>

                <button type="submit" class="btn-add-new">Save</button>
            </form:form>

I have already tried to display it like that:

<img src="file:C:${eventForm.thumbnailUrl}">

However, my browser seems to block this action in order to prevent any security problems. I did some research and found out that you can let Apache serve files from a directory that it can access. Since I am new to web development, I have no idea how I would implement that even though I looked up a few articles and tutorials.

Thank you in advance.

Upvotes: 2

Views: 2971

Answers (3)

Tomaž Bizjak
Tomaž Bizjak

Reputation: 65

I have finally managed to display the image. If any one else is trying to do the same, I'd like to list the steps that I took. FYI, I was using Tomcat and MySQL database.

  • Make sure that your image directory exists on your system and add an image into it.

  • Create a new class named FileServlet and apply the following code into it.

@WebServlet("/images/*")
public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException
    {
        String filename = URLDecoder.decode(request.getPathInfo().substring(1), "UTF-8");
        File file = new File("C:\\your\\local\\image\\directory", filename);
        response.setHeader("Content-Type", getServletContext().getMimeType(filename));
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
        Files.copy(file.toPath(), response.getOutputStream());
    }
}
  • Now go to your main class and apply an annotation named @ServletComponentScan. Your main class should now look like that:
@SpringBootApplication
@ServletComponentScan
public class WebApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WebApplication.class);
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(WebApplication.class, args);
    }

}
  • In your .jsp file add this line wherever you'd like to display the image:
<img src="http://localhost:8080/images${YOUR_PASSED_OBJECT.RELATIVE_IMG_PATH_VARIABLE}">
  • Rebuild your web application and go to localhost:PORT/images/YOUR_FILE_NAME.EXTENSION

If you have any problems, feel free to comment on this answer and I'll update it if needed.

Upvotes: 1

Amit
Amit

Reputation: 262

Assuming that you have Apache tomcat server . You will have to update the server.xml file. add

<Context  docBase="C:\your\physical\path" path="/path/for/http/url" />

inside <Host></Host> tag . Doing so , you can access any file kept inside

"C:\your\physical\path"

from your web application with the help of URL :

"http://yourdomain/path/for/http/url/somefile.someextension"

Upvotes: 0

Amer Qarabsa
Amer Qarabsa

Reputation: 6574

your src should not be the location of the file in your server, the source should be the http link which will serve your resource.

you can either configure apache to map URL to resources from specific directory then mention the mapped URL + file name in src property

or you can create a controller which fetches the resource from the specific location and return it as byte stream and in src property set the link to your controller + file name

Upvotes: 1

Related Questions