2016-11-14 120 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(啓動碼頭並部署您的模塊) –