Spring MVC - Servlet调度程序抛出异常:java.lang.StackOverflowError

时间:2016-01-08 14:58:32

标签: java angularjs spring spring-mvc

我有一个名为A的AngularJS + Spring MVC应用程序。这个Web应用程序已被克隆(ctrl + c& ctrl + v在项目文件夹中)到另一个名为B的文件中。

尝试同时运行它们(自然地)具有相同的行为。

我的目标是简化A但我在第一步陷入困境,我希望对包含.html个文件的文件夹进行一些重构。

树文件夹如下:

src/main/webapp
           |--- WEB-INF/
           |--- META-INF/
           |--- static/
                   |--- js/
                   |--- css/
                   |--- index.html
                   |--- sth.html

B的转变是:

src/main/webapp
           |--- META-INF/
           |--- js/
           |--- css/
           |--- index.html
           |--- sth.html

简单地说,我将static文件夹中的所有资源都提升了一级。

下一步是从旧版本开始调整A WebMvcConfigurerAdapter(是的,一旦解决了,我会做一个更好的组织代码...... ARG !!!):

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "my.package.name")
public class Configurations extends WebMvcConfigurerAdapter {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);

        viewResolver.setPrefix("/static/");
        viewResolver.setSuffix(".html");

        registry.viewResolver(viewResolver);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //resources locations

        // html
        registry.addResourceHandler("static/**").addResourceLocations("/static/");
        registry.addResourceHandler("static/modals/**").addResourceLocations("/static/modals/");

        // css
        registry.addResourceHandler("css/**").addResourceLocations("/static/css/");
        registry.addResourceHandler("css/bootstrap/**").addResourceLocations("/static/css/bootstrap/");
        registry.addResourceHandler("js/fullcalendar/dist/**").addResourceLocations("/static/js/fullcalendar/dist/");

        // scripts
        registry.addResourceHandler("js/**").addResourceLocations("/static/js/");
        registry.addResourceHandler("js/jquery/**").addResourceLocations("/static/js/jquery/");
        registry.addResourceHandler("js/bootstrap/**").addResourceLocations("/static/js/bootstrap/");
        registry.addResourceHandler("js/bootstrap/ui-bootstrap/**").addResourceLocations("/static/js/bootstrap/ui-bootstrap/");
        registry.addResourceHandler("js/bootstrap/umd/**").addResourceLocations("/static/js/bootstrap/umd/");
        registry.addResourceHandler("js/angular/**").addResourceLocations("/static/js/angular/");
        registry.addResourceHandler("js/angular/animate/**").addResourceLocations("/static/js/angular/animate/");
        registry.addResourceHandler("js/angular/ui-router/release/**").addResourceLocations("/static/js/angular/ui-router/release/");
        registry.addResourceHandler("js/angular-ui-calendar/src/**").addResourceLocations("/static/js/angular-ui-calendar/src/");
        registry.addResourceHandler("js/fullcalendar/dist/**").addResourceLocations("/static/js/fullcalendar/dist/");
        registry.addResourceHandler("js/moment/**").addResourceLocations("/static/js/moment/");
        registry.addResourceHandler("js/angular-ui-grid/**").addResourceLocations("/static/js/angular-ui-grid/");

        // custom
        registry.addResourceHandler("js/service/**").addResourceLocations("/static/js/service/");
        registry.addResourceHandler("js/controller/**").addResourceLocations("/static/js/controller/");
        registry.addResourceHandler("js/controller/modals/**").addResourceLocations("/static/js/controller/modals/");
    }

}

