错误404:访问/WEB-INF/views/sendMessage.jsp的问题。原因:未找到

时间:2014-11-18 14:24:51

标签: java spring jsp spring-mvc jetty

我一直在努力奋斗数小时。我无法使用我的简单Jetty + Spring MVC + JSP Web应用程序。

这是我项目的目录结构:

spring-form-utf-8-test
|-- pom.xml
|-- src
|   `-- main
|       |-- java
|       |   |-- com
|       |   |   `-- example
|       |   |       |-- beans
|       |   |       |   `-- forms
|       |   |       |       `-- MessageForm.java
|       |   |       |-- config
|       |   |       |   `-- WebMvcConfig.java
|       |   |       `-- controller
|       |   |           `-- FormController.java
|       |   `-- Main.java
|       |-- resources
|       `-- webapp
|           |-- images
|           |   `-- kitty.jpg
|           `-- WEB-INF
|               `-- views
|                   `-- sendMessage.jsp
`-- target

问题在于,当我尝试访问http://localhost:8080时,我收到以下错误。

Error 404

我从命令行运行服务器:

java -jar target\spring-form-utf-8-test-1.0-SNAPSHOT.jar

控制器看起来像这样,我没有看到映射有什么问题:

package com.example.controller;

import com.example.beans.forms.MessageForm;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


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

    @ModelAttribute("message")
    public MessageForm createMessageForm() {
        return new MessageForm();
    }

    @RequestMapping(method = RequestMethod.GET)
    public String sendForm() {
        return "sendMessage";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String processForm(@ModelAttribute("message") @Valid final MessageForm message,
        final BindingResult result,
        final Model model) {
        return "sendMessage";
    }
}

带注释的Web应用程序上下文如下所示

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
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
@ComponentScan("com.example.controller")
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("images/**").addResourceLocations("images/");
    }

    @Bean
    public InternalResourceViewResolver setupViewResolver() {
        final InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");

        return resolver;
    }
}

运行Jetty服务器实例的主类看起来像这样。

import java.io.IOException;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

import org.springframework.core.io.ClassPathResource;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.servlet.DispatcherServlet;

public class Main {
    public static void main(String[] args) {
        final Server server = new Server(8080);
        final ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        servletContextHandler.setErrorHandler(null);
        servletContextHandler.setContextPath("/");

        final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("com.example.config");
        context.getEnvironment().setDefaultProfiles("dev");

        servletContextHandler.addServlet(new ServletHolder(new DispatcherServlet(context)), "/*");
        servletContextHandler.addEventListener(new ContextLoaderListener(context));


        try {
        servletContextHandler.setResourceBase(new ClassPathResource("webapp").getURI().toString());
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }

        server.setHandler(servletContextHandler);
        try {
            server.start();
            server.join();
        } catch (final InterruptedException e) {
            throw new RuntimeException(e);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }
}

访问静态资源http://localhost:8080/images/kitty.jpg没有任何问题。此外,如果我将控制器更改为不映射到视图,而是使用@ResponseBody注释,那么我可以在浏览器中看到结果。

我尝试添加org.apache.jasper.servlet.JspServlet实例,就像this blog上显示的那样,但这并没有带来任何结果。错误消息是相同的。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

经过长时间的研究后,我找到了this stackoverflow post。

在我的情况下,将import org.eclipse.jetty.servlet.ServletContextHandler更改为org.eclipse.jetty.webapp.WebAppContext就像魅力一样。

最后,Main.java文件如下所示。

import java.io.IOException;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;

import org.springframework.core.io.ClassPathResource;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.servlet.DispatcherServlet;

public class Main {
    public static void main(String[] args) {
        final Server server = new Server(8080);
        final WebAppContext webAppContext = new WebAppContext();
        webAppContext.setErrorHandler(null);
        webAppContext.setContextPath("/");

        final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("com.example.config");
        context.getEnvironment().setDefaultProfiles("dev");

        webAppContext.addServlet(new ServletHolder(new DispatcherServlet(context)), "/");
        webAppContext.addEventListener(new ContextLoaderListener(context));


        try {
            webAppContext.setResourceBase(new ClassPathResource("webapp").getURI().toString());
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }

        server.setHandler(webAppContext);
        try {
            server.start();
            server.join();
        } catch (final InterruptedException e) {
            throw new RuntimeException(e);
        } catch (final Exception e) {
            throw new RuntimeException(e);
        }
    }
}

在这行代码中将/*更改为/也很重要:

webAppContext.addServlet(new ServletHolder(new DispatcherServlet(context)), "/");