【问题标题】:Spring: Controller @RequestMapping to jspSpring:控制器@RequestMapping到jsp
【发布时间】:2012-09-20 18:53:13
【问题描述】:

使用 Spring 3.1.2

如何从 jsp 中引用 CONTROLLER(不是方法)RequestMapping 的注释值,以便我可以构建相对于控制器的 URL。如果引用了方法级别的请求映射,则会导致我的链接不起作用,因此它们无论如何都不能成为 this 的一部分。

例如(注意这个控制器的映射是“/foo/test”):

@Controller
@RequestMapping("/foo/test")
public class FooController {

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

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

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

...以及来自我的 this.jsp:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s"%>
<s:url value="${controllerRequestMapping}" var="baseUrl"/>

<a href="${baseUrl}/that">That</a>
<a href="${baseUrl}/other">Other</a>

我需要访问 RequestMapping 的原因是因为我的视图可以从多个控制器访问。注意这个控制器的映射是“/bar/test”!

@Controller
@RequestMapping("/bar/test")
public class BarController {

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

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

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

我的一些控制器级别的请求映射也有路径变量,所以只获取请求映射的字符串值是行不通的。必须解决:

@Controller
@RequestMapping("/something/{anything}/test/")
public class SomethingController {
...
}

更新

也许如果有一种方法可以通过在 Spring URL 标记之前附加控制器请求映射来修改上下文路径,那将解决问题。

contextPath = contextPath/controllerRequestMapping

然后,我可以这样做,因为我相信 Spring 会自动检索当前上下文路径:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s"%>

<a href="<s:url value="/that"/>">That</a>
<a href="<s:url value="/other"/>">Other</a>

这当然是最佳选择!想法?想法...?

提前致谢!

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    您可以使用 Servlet API 获取 URI。据我所知,没有“春天”的方式来做到这一点。

    @RequestMapping(value="/this", method=RequestMethod.GET)
    public String getThis(HttpServletRequest request, Model m) {
        m.addAttribute("path", request.getRequestURI());
        return "test/this";
    }
    

    然后在你的 JSP 中:

    <a href="${path}">This</a>
    

    有关 HttpServletRequest 的更多信息,see the API here

    【讨论】:

      【解决方案2】:

      没有访问@RequestMapping 的内置方法,但您可以简单地将URL 添加到模型并通过这种方式从视图中引用它。

      【讨论】:

      • 感谢您的快速回复。这可能有效,但我希望有更多“面向约定”的方式来添加它以将其添加到请求中。那可能我不必为每个控制器的模型添加静态 URL。
      • 恐怕没有更传统的方法了。您可以编写一些方法来检查当前方法的注释并以这种方式添加它,而不是对其进行硬编码(但话又说回来,@RequestMapping 值也是硬编码的)
      【解决方案3】:

      在我看来,将@RequestMapping 注解放在类级别和方法级别没有区别。取而代之的是,您可以仅在方法顶部使用组合的 @RequestMapping 注释。

      所以现在你的方法级别注释将是这样的。

      @RequestMapping(value="("/foo/test/this", method=RequestMethod.GET)
      

      @RequestMapping(value="("/bar/test/this", method=RequestMethod.GET)
      

      现在,由于您的两种方法都返回相同的视图,因此您可以只为它们两种方法使用一种方法。并且在注解映射值而不是 foo 和 bar 中可以引入一个路径变量 {from}。所以最后你的注解和方法会是这样的。

      @RequestMapping(value="("/{from}/test/this", method=RequestMethod.GET)
      public String getThis(@PathVariable("from") String from) {       
          return "test/this";       
      }
      

      在您的方法中执行此操作后,您可以根据您获得的路径变量 from 的运行时值执行不同的计算或操作。在 JSP 页面中,您可以使用 ${from} 简单地获取此值。

      希望这对您有所帮助。干杯。

      【讨论】:

        【解决方案4】:

        如果您使用的是 Spring 3.1 及更高版本,请参阅下面的代码以访问请求映射。我不确定这是否是您所需要的。这只是一种尝试,当然我不知道任何直接的方法。从具有请求映射的方法内部调用 getRequestMappings()。

        public class FooController{
        
            private RequestMappingHandlerMapping handlerMapping = null;
        
            @Autowired
            public FooController(RequestMappingHandlerMapping handlerMapping){
                this.handlerMapping = handlerMapping;
            }
        
            public Set<String> getRequestMappings(){
                Map<RequestMappingInfo, HandlerMethod> handlerMap = handlerMapping.getHandlerMethods();
                Iterator<RequestMappingInfo> itr = handlerMap.keySet().iterator();
                while(itr.hasNext()){
                    RequestMappingInfo info = itr.next();
                    PatternsRequestCondition condition = info.getPatternsCondition();
                    Set<String> paths = condition.getPatterns();
                    HandlerMethod method = handlerMap.get(info);
                    if(method.getMethod().getName().equals(Thread.currentThread().getStackTrace()[2].getMethodName()))
                    return paths;
        
                    }
                return new HashSet<String>();
            }
        
        
        
        }
        

        【讨论】:

          【解决方案5】:

          从 4.1 开始,每个 @RequestMapping 都被分配了一个基于大写字母的默认名称 类的字母和完整的方法名称。例如,getFoo 方法 在类 FooController 中被分配了名称“FC#getFoo”。这个命名策略是enter code here 通过实现 HandlerMethodMappingNamingStrategy 并在您的 请求映射处理程序映射。此外,@RequestMapping 注释包括一个 name 属性,可用于覆盖默认策略。 Spring JSP 标记库提供了一个名为 mvcUrl 的函数,可用于准备指向 基于这种机制的控制器方法。

          例如给出:

          @RequestMapping("/people/{id}/addresses")
          public class MyController {
          @RequestMapping("/{country}")
          public HttpEntity getAddress(@PathVariable String country) { ... }
          }
          

          下面的JSP代码可以准备一个链接:

          <%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
          ...
          <a href="${s:mvcUrl('MC#getPerson').arg(0,'US').buildAndExpand('123')}">Get Address</a>
          

          确保您已使用 Java Config 或 XML 方式配置 MVC,而不是两种方式。 你会得到一个异常:多个 RequestMappingInfo HandlerMapping found。

          【讨论】:

            猜你喜欢
            • 2016-02-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-31
            • 2015-09-05
            • 1970-01-01
            • 2012-01-10
            • 2021-04-03
            相关资源
            最近更新 更多