换一个新的B:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "my.package.name")
public class Configurations extends WebMvcConfigurerAdapter {

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);

        viewResolver.setPrefix("/");
        viewResolver.setSuffix(".html");

        registry.viewResolver(viewResolver);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //resources locations

        // html
        registry.addResourceHandler("/**").addResourceLocations("/");

        // css
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/css/bootstrap/**").addResourceLocations("/css/bootstrap/");
        registry.addResourceHandler("/js/fullcalendar/dist/**").addResourceLocations("/js/fullcalendar/dist/");

        // scripts
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/js/jquery/**").addResourceLocations("/js/jquery/");
        registry.addResourceHandler("/js/bootstrap/**").addResourceLocations("/js/bootstrap/");
        registry.addResourceHandler("/js/bootstrap/ui-bootstrap/**").addResourceLocations("/js/bootstrap/ui-bootstrap/");
        registry.addResourceHandler("/js/bootstrap/umd/**").addResourceLocations("/js/bootstrap/umd/");
        registry.addResourceHandler("/js/angular/**").addResourceLocations("/js/angular/");
        registry.addResourceHandler("/js/angular/animate/**").addResourceLocations("/js/angular/animate/");
        registry.addResourceHandler("/js/angular/ui-router/release/**").addResourceLocations("/js/angular/ui-router/release/");
        registry.addResourceHandler("/js/angular-ui-calendar/src/**").addResourceLocations("/js/angular-ui-calendar/src/");
        registry.addResourceHandler("/js/fullcalendar/dist/**").addResourceLocations("/js/fullcalendar/dist/");
        registry.addResourceHandler("/js/moment/**").addResourceLocations("/js/moment/");
        registry.addResourceHandler("/js/angular-ui-grid/**").addResourceLocations("/js/angular-ui-grid/");

        // custom
        registry.addResourceHandler("/js/service/**").addResourceLocations("/js/service/");
        registry.addResourceHandler("/js/controller/**").addResourceLocations("/js/controller/");
    }

}

如图所示,我在每条路径上删除了static/前缀。

一旦运行,浏览器的控制台会递归地向我Error 500发送请求sth,尽管成功向我显示index.html

GET http://localhost:8080/MyWebApp/sth 500 (Internal Server Error)

而Tomcat正在记录此异常:

    SEVERE: Servlet.service() for servlet dispatcher threw exception
    java.lang.StackOverflowError
        at javax.servlet.ServletRequestWrapper.getRemoteAddr(ServletRequestWrapper.java:221)
        at javax.servlet.ServletRequestWrapper.getRemoteAddr(ServletRequestWrapper.java:221)
        at javax.servlet.ServletRequestWrapper.getRemoteAddr(ServletRequestWrapper.java:221)
// lots of times...

    at org.springframework.web.servlet.FrameworkServlet.publishRequestHandledEvent(FrameworkServlet.java:1075)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:486)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:411)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)
        at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
        at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
        at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1244)
        at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:748)
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:486)
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:411)
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)

//To the infinity and beyond! (cit.)... unless tomcat shutdown

这是索引控制器:

@Controller
@RequestMapping("/")
public class IndexController {

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView getIndexPage() {
        return new ModelAndView("index");
    }

}

管理sth

的控制器
@Controller
public class TemplateController {

    @RequestMapping(value = "/sth")
    public ModelAndView getGrid() {
        return new ModelAndView("sth");
    }

}
angular.ui文件中的

app.js路由器:

var app = angular.module('MyWebApp', [
    'ui.router',
    'ui.calendar',
    'ngAnimate',
    'ui.bootstrap',
    'ui.grid'
]);

//globals
app.value('baseUrl', '/MyWebApp');

app.config(function ($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/sth');

    $stateProvider.state('sth', {
        url: '/sth',
        templateUrl: 'sth',
        controller: 'sthCtrl',
        controllerAs: 'sth'
    });

});

,最后是sthCtrl文件

app.controller('sthCtrl', function ($http, baseUrl) {
    var scope = this;
    scope.users = [];
    scope.structures = [];

    $http.get(baseUrl + '/users').then(function (userResp) {
        scope.users = userResp.data;
    });

    $http.get(baseUrl + '/structures').then(function (structureResp) {
        scope.structures = structureResp.data;
    });

});

我必须错过一些我看不到的东西......但是,我有一些嫌疑人:

1)在Configurations课程内:我可能忘记了什么; 2)这是一个前端结构问题:创建static文件夹并移动所有以前的人群(在Configurations类中也改变路径)“自动”Error 500消失,我可以看到我的HTML! (OMG)所以我想如果AngularJS需要static文件夹,如果我不想要,我必须告诉它...但是Tomcat上的例外仍然是(废话......)

对AngularJS和Spring MVC的经验很少,我无法解决我所缺少的问题。

1 个答案:

答案 0 :(得分:0)

您需要返回一个字符串,该字符串将被View解析为ViewResolver,尝试这样的方法以避免无限循环:

 @RequestMapping(value = "/sth")
  public String getGrid() {
    return "someThing";
}