无法访问http://localhost:8888/uploads/ url、Spring Boot、Tomcat下的静态文件

时间:2021-05-18 18:07:17

标签: spring-boot tomcat

我有以下项目文件夹结构

enter image description here

假设我有空的 /resources/static/uploads 文件夹

通过一个网站,在我的 FileService 的帮助下,添加一张图片并将其保存在 /resources/static/uploads 中

@Service
public class FileService {
    @Value("${app.upload.imgsdir:${user.home}}")
    private String uploadDir;

    public String uploadFile(MultipartFile file) {
        try {
            String FullFileName = UUID.randomUUID().toString() + '.' + file.getOriginalFilename();
            Path copyLocation = Paths.get(uploadDir + File.separator + StringUtils.cleanPath(FullFileName));
            Files.copy(file.getInputStream(), copyLocation, StandardCopyOption.REPLACE_EXISTING);

            return FullFileName;
        } catch (IOException e) {
            e.printStackTrace();
            throw new FileStorageException("Could not store file " + file.getOriginalFilename()
                    + ". Please try again!");
        }
    }

    public void delFile(String fileName) {
        try {
            Files.delete(Paths.get(uploadDir + '/' + fileName));
        } catch (IOException e) {
            throw new FileStorageException("Could not delete file " + fileName
                    + ". Please try again!");
        }
    }
}

然后如果我尝试使用 url 访问它 http://localhost:8888/uploads/f3dc9351-1c64-4d96-b084-176becc07546.unnamed.jpg 我收到以下错误

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue May 18 23:38:48 ALMT 2021
There was an unexpected error (type=Not Found, status=404).
No message available

enter image description here

Tomcat调试日志如下

2021-05-18 23:27:01.600 DEBUG 7264 --- [nio-8888-exec-5] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@36a341e3:org.apache.tomcat.util.net.NioChannel@3864b947:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49324]], Read from buffer: [0]
2021-05-18 23:27:01.600 DEBUG 7264 --- [nio-8888-exec-5] org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@36a341e3:org.apache.tomcat.util.net.NioChannel@3864b947:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49324]], Read direct from socket: [695]
2021-05-18 23:27:01.601 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.authenticator.AuthenticatorBase    : Security checking request GET /uploads/f0f46c7c-b9f2-47c7-9d75-cc23b27bc6a6.unnamed.jpg
2021-05-18 23:27:01.601 DEBUG 7264 --- [nio-8888-exec-5] org.apache.catalina.realm.RealmBase      :   No applicable constraints defined
2021-05-18 23:27:01.601 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.authenticator.AuthenticatorBase    : Not subject to any constraint
2021-05-18 23:27:01.603 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.c.C.[Tomcat].[localhost]           : Processing ErrorPage[errorCode=0, location=/error]
2021-05-18 23:27:01.612 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(freemarker.template.Configuration)
2021-05-18 23:27:01.612 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.613 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(freemarker.template$Configuration)
2021-05-18 23:27:01.614 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.615 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(com.samskivert.mustache.Template)
2021-05-18 23:27:01.615 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.616 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(com.samskivert.mustache$Template)
2021-05-18 23:27:01.616 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.617 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(groovy.text.TemplateEngine)
2021-05-18 23:27:01.617 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.617 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(groovy.text$TemplateEngine)
2021-05-18 23:27:01.618 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.618 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(org.thymeleaf.spring5.SpringTemplateEngine)
2021-05-18 23:27:01.619 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.619 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(org.thymeleaf.spring5$SpringTemplateEngine)
2021-05-18 23:27:01.619 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.620 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(org.apache.jasper.compiler.JspConfig)
2021-05-18 23:27:01.620 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.621 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(org.apache.jasper.compiler$JspConfig)
2021-05-18 23:27:01.621 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.621 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       : getResource(uploads/error/404.html)
2021-05-18 23:27:01.621 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :   Delegating to parent classloader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@5cf487c3
2021-05-18 23:27:01.621 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :   --> Resource not found, returning null
2021-05-18 23:27:01.622 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(freemarker.template.Configuration)
2021-05-18 23:27:01.622 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.623 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(freemarker.template$Configuration)
2021-05-18 23:27:01.623 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.623 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(com.samskivert.mustache.Template)
2021-05-18 23:27:01.624 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.624 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(com.samskivert.mustache$Template)
2021-05-18 23:27:01.624 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.624 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(groovy.text.TemplateEngine)
2021-05-18 23:27:01.625 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.625 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(groovy.text$TemplateEngine)
2021-05-18 23:27:01.625 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.626 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(org.thymeleaf.spring5.SpringTemplateEngine)
2021-05-18 23:27:01.626 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.626 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(org.thymeleaf.spring5$SpringTemplateEngine)
2021-05-18 23:27:01.626 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.627 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(org.apache.jasper.compiler.JspConfig)
2021-05-18 23:27:01.627 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.627 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     findClass(org.apache.jasper.compiler$JspConfig)
2021-05-18 23:27:01.627 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :     --> Returning ClassNotFoundException
2021-05-18 23:27:01.628 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       : getResource(uploads/error/4xx.html)
2021-05-18 23:27:01.628 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :   Delegating to parent classloader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@5cf487c3
2021-05-18 23:27:01.628 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.loader.WebappClassLoaderBase       :   --> Resource not found, returning null
2021-05-18 23:27:01.635 DEBUG 7264 --- [nio-8888-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    :  Disabling the response for further output
2021-05-18 23:27:01.637 DEBUG 7264 --- [nio-8888-exec-5] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@36a341e3:org.apache.tomcat.util.net.NioChannel@3864b947:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49324]], Read from buffer: [0]
2021-05-18 23:27:01.637 DEBUG 7264 --- [nio-8888-exec-5] org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@36a341e3:org.apache.tomcat.util.net.NioChannel@3864b947:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49324]], Read direct from socket: [0]
2021-05-18 23:27:01.637 DEBUG 7264 --- [nio-8888-exec-5] org.apache.tomcat.util.net.NioEndpoint   : Registered read interest for [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@36a341e3:org.apache.tomcat.util.net.NioChannel@3864b947:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49324]]

