2016-11-14 108 views
1

对于一个任务,我正在练习Java的Spring MVC以创建一个Web应用程序。我已经在IDE Intellij Ultimate 2016.2.5中构建了整个项目。由于路由无效,弹簧路由获取404错误

我为此创建了一个Maven项目,为此导入了正确的和问题的依赖关系并构建它。

IDE将构建以下的目录结构:

├───src 
│ └───bas 
│  └───animalkingdom 
│   ├───config 
│   ├───controllers 
├───test 
│ └───bas 
│  └───animalkingdom 
└───web 
    ├───META-INF 
    ├───resources 
    └───WEB-INF 
     └───pages 

config包是我的配置类,从WebMvcConfigurerAdapter延伸:

包bas.animalkingdom.config;

import ... 

@Configuration 
@ComponentScan("bas.animalkingdom") 
@EnableWebMvc 
public class Config extends WebMvcConfigurerAdapter { 
    @Bean 
    public UrlBasedViewResolver setupViewResolver() { 
     UrlBasedViewResolver resolver = new UrlBasedViewResolver(); 
     resolver.setPrefix("/WEB-INF/pages/"); 
     resolver.setSuffix(".jsp"); 
     resolver.setViewClass(JstlView.class); 
     return resolver; 
    } 

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

我以为@ComponentScan必须指向所有源文件所在的主要源代码目录。

有人告诉我,我还需要一个从WebApplicationInitializer延伸的类。我从我的学校得到这一个

package bas.animalkingdom.config; 

import ... 

public class WebInitializer implements WebApplicationInitializer { 
    @Override 
    public void onStartup(ServletContext servletContext) throws ServletException { 
     AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); 
     ctx.register(Config.class); 
     ctx.setServletContext(servletContext); 

     ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); 
     servlet.addMapping("/"); 
     servlet.setLoadOnStartup(1); 
    } 
} 

这一个也在config包。

Config类在IDE中的项目结构设置中设置为Spring Application Context


在根目录下是web文件夹。在文件夹WEB-INF是一个空的web.xml文件,我被告知我不需要,因为设置将通过配置类加载。它看起来像这样:

<web-app id="WebApp_ID" version="2.4" 
     xmlns="http://java.sun.com/xml/ns/j2ee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 

</web-app> 

web文件夹的根目录下有一个index.jsp文件。

bas.animalkingdom.controllers包是我的控制器。为了测试用途变更,我只创建了一个:

package bas.animalkingdom.controllers; 

import ... 

@Controller("AnimalC") 
public class AnimalController { 
    @RequestMapping(value = "/animals", method = RequestMethod.GET) 
    public String getAnimals(ModelMap modelMap) { 
     Animal animal = new AfricanElephant(new Male(), "Body Covering", "Ename", " acolor", 123, 321); 
     modelMap.put("animal", animal); 
     return "animals"; 
    } 
} 

有了这个控制器我的预期,我可以去localhost/animals URL,并且它会加载了animals.jsp文件位于我web\WEB-INF\pages\包。

我的代码没有编译错误。

当我运行我的TomCat服务器,并打开我的浏览器去与相应的主机本地主机,index.jsp文件只是加载没有问题。该文件位于web\包中。

当我转到localhost:(port)/animals时,我刚刚收到一个404页面,并显示无法找到该页面的消息。

这是什么造成的?我已经定义了控制器设置该路线的权利?

另外,查找其他Spring MVC教程时,它们都使用不同的包装,这是否也适用?

+0

对于初学者删除您'web.xml'你不需要它,它目前防止'WebInitializer'从做其工作。 –

+0

你不需要在控制器中返回'pages/animals'吗? –

+0

@OlarAndrei为什么呢? – Bas

回答

1

所有的java类和jsps都很好,问题在于你的模块结构。基本上有两种解决问题的方法,即传统(推荐)和非常规方式。让我们开始与非常规的方式,这是更快,不建议:

A.非常规:

添加到您的Maven的战争插件,该warSourceDirectory标签,如下图所示:

<plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-war-plugin</artifactId> 
      <version>3.0.0</version> 
      <configuration> 
       <warSourceDirectory>${basedir}/web</warSourceDirectory> 
       <failOnMissingWebXml>false</failOnMissingWebXml> 
      </configuration> 
     </plugin> 

使用这种方法的缺点是,其他插件可能会给你带来意想不到的问题,例如maven-jetty-plugin不会用这种方法运行。它默认查看src/main/webapp,尽管它是可配置的。如果你遵循传统的方法,Maven的生活会更容易。

B.传统的方法:

解决之道在于有你的模块传统的行家结构,确保做到以下几点:

  1. 删除您的web.xml文件。如果行家包失败,因为缺少web.xml文件中,添加下面的插件在你的pom.xml的构建部分:

    <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-war-plugin</artifactId> 
        <version>3.0.0</version> 
        <configuration> 
         <failOnMissingWebXml>false</failOnMissingWebXml> 
        </configuration> 
    </plugin> 
    
  2. 创建文件夹结构/src目录/主/ JAVA,并把所有你的java包到这个的java目录下。如果您的包格式不正确,您可以右键单击文件夹java,然后转到标记目录 - >源根目录。

  3. 创建文件夹结构/src/test/java并将所有测试包放入java目录中。

  4. 创建一个文件夹结构/src目录/主/ web应用,并把文件夹网络的所有内容复制到Web应用目录

这样做后,您可以测试您的应用程序。您可以尝试使用码头插件与下面的配置部署Web应用程序:

<build> 
    <finalName>spring-mvc</finalName> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-war-plugin</artifactId> 
      <version>3.0.0</version> 
      <configuration> 
       <failOnMissingWebXml>false</failOnMissingWebXml> 
      </configuration> 
     </plugin> 
     <plugin> 
      <groupId>org.eclipse.jetty</groupId> 
      <artifactId>jetty-maven-plugin</artifactId> 
      <version>9.2.11.v20150529</version> 
      <configuration> 
       <scanIntervalSeconds>10</scanIntervalSeconds> 
       <webApp> 
        <contextPath>/</contextPath> 
       </webApp> 
       <httpConnector> 
        <port>8080</port> 
       </httpConnector> 
      </configuration> 
     </plugin> 
    </plugins> 
    </build> 
+0

这是一个很好的解决方案,但是您不应该在IDE中将您的目录标记为源代码或测试。您应该按照上面所述完成更改,然后直接从pom.xml文件重新导入项目。这应该刷新所有路径并正确配置项目。 –

+0

@TauraiNyamakura我甚至没有这个插件,这可能是一个问题吗? – Bas

+0

@如果你打包你的模块是一场战争,最好在你的build部分有“maven-war-plugin”插件。至于“jetty-maven-plugin”,如果你不使用它,你可以从构建部分删除它。 Jetty插件仅推荐用于开发阶段测试,如果您想快速测试您的模块,可以使用它:mvn jetty:run(启动码头并部署您的模块) –