spring mvc4.1.x如何使用s:mvcUrl

来源:互联网 发布:可以追里番的软件 编辑:程序博客网 时间:2024/06/05 11:09

一.前提:

1.spring必须是4.1版本以上

2.支持EL 3.0的容器中(比如tomcat容器必须选择tomcat7以上版本)

官方文档参考:这里21.7.2 Building URIs to Controllers and methods from views


二.优点:

  可以在JSP, Thymeleaf, FreeMarker 直接获取请求的地址,无需在控制器的路径修改后,再次修改页面。


三.原理:

   每个RequestMapping 都会默认分配一个名称name,规则是类名中大写字母方法名中间加上#

  当然如果这样觉得太复杂了,你可以直接指定RequestMapping 的name,然后直接使用它。

  注意:如果你指定了当前RequestMapping 的name属性的值,则不可以使用先前默认规则来获取url,否则将会报错

例如:FooController 控制器中有个方法叫做getFoo 那么他的默认分配name为FC#getFoo。


四.实现:

controller:

package com.zone.controller;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;/** *  * @author pony * @version [版本号, 2015年12月4日] * @see [相关类/方法] * @since [产品/模块版本] */@Controller@RequestMapping("/account")public class LoginController {/** *  * @param username * @param request * @return * @see [类、类#方法、类#成员] */@RequestMapping(value = "/login", name = "accountLogin", method = RequestMethod.POST)public String login(@RequestParam(value = "username") String username, HttpServletRequest request) {request.setAttribute("username", username);return "loginSuccess";}}

JSP页面注意不能是index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@page isELIgnored="false"%><%@ taglib prefix="s" uri="http://www.springframework.org/tags"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Login Success</title></head><body>Hello<span style="color: red;">${username}</span> ,Welcome to spring mvc.        <br><span style="white-space:pre"></span>使用s:mvcURL获取url地址: ${s:mvcUrl('accountLogin').arg(0,username).build()}</body></html>

解释:

//引入标签库<%@ taglib prefix="s" uri="http://www.springframework.org/tags"%>${s:mvcUrl('accountLogin').arg(0,username).build()}accountLogin:为requestMapping属性name的值.arg()第一个参数表示controller方法中的第几个参数,第二个参数即为参数的值.本例中的login方法设置为username的值build()即生成url


五:异常定位

1.容器不支持EL3.0报错日志如下:

org.apache.jasper.JasperException: /WEB-INF/jsp/loginSuccess.jsp(14,3) The function arg must be used with a prefix when a default namespace is not specifiedorg.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:148)org.apache.jasper.compiler.Validator$ValidateVisitor$1FVVisitor.visit(Validator.java:1506)org.apache.jasper.compiler.ELNode$Function.accept(ELNode.java:129)org.apache.jasper.compiler.ELNode$Nodes.visit(ELNode.java:200)org.apache.jasper.compiler.ELNode$Visitor.visit(ELNode.java:242)org.apache.jasper.compiler.ELNode$Root.accept(ELNode.java:56)org.apache.jasper.compiler.ELNode$Nodes.visit(ELNode.java:200)org.apache.jasper.compiler.Validator$ValidateVisitor.validateFunctions(Validator.java:1531)org.apache.jasper.compiler.Validator$ValidateVisitor.prepareExpression(Validator.java:1536)org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:720)org.apache.jasper.compiler.Node$ELExpression.accept(Node.java:958)org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2361)org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2411)org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2417)org.apache.jasper.compiler.Node$Root.accept(Node.java:495)org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2361)org.apache.jasper.compiler.Validator.validateExDirectives(Validator.java:1763)org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:198)org.apache.jasper.compiler.Compiler.compile(Compiler.java:347)org.apache.jasper.compiler.Compiler.compile(Compiler.java:327)org.apache.jasper.compiler.Compiler.compile(Compiler.java:314)org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:592)org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:317)org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)javax.servlet.http.HttpServlet.service(HttpServlet.java:717)org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)javax.servlet.http.HttpServlet.service(HttpServlet.java:637)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)javax.servlet.http.HttpServlet.service(HttpServlet.java:717)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

2.当你在index.jsp页面中使用s:mvcURL,报错信息如下

很明显这个是在没有加载spring mvc context之前就使用了s:mvcURL,所以你的JSP页面必须在你指定的视图路径下


java.lang.IllegalArgumentException: Cannot lookup handler method mappings without WebApplicationContextorg.springframework.util.Assert.notNull(Assert.java:112)org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder.getRequestMappingInfoHandlerMapping(MvcUriComponentsBuilder.java:358)org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder.fromMappingName(MvcUriComponentsBuilder.java:262)sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)java.lang.reflect.Method.invoke(Method.java:606)org.apache.el.parser.AstFunction.getValue(AstFunction.java:112)org.apache.el.parser.AstValue.getValue(AstValue.java:161)org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:1026)org.apache.jsp.index_jsp._jspService(index_jsp.java:80)org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

3.给@RequestMapping的name属性进行显示的命名后却使用默认的名称去调用s:mvcURL()

例如本例中你使用${s:mvcUrl('LC#login').arg(0,username).build()}就会报如下错误

java.lang.IllegalArgumentException: Mapping mappingName not found: LC#loginorg.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder.fromMappingName(MvcUriComponentsBuilder.java:265)sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)java.lang.reflect.Method.invoke(Method.java:606)org.apache.el.parser.AstFunction.getValue(AstFunction.java:112)org.apache.el.parser.AstValue.getValue(AstValue.java:161)org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:1026)org.apache.jsp.WEB_002dINF.jsp.loginSuccess_jsp._jspService(loginSuccess_jsp.java:83)org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1228)org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)javax.servlet.http.HttpServlet.service(HttpServlet.java:647)org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)javax.servlet.http.HttpServlet.service(HttpServlet.java:728)org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)


六:源码下载:

源码例子在这里

个人拙见,如有不妥,欢迎指正。




0 0