但是如果我重新启动我的嵌入式 Tomcat 服务器,我就可以访问它

服务器重启后的Tomat调试日志

2021-05-18 23:28:11.581 DEBUG 17056 --- [o-8888-Acceptor] o.apache.tomcat.util.threads.LimitLatch  : Counting up[http-nio-8888-Acceptor] latch=1
2021-05-18 23:28:11.582 DEBUG 17056 --- [o-8888-Acceptor] o.apache.tomcat.util.threads.LimitLatch  : Counting up[http-nio-8888-Acceptor] latch=2
2021-05-18 23:28:11.606 DEBUG 17056 --- [nio-8888-exec-1] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@4ef2e77e:org.apache.tomcat.util.net.NioChannel@2945f6ff:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49525]], Read from buffer: [0]
2021-05-18 23:28:11.606 DEBUG 17056 --- [nio-8888-exec-1] org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@4ef2e77e:org.apache.tomcat.util.net.NioChannel@2945f6ff:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49525]], Read direct from socket: [721]
2021-05-18 23:28:11.619 DEBUG 17056 --- [nio-8888-exec-1] org.apache.tomcat.util.http.Parameters   : Set query string encoding to UTF-8
2021-05-18 23:28:11.623 DEBUG 17056 --- [nio-8888-exec-1] o.a.c.authenticator.AuthenticatorBase    : Security checking request GET /uploads/f0f46c7c-b9f2-47c7-9d75-cc23b27bc6a6.unnamed.jpg
2021-05-18 23:28:11.624 DEBUG 17056 --- [nio-8888-exec-1] org.apache.catalina.realm.RealmBase      :   No applicable constraints defined
2021-05-18 23:28:11.626 DEBUG 17056 --- [nio-8888-exec-1] o.a.c.a.jaspic.AuthConfigFactoryImpl     : Loading persistent provider registrations from [C:\Temp\tomcat.8888.589837828379523203\conf\jaspic-providers.xml]
2021-05-18 23:28:11.626 DEBUG 17056 --- [nio-8888-exec-1] o.a.c.authenticator.AuthenticatorBase    : Not subject to any constraint
2021-05-18 23:28:11.627  INFO 17056 --- [nio-8888-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-05-18 23:28:11.627  INFO 17056 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-05-18 23:28:11.628  INFO 17056 --- [nio-8888-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2021-05-18 23:28:11.667 DEBUG 17056 --- [nio-8888-exec-1] o.a.tomcat.util.net.SocketWrapperBase    : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@4ef2e77e:org.apache.tomcat.util.net.NioChannel@2945f6ff:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49525]], Read from buffer: [0]
2021-05-18 23:28:11.667 DEBUG 17056 --- [nio-8888-exec-1] org.apache.tomcat.util.net.NioEndpoint   : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@4ef2e77e:org.apache.tomcat.util.net.NioChannel@2945f6ff:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49525]], Read direct from socket: [0]
2021-05-18 23:28:11.667 DEBUG 17056 --- [nio-8888-exec-1] org.apache.tomcat.util.net.NioEndpoint   : Registered read interest for [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper@4ef2e77e:org.apache.tomcat.util.net.NioChannel@2945f6ff:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8888 remote=/0:0:0:0:0:0:0:1:49525]]

enter image description here

我的 WebSecurityConfig 类在下面

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.exceptionHandling()
//                .accessDeniedHandler(accessDeniedHandler())
                .authenticationEntryPoint(authenticationEntryPoint())
        ;

        // Disable CSRF (cross site request forgery)
        httpSecurity
                .csrf().disable()
                .formLogin().disable()
                .httpBasic().disable();

        // No session will be created or used by spring security
        httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // Entry points
        httpSecurity.authorizeRequests()
                .antMatchers("/api/user/signin").permitAll()
                .antMatchers("/api/user/signup").permitAll()
                .antMatchers("/api/course/list").permitAll()
                .antMatchers("/api/teacher/list").permitAll()
                .antMatchers("/uploads/**").permitAll()
                // Disallow everything else..
                .anyRequest().authenticated();

//        httpSecurity.authorizeRequests().anyRequest().permitAll();

        // Apply JWT
        httpSecurity.apply(new JwtTokenFilterConfigurer(jwtTokenProvider));

        // Optional, if you want to test the API from a browser
        // http.httpBasic();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(12);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return new CustomAuthenticationEntryPoint();
    }

    @Bean
    public AccessDeniedHandler accessDeniedHandler() {
        return new CustomAccessDeniedHandler();
    }
}

我的 MvcConfig 类

@Configuration
public class MvcConfig implements WebMvcConfigurer {
    @Value("${app.upload.imgsdir}")
    private String uploadPath;

    private static final String[] CLASSPATH_RESOURCE_LOCATIONS =
            {
                    "classpath:/static/uploads",
            };

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS)
                .addResourceLocations("file:///" + uploadPath + "/")
        ;
    }
}

1 个答案:

答案 0 :(得分:0)

解决方案:

在 MvcConfig 类更改行

registry.addResourceHandler("/**")

registry.addResourceHandler("/**","/uploads/**")
相关问题