使用 spring 控制器服务时出现 404

getting 404 when consumiing spring controller service

我创建了一个 spring 应用程序(Spring 版本 3.2.8)。该应用程序运行良好,但我面临的问题是,当我尝试通过 url 使用控制器服务时,出现 404 错误

下面给出了我尝试通过浏览器 url 使用的 url,我希望它 return 一个 test 字符串

http://localhost/Spring3Sample/user/getPersonDetails

我的代码如下

调度员-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
          p:prefix="/" p:suffix=".jsp" />
</beans>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.controllers" />

</beans>

UserController.java

package com.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/user")
public class UserController {

    private static final String APP_JSON = "application/json";

    @RequestMapping(value = "/getPersonDetails", method = RequestMethod.GET, produces = APP_JSON)
    public String getPersonDetails() {
        return "test";
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>Spring3Sample</display-name>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
</web-app>

谁能告诉我一些解决方案

更新 1

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
    <display-name>Spring3Sample</display-name>
:
:
:

您已将 DispatcherServlet 与 URL 模式映射为

 <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

无论何时您想要请求控制器方法,您都必须将此 URL 模式添加到请求中。这样 Spring 就会找到正确的映射。

所以将您的请求URL更改为以下内容:-

http://localhost:8080/Spring3Sample/user/getPersonDetails.do

如你所料 return 一个 test string:

添加

@ResponseBody

你的控制器方法的注释。这样 Spring 就不会查找名称为 test 的 JSP 页面,而是 return test as String.

编辑:

来自聊天中的讨论:

你也不见了<mvc:annotation-driven /> in applicationContext.xml

从请求中删除 *.do URL:

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

首先在 Spring MVC 手册中

The @Controller annotation acts as a stereotype for the annotated class, indicating its role. The dispatcher scans such annotated classes for mapped methods and detects @RequestMapping annotations (see the next section).

所以删除这个

@RequestMapping("/user")

因为下一个没有意义

@RequestMapping("/user/getPersonDetails")

你应该注意到我在 url 中添加了“/user”。 你也不是 return 任何 jSon。首先,如果我是你,我会用我在这个答案中输入的字符串更改第二个请求映射(在方法 getUserDetails 上)。

而且您好像错过了配置文件... 在 web.xml

中检查此字符串
<url-pattern>*.do</url-pattern>

它只会发送 url 结尾带有“.do”的文件。

观察您的 applicationContext.xml 后,我发现您遗漏了 <mvc:annotation-driven/> 您的更新代码如下所示

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd"
               http://www.springframework.org/schema/mvc   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">                                            

    <context:component-scan base-package="com.controllers" />
    <mvc:annotation-driven/>  

</beans>

Explanation

<annotation-driven /> 意味着您可以定义 spring beans 依赖关系,而不必实际指定 xml 中的一堆元素或实现接口或扩展基础 class.Means @Controller 告诉 spring 指定的 class 包含处理 http 请求的方法,而无需实现 Controller 接口或扩展实现控制器的子class。

<context:component-scan base-package="com.controllers" /> 告诉 spring 它应该在 class 路径中搜索 com.controllers 下的所有 class 并查看每个 class 查看它是否有 @Controller、@Repository、@Service 或 @Component,如果有,则 Spring 将向 bean 工厂注册 class,就像您在中定义的一样xml 个配置文件

根据用户评论

do we need both applicationContext.xml and dispatcher-servlet.xml

实际上 Spring 允许您在父子层次结构中定义多个上下文。

applicationContext.xml 为根 webapp 上下文定义 beans 意味着与 webapp 关联的上下文。

dispatcher-servlet.xml 为一个 servlet 的应用程序上下文定义 bean。 webapp 中可以有很多 dispatcher-servlet.xml,即 servlet1-servlet.xml 用于 servlet spring1,spring2-servlet.xml 用于 servlet spring2

note:: Beans in spring-servlet.xml can reference beans in applicationContext.xml, but not vice versa.

我将其添加到扩展 WebMvcConfigurer:

的配置 class
  @Bean
    public ViewResolver viewResolver() {
        final InternalResourceViewResolver bean = new InternalResourceViewResolver();

        bean.setViewClass(JstlView.class);
        bean.setPrefix("/WEB-INF/view/pages/");
        bean.setSuffix(".jsp");

        return bean;
    }

您必须添加此依赖项才能使其正常工作:

<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
</dependency>