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

一.前提:

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 specified
	org.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 WebApplicationContext
	org.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#login
	org.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)


六:源码下载:

源码例子在这里

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值