Spring MVC 控制器工作但未创建指定的响应 URL,它正在从请求映射字符串创建 url

Posted

技术标签:

【中文标题】Spring MVC 控制器工作但未创建指定的响应 URL,它正在从请求映射字符串创建 url【英文标题】:Spring MVC Controller working but not creating the specified response URL ,It is creating the url from request mapping string 【发布时间】:2016-09-21 12:08:07 【问题描述】:

我正在研究基于 Spring MVC 的 webapps。所以我在spring mvc中创建了一个项目,我选择了eclipse IDE.Apache tomcat 8 server和jre1.8,spring包的版本是4.2.5。在我的项目中,我创建了登录名,登录后工作正常,我将页面重定向到另一个名为“branchinsert.jsp”的jsp,该jsp放置在另一个文件夹中(login.jsp和branchinsert.jsp来自不同的文件夹)。在 Branchinsert.jsp 中,Spring MVC 控制器正在工作但没有创建指定的响应 URL,它是从请求映射字符串创建 url,这意味着如果我给出如下所述的模式,

@RequestMapping(value="/branchsubmitinsert.travel", method=RequestMethod.POST)
public ModelAndView submitBranchInsert(@ModelAttribute BranchModel branchModel)

    ModelAndView modelAndView = new ModelAndView("/branch/branchinsert");

    return modelAndView;


显示 url /ProjectName/modules/branch/branchsubmitinsert.jsp 的 404 错误

实际上我期望的 url 是 /branch/branchinsert.jsp(这是通常发生的情况)但这里创建了 /branch/branchsubmitinsert.jsp url。为什么????

这是我的代码

web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns="http://java.sun.com/xml/ns/javaee" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" 
 version="3.0">
<display-name>CalicutTravels</display-name>
   <servlet>
     <servlet-name>spring-dispatcher</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
  </servlet>
<servlet-mapping>
  <servlet-name>spring-dispatcher</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping>
<listener><listener-class>
    org.springframework.web.context.ContextLoaderListener
</listener-class>

ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

 <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context = "http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

      <context:component-scan base-package="com.classes.controller">
          <context:exclude-filter type="annotation"  
                expression="org.springframework.stereotype.Controller"/>
      </context:component-scan>

  </beans>

spring-dispatcher-servlet.xml

 <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context = "http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
  <context:annotation-config />
  <context:component-scan base-package="com.classes.controller">
  </context:component-scan>
  <mvc:annotation-driven/>

   <mvc:resources mapping="/resources/**" location="/resources/" />

   <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/modules/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

    <!-- declare beans -->

      <bean id="userDaoImplementation" 
       class="com.classes.dao.login.UserDaoImplementation" />
      <bean id="userServiceImplementation"

      class="com.classes.service.login.UserServiceImplementation" />

   <!-- declare datasource bean "jdbc:postgresql://hostname:port
   /dbname","username", "password");-->
  <bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
   <property name="driverClassName" value="org.postgresql.Driver" />
   <property name="url" value="jdbc:postgresql://localhost:5432
   /db_enterpricer_travel" />
   <property name="username" value="vishnu" />
   <property name="password" value="root" />
  </bean>

  </beans>

branchinsert.jsp 的表单域

 <form action='branchsubmitinsert.travel' id='brach_submit' method='post' >
            <fieldset class="well the-fieldset">
                <legend class="the-legend">  INSERT </legend>

                    <table>
                        <tr>
                            <th> Branch Name :</th>
                            <td> <input type="text" name='branchName' id='branchName' /></td>
                        </tr>
                        <tr>
                          <td colspan="2" align="right"><input type="button" class="btn btn-default" value='INSERT' onclick='return validateBranchInsert()'/></td>
                        </tr>
                    </table>


             </fieldset>
        </form>

