Home > Software design >  Spring MVC - Unable to load images in controller
Spring MVC - Unable to load images in controller

Time:11-14

UPDATE:

I got it to work by using ClassPathResource as M. Deinum had suggested. I've also removed my WebMvcConfig, I'm not sure if that is related to the problem though.

@RequestMapping(value = "/image", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
    public @ResponseBody byte[] getImage() throws IOException {
        ClassPathResource classPathResource = new ClassPathResource("static/images/user-default.png");
        InputStream in = classPathResource.getInputStream();
        return IOUtils.toByteArray(in);
    }

I'm working on a Spring Boot project with Spring MVC architecture and Spring Security. I can't pinpoint where I mis-configured my MVC configurations, I have a problem where my controller is unable to find the image I specified.

Here's my controller which serves images:

@Controller
public class ImageController {
    @Autowired
    private ServletContext servletContext;
    
    @RequestMapping(value = "/image", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
    public @ResponseBody byte[] getImage() throws IOException {
        InputStream in = servletContext.getResourceAsStream("/images/user-default.png");
        return IOUtils.toByteArray(in);
    }
}

Through debugging I found that the InputStream resulted in null. However, I'm actually able to load the image on my browser through a Thymeleaf template:

<!DOCTYPE html>
<html lang="en"
      xmlns:th="http://www.thymeleaf.org">
<!--omitted for brevity-->
<img th:src="@{/images/quiz-academic.png}"/> <!--This WORKS, image is VISIBLE in the browser-->
<!--omitted for brevity-->
</html>

Or by accessing it with a direct path:

http://localhost:8080/images/user-default.png (This WORKS, image is VISIBLE in the browser)

I'm confused as to why my controller is not able to pick up the image yet the two above methods (Thymeleaf, direct path) could do that without any problem.

Here's my MVC Configuration:

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/resources/", "classpath:/static/", "classpath:/images/");
    }
}

Here's my Security configuration:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests().and().exceptionHandling().accessDeniedPage("/error");
        http.headers().frameOptions().disable();
        http.authorizeRequests()
                .antMatchers("/admin/**").access("hasAnyRole('ROLE_ADMIN')")
                .antMatchers("/user").access("hasAnyRole('ROLE_ADMIN', 'ROLE_USER')")
                .antMatchers("/css/**").permitAll()
                .antMatchers("/js/**").permitAll()
                .antMatchers("/images/**").permitAll()
                .antMatchers("/image").permitAll()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated();
                /* login/logout configuration omitted for brevity */
    }
}

And my project directories:

src/main/java/com/kjnts/springwebapp/config/WebSecurityConfig.java
src/main/java/com/kjnts/springwebapp/config/WebMvcConfig.java
src/main/java/com/kjnts/springwebapp/controller/ImageController.java
src/main/resources/static/images/user-default.png
src/main/resources/templates/user-profile.html

If you are wondering, I don't use XML for Spring configuration.

Thank you.

CodePudding user response:

Figured I should post an answer so I could mark it as answered.


I got it to work by using ClassPathResource as M. Deinum had suggested. I've also removed my WebMvcConfig, I'm not sure if that is related to the problem though.

@RequestMapping(value = "/image", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
    public @ResponseBody byte[] getImage() throws IOException {
        ClassPathResource classPathResource = new ClassPathResource("static/images/user-default.png");
        InputStream in = classPathResource.getInputStream();
        return IOUtils.toByteArray(in);
    }
  • Related