使用静态内容的SpringBoot项目的正确目录结构是什么

时间:2017-08-04 14:12:27

标签: java angularjs spring-boot

我正在试图理解为什么我的SpringBoot webApp无法在浏览器中呈现。这就是我的调试日志所说的:

2017-08-04 14:54:24.760 DEBUG 23863 --- [tp1027569178-15] o.s.w.servlet.view.InternalResourceView  : Forwarding to resource [/views/tictactoe.html] in InternalResourceView 'tictactoe'
2017-08-04 14:54:24.762 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/views/tictactoe.html]
2017-08-04 14:54:24.766 DEBUG 23863 --- [tp1027569178-15] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /views/tictactoe.html
2017-08-04 14:54:24.768 DEBUG 23863 --- [tp1027569178-15] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/views/tictactoe.html]
2017-08-04 14:54:24.768 DEBUG 23863 --- [tp1027569178-15] o.s.w.s.handler.SimpleUrlHandlerMapping  : Matching patterns for request [/views/tictactoe.html] are [/**]
2017-08-04 14:54:24.770 DEBUG 23863 --- [tp1027569178-15] o.s.w.s.handler.SimpleUrlHandlerMapping  : URI Template variables for request [/views/tictactoe.html] are {}
2017-08-04 14:54:24.771 DEBUG 23863 --- [tp1027569178-15] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapping [/views/tictactoe.html] to HandlerExecutionChain with handler [org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler@47b52f9] and 1 interceptor
2017-08-04 14:54:24.771 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/views/tictactoe.html] is: -1
2017-08-04 14:54:24.772 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2017-08-04 14:54:24.777 DEBUG 23863 --- [tp1027569178-15] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2017-08-04 14:54:24.778 DEBUG 23863 --- [tp1027569178-15] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
2017-08-04 14:54:24.778 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/error] is: -1
2017-08-04 14:54:24.784 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : Rendering view [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView@41ee3720] in DispatcherServlet with name 'dispatcherServlet'
2017-08-04 14:54:24.795 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-08-04 14:54:24.802 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-08-04 14:54:24.802 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-08-04 14:54:24.804 DEBUG 23863 --- [tp1027569178-15] o.s.web.servlet.DispatcherServlet        : Successfully completed request

我不确定我的目录结构是否正确。这就是它的样子:enter image description here

enter code here

我的网页/角度可能有问题吗?

<!DOCTYPE html>
<html ng-app="myApp" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
    <title>TicTacToe</title>
    <link type="text/css" href="css/design.css" rel="stylesheet" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.js"></script>
    <script src="js/tictactoe.js"></script>

</head>
<body ng-controller="displayPageController">
<div id="player-1">PLAYER 1<br/>
    {{gameBoardDto.player1}}<span style="display:inline-block"/>
</div>
<div id="game">

    <div id="top-left" ng-click='playPage("topleft")'>{{gameBoardDto.topleft}}<span style="display:inline-block"/></div>
    <div id="top" ng-click='playPage("top")'>{{gameBoardDto.top}}<span style="display:inline-block"/></div>
    <div id="top-right" ng-click='playPage("topright")'>{{gameBoardDto.topright}}<span style="display:inline-block"/></div>
    <div id="left" ng-click='playPage("left")'>{{gameBoardDto.left}}<span style="display:inline-block"/></div>
    <div id="middle" ng-click='playPage("middle")'>{{gameBoardDto.middle}}<span style="display:inline-block"/></div>
    <div id="right" ng-click='playPage("right")'>{{gameBoardDto.right}}<span style="display:inline-block"/></div>
    <div id="bottom-left" ng-click='playPage("bottomleft")'>{{gameBoardDto.bottomleft}}<span style="display:inline-block"/></div>
    <div id="bottom" ng-click='playPage("bottom")'>{{gameBoardDto.bottom}}<span style="display:inline-block"/></div>
    <div id="bottom-right" ng-click='playPage("bottomright")'>{{gameBoardDto.bottomright}}<span style="display:inline-block"/></div>
</div>
<div id="player-2">PLAYER 2<br/>
    {{gameBoardDto.player2}}<span style="display:inline-block"/>
</div>
</body>
</html>

这是我的Spring MVC conf: 包裹申请;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter {
    //This allows html pages to be resolved
    @Bean
    public ViewResolver getViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/views/");
        resolver.setSuffix(".html");
        return resolver;
    }
    /*
    This allows resources such as .js .css etc to be resolved
    Here an example of how the views are linked to the resources
    <link rel="stylesheet" type="text/css" href="resources/css/design.css"/>
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

知道如何解决这个问题?我尝试访问时,我的浏览器只会出现错误:

enter image description here

更新 我做了安迪威尔金森建议,但没有真正的工作,但我做了一些修改,现在我有页面服务但javascript无法正常工作。

这就是我所做的:   - 我从@EnableWebMvc删除了MvcConfiguration   - 从MvcConfiguration中删除了addResourceHandlers和configureDefaultServletHandling   - 从MvcConfiguration中删除了ViewResolver @Bean方法   - 我在compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'添加了一个依赖项   - 我创建了一个名为templates的目录,并将.html文件移动到那里

现在浏览器显示了这个:

[![enter code here][3]][3]

这是日志输出的内容:

017-08-06 13:58:54.397 DEBUG 17581 --- [qtp758944736-18] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2017-08-06 13:58:54.402 DEBUG 17581 --- [qtp758944736-19] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/error] is: -1
2017-08-06 13:58:54.402 DEBUG 17581 --- [qtp758944736-18] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2017-08-06 13:58:54.403 DEBUG 17581 --- [qtp758944736-18] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
2017-08-06 13:58:54.403 DEBUG 17581 --- [qtp758944736-18] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/error] is: -1
2017-08-06 13:58:54.508 DEBUG 17581 --- [qtp758944736-18] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Written [{timestamp=Sun Aug 06 13:58:54 BST 2017, status=404, error=Not Found, message=Not Found, path=/resources/css/design.css}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@15adc6be]
2017-08-06 13:58:54.508 DEBUG 17581 --- [qtp758944736-18] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-08-06 13:58:54.508 DEBUG 17581 --- [qtp758944736-18] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-08-06 13:58:54.509 DEBUG 17581 --- [qtp758944736-18] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-08-06 13:58:54.509 DEBUG 17581 --- [qtp758944736-18] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-08-06 13:58:54.510 DEBUG 17581 --- [qtp758944736-19] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Written [{timestamp=Sun Aug 06 13:58:54 BST 2017, status=404, error=Not Found, message=Not Found, path=/resources/javascript/tictactoe.js}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@15adc6be]
2017-08-06 13:58:54.511 DEBUG 17581 --- [qtp758944736-19] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-08-06 13:58:54.511 DEBUG 17581 --- [qtp758944736-19] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-08-06 13:58:54.511 DEBUG 17581 --- [qtp758944736-19] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-08-06 13:58:54.511 DEBUG 17581 --- [qtp758944736-19] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-08-06 13:58:54.700 DEBUG 17581 --- [qtp758944736-21] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/resources/javascript/tictactoe.js]
2017-08-06 13:58:54.701 DEBUG 17581 --- [qtp758944736-21] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /resources/javascript/tictactoe.js
2017-08-06 13:58:54.701 DEBUG 17581 --- [qtp758944736-21] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/resources/javascript/tictactoe.js]
2017-08-06 13:58:54.701 DEBUG 17581 --- [qtp758944736-21] o.s.w.s.handler.SimpleUrlHandlerMapping  : Matching patterns for request [/resources/javascript/tictactoe.js] are [/**]
2017-08-06 13:58:54.701 DEBUG 17581 --- [qtp758944736-21] o.s.w.s.handler.SimpleUrlHandlerMapping  : URI Template variables for request [/resources/javascript/tictactoe.js] are {}
2017-08-06 13:58:54.701 DEBUG 17581 --- [qtp758944736-21] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapping [/resources/javascript/tictactoe.js] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver@453002f1]]] and 1 interceptor
2017-08-06 13:58:54.701 DEBUG 17581 --- [qtp758944736-21] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/resources/javascript/tictactoe.js] is: -1
2017-08-06 13:58:54.702 DEBUG 17581 --- [qtp758944736-21] o.s.web.servlet.DispatcherServlet        : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2017-08-06 13:58:54.703 DEBUG 17581 --- [qtp758944736-21] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2017-08-06 13:58:54.704 DEBUG 17581 --- [qtp758944736-21] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
2017-08-06 13:58:54.704 DEBUG 17581 --- [qtp758944736-21] o.s.web.servlet.DispatcherServlet        : Last-Modified value for [/error] is: -1
2017-08-06 13:58:54.711 DEBUG 17581 --- [qtp758944736-21] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Written [{timestamp=Sun Aug 06 13:58:54 BST 2017, status=404, error=Not Found, message=Not Found, path=/resources/javascript/tictactoe.js}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@15adc6be]
2017-08-06 13:58:54.711 DEBUG 17581 --- [qtp758944736-21] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-08-06 13:58:54.711 DEBUG 17581 --- [qtp758944736-21] o.s.web.servlet.DispatcherServlet        : Successfully completed request
2017-08-06 13:58:54.711 DEBUG 17581 --- [qtp758944736-21] o.s.web.servlet.DispatcherServlet        : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2017-08-06 13:58:54.711 DEBUG 17581 --- [qtp758944736-21] o.s.web.servlet.DispatcherServlet        : Successfully completed request

如果有人想看看这个项目: https://github.com/SFRJ/tictactoe(Note:github中的版本在使用gradlew运行但不从.jar运行时有效。

2 个答案:

答案 0 :(得分:0)

@EnableWebMvc关闭Spring Boot的Spring MVC自动配置。这包括将其配置为提供来自classpath:static/的静态资源(这是src/main/resources/static中的资源最终结束的位置。您还有一些Spring Boot将为您配置的其他配置位。

这应该可以帮助你恢复正常运行:

  • @EnableWebMvc
  • 移除MvcConfiguration
  • addResourceHandlers
  • 删除configureDefaultServletHandlingMvcConfiguration的覆盖
  • ViewResolver
  • 中删除@Bean MvcConfiguration方法
  • 假设其内容是您问题中的HTML,请将tictactoe.html移至src/main/resources/static

答案 1 :(得分:-2)

尝试将静态文件夹移动到项目根目录,它将成为src的兄弟。然后,Tomcat将使用默认的Servlet提供内容。