控制器类BranchController.java

 package com.classes.controller.branch;

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

 import com.classes.service.branch.BranchModel;


 /**
 * @author vishnu
 *
 */

 @Controller
 @RequestMapping("/branch")
 public class BranchController 

 @RequestMapping(value="/branchinsert.travel", method=RequestMethod.GET)
 public ModelAndView getBranchInsert()

    ModelAndView modelAndView = new ModelAndView("/branch/branchinsert");
    return modelAndView;

 

 @RequestMapping(value="/branchupdate.travel", method=RequestMethod.GET)
 public ModelAndView getBranchUpdate()

    ModelAndView modelAndView = new ModelAndView("/branch/branchupdate");
    return modelAndView;

 

 @RequestMapping(value="/branchshow.travel", method=RequestMethod.GET)
 public ModelAndView getBranchShow()

    ModelAndView modelAndView = new ModelAndView("/branch/branchshow");
    return modelAndView;

 

 @RequestMapping(value="/branchdelete.travel", method=RequestMethod.GET)
 public ModelAndView getBranchDelete()

    ModelAndView modelAndView = new ModelAndView("/branch/branchdelete");
    return modelAndView;

 

@RequestMapping(value="/branchsubmitinsert.travel",
method=RequestMethod.POST)
public ModelAndView submitBranchInsert(@ModelAttribute BranchModel 
branchModel)

    ModelAndView modelAndView = new ModelAndView("/branch/branchinsert");
    modelAndView.addObject("branch",branchModel);
    return modelAndView;




【问题讨论】:

模块命名文件夹,其中包含包含文件夹(登录、分支..等)的 jsp 文件 【参考方案1】:

由于您在 viewResolver 的前缀中提到了 modules 文件夹,它的工作原理就是这样......

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/modules/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

这意味着返回"branch/branchInsert"会在/modules/branch/branchInsert.jsp中找到jsp。

如果您只使用字符串返回意味着它只是来自您发送请求集的 jsp 的路径。所以对于那个 viewResolver 不会添加前缀文件夹。

但是如果你使用ModelAndView,viewResolver 会添加前缀和后缀。

【讨论】:

是的,.. 现在它按照我的逻辑运行。但是为什么它在使用 ModelAndView 作为返回类型时生成 branchsubmitinsert.jsp。所以模型中的 String 和我正在寻找的 ModelAndView 之间存在一些差异..,谢谢您的回复:-) 已更新答案..如果您想检查将 branchsubmitInsert.jsp 移动到其他文件夹并通过提供分支/branchinsert 进行测试【参考方案2】:

我把submitBranchInsert方法的返回类型改成String如下

 @RequestMapping(value="/branchsubmitinsert.travel", method=RequestMethod.POST)
public String submitBranchInsert(ModelMap model,@ModelAttribute BranchModel branchModel)

    //ModelAndView modelAndView = new ModelAndView("/branch/branchinsert");
    //modelAndView.addObject("branch",branchModel);
    //return modelAndView;
    model.addAttribute("branch", branchModel);
    return "/branch/branchinsert";


现在可以了,但为什么我不能在这里使用 ModelAndView 而不是 Model in String , 对于 Spring MVC 的专家来说,我可能听起来很愚蠢。 我只想知道什么时候应该在 String 中使用 ModelAndView 而不是 Model? 我不想单独问这个问题,这就是为什么我用我的答案来问这个问题。 有人可以帮帮我吗?

【讨论】:

如果您需要响应客户端提供一些数据来呈现页面而不仅仅是一个页面,您应该使用ModelAndView 好的..知道了,但看起来我也可以在“模型中的字符串”概念中提供数据..我正在传递带有响应的对象,请看我的答案,我发现的问题是当我我使用 ModelAndView 作为返回类型,视图解析器创建 branchsubmit.jsp,在其他情况下它正在创建 branchinsert,jsp 好的,你对,请看Which is better, return “ModelAndView” or “String” on spring3 controller 不要发布问题作为答案,如果您有其他问题,请提出新问题或扩展您的原始问题。

以上是关于Spring MVC 控制器工作但未创建指定的响应 URL,它正在从请求映射字符串创建 url的主要内容,如果未能解决你的问题,请参考以下文章

如何在spring mvc中的操作之前发送响应

在 Spring MVC 3.1 控制器的处理程序方法中直接流到响应输出流

如何从 Spring MVC 控制器返回对象以响应 AJAX 请求?

混合 Spring MVC + Spring Data Rest 会导致奇怪的 MVC 响应

使用 JSON Sanitizer 清理来自 Spring MVC 控制器的响应 JSON?

Spring MVC 中 Json 响应的后处理