目标:
基于契约优先的webservice功能开发
?
服务端
一、编写xsd和wsdl文件(validate必须要通过,注意命名空间要一致),放到WEB-INF/wsdl目录下
二、项目中引入jaxws-ri的相关jar包;WEB-INF下增加sun-jaxws.xml(配置服务的实现类);在web.xml中配置jaxws-ri提供的监听器WSServletContextListener;在web.xml中配置jaxws-ri提供的Servlet:WSServlet
三、使用wsimport命令将本地wsdl转换为java文件,拷贝服务接口源文件到服务端(删除@XmlSeeAlso({ObjectFactory.class}) ,将异常类改为自定义的异常---该异常应该继承自Exception,如果是runtimeexception,服务端也会抛出异常)
四、编写实现类,配置一些注解endpointInterface,wsdlLocation,targetNamespace,serviceName,portName等
五、部署项目到tomcat并启动。
备注:在wsdl中通过include或者import引入xsd文件,通过wsimport获取服务端的接口以及客户端生成的java文件,有可能会出现问题,如,客户端调用list()在服务端返回时有对象,但是客户端获取到的就是null。
如果将schema的定义全部放到wsdl中,客户端访问webservice的list()就不会出现问题。这是怎么回事呢?
如果都正常了,则可以将schema的定义单独放到xsd文件中,又没事了!?所以,先将schema的定义放到wsdl中,这样通过wsdl生成的客户端代码才能与服务端顺利的进行沟通!如果分离开,启动服务,生成的客户端代码调用服务是有问题的,切记!!!
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.hqh.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="UserService" targetNamespace="http://service.hqh.com"> <wsdl:types> <!-- <xsd:schema targetNamespace="http://service.hqh.com"> <xsd:include schemaLocation="user.xsd"/> </xsd:schema> --> <!-- <xsd:schema> <xsd:import namespace="http://service.hqh.com" schemaLocation="user.xsd" /> </xsd:schema> --> <xsd:schema targetNamespace="http://service.hqh.com"> <xsd:element name="add" type="tns:add" /> <xsd:element name="addResponse" type="tns:addResponse" /> <xsd:element name="delete" type="tns:delete" /> <xsd:element name="deleteResponse" type="tns:deleteResponse" /> <xsd:element name="list" type="tns:list" /> <xsd:element name="listResponse" type="tns:listResponse" /> <xsd:element name="login" type="tns:login" /> <xsd:element name="loginResponse" type="tns:loginResponse" /> <xsd:element name="UserException" type="tns:UserException"></xsd:element> <xsd:complexType name="UserException"> <xsd:sequence> <xsd:element name="error" type="xsd:string" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="add"> <xsd:sequence> <xsd:element name="user" type="tns:user" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="addResponse"> <xsd:sequence /> </xsd:complexType> <xsd:complexType name="delete"> <xsd:sequence> <xsd:element name="id" type="xsd:int"></xsd:element> </xsd:sequence> </xsd:complexType> <xsd:complexType name="deleteResponse"> <xsd:sequence /> </xsd:complexType> <xsd:complexType name="list"> <xsd:sequence /> </xsd:complexType> <xsd:complexType name="listResponse"> <xsd:sequence minOccurs="1" maxOccurs="unbounded"> <xsd:element name="users" type="tns:user" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="login"> <xsd:sequence> <xsd:element name="name" type="xsd:string" /> <xsd:element name="pwd" type="xsd:string" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="loginResponse"> <xsd:sequence> <xsd:element name="user" type="tns:user" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="user"> <xsd:sequence> <xsd:element name="id" type="xsd:int" /> <xsd:element name="name" type="xsd:string" /> <xsd:element name="pwd" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:schema> </wsdl:types> <!-- 添加异常 消息 --> <wsdl:message name="UserException"> <wsdl:part name="fault" element="tns:UserException" /> </wsdl:message> <wsdl:message name="add"> <wsdl:part element="tns:add" name="parameters" /> </wsdl:message> <wsdl:message name="addResponse"> <wsdl:part element="tns:addResponse" name="parameters" /> </wsdl:message> <wsdl:message name="delete"> <wsdl:part element="tns:delete" name="parameters" /> </wsdl:message> <wsdl:message name="deleteResponse"> <wsdl:part element="tns:deleteResponse" name="parameters" /> </wsdl:message> <wsdl:message name="list"> <wsdl:part element="tns:list" name="parameters" /> </wsdl:message> <wsdl:message name="listResponse"> <wsdl:part element="tns:listResponse" name="parameters" /> </wsdl:message> <wsdl:message name="login"> <wsdl:part element="tns:login" name="parameters" /> </wsdl:message> <wsdl:message name="loginResponse"> <wsdl:part element="tns:loginResponse" name="parameters" /> </wsdl:message> <!-- 指定接口和方法 --> <wsdl:portType name="IUserService"> <wsdl:operation name="add"> <wsdl:input message="tns:add" /> <wsdl:output message="tns:addResponse" /> <!-- 异常 --> <wsdl:fault name="UserException" message="tns:UserException"></wsdl:fault> </wsdl:operation> <wsdl:operation name="delete"> <wsdl:input message="tns:delete" /> <wsdl:output message="tns:deleteResponse" /> </wsdl:operation> <wsdl:operation name="list"> <wsdl:input message="tns:list" /> <wsdl:output message="tns:listResponse" /> </wsdl:operation> <wsdl:operation name="login"> <wsdl:input message="tns:login" /> <wsdl:output message="tns:loginResponse" /> <!-- 异常 --> <wsdl:fault name="UserException" message="tns:UserException"></wsdl:fault> </wsdl:operation> </wsdl:portType> <!-- 编码格式 --> <wsdl:binding name="userServiceSOAP" type="tns:IUserService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="add"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> <!-- 异常 --> <wsdl:fault name="UserException"> <soap:fault name="UserException" use="literal" /> </wsdl:fault> </wsdl:operation> <wsdl:operation name="delete"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="list"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="login"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> <!-- 异常 --> <wsdl:fault name="UserException"> <soap:fault name="UserException" use="literal" /> </wsdl:fault> </wsdl:operation> </wsdl:binding> <!-- 服务 --> <wsdl:service name="UserService"> <wsdl:port binding="tns:userServiceSOAP" name="userServicePort"> <!-- 通过jaxws-ri.jax中的servlet对访问进行监听,这里配置的地址很关键,根目录后跟servlet的url-pattern,保持一致 --> <soap:address location="http://localhost:8080/Demo/service" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
?
?
客户端
一、客户端通过服务端发布的地址得到wsdl并使用wsdl转换为java文件。
二、客户端将所有转换的java文件拷贝至项目中(字节码文件不要拷贝到项目中,否则启动会报错)
三、获取port,访问服务端对外公布的方法
?
需要注意的地方:
服务端的接口文件,来源:通过本地wsdl文件使用wsimport命令转换而来
客户端的java文件,来源:服务端启动服务,通过可访问的url地址使用wsimport命令转换而来
服务端与客户端的版本必须保持一致,即服务端一旦有变化,客户端使用的访问服务端的java文件必须根据新的wsdl来生成,否则访问服务端的方法有可能得不到正确的返回值!!!
尽量保持命名的一致性,很多地方是有对应关系的,不能一边大写一边小写
?
服务端
?
1.将编写好的user.xsd和user.wsdl文件放到WEB-INF/wsdl目录下
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.hqh.com" xmlns:tns="http://service.hqh.com" elementFormDefault="qualified"> <xsd:element name="add" type="tns:add" /> <xsd:element name="addResponse" type="tns:addResponse" /> <xsd:element name="delete" type="tns:delete" /> <xsd:element name="deleteResponse" type="tns:deleteResponse" /> <xsd:element name="list" type="tns:list" /> <xsd:element name="listResponse" type="tns:listResponse" /> <xsd:element name="login" type="tns:login" /> <xsd:element name="loginResponse" type="tns:loginResponse" /> <xsd:element name="UserException" type="tns:UserException"></xsd:element> <xsd:complexType name="UserException"> <xsd:sequence> <xsd:element name="error" type="xsd:string"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="add"> <xsd:sequence> <xsd:element name="user" type="tns:user" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="addResponse"> <xsd:sequence /> </xsd:complexType> <xsd:complexType name="delete"> <xsd:sequence> <xsd:element name="id" type="xsd:int"></xsd:element> </xsd:sequence> </xsd:complexType> <xsd:complexType name="deleteResponse"> <xsd:sequence /> </xsd:complexType> <xsd:complexType name="list"> <xsd:sequence /> </xsd:complexType> <xsd:complexType name="listResponse"> <xsd:sequence minOccurs="1" maxOccurs="unbounded"> <xsd:element name="users" type="tns:user"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="login"> <xsd:sequence> <xsd:element name="name" type="xsd:string" /> <xsd:element name="pwd" type="xsd:string" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="loginResponse"> <xsd:sequence> <xsd:element name="user" type="tns:user" /> </xsd:sequence> </xsd:complexType> <xsd:complexType name="user"> <xsd:sequence> <xsd:element name="id" type="xsd:int" /> <xsd:element name="name" type="xsd:string" /> <xsd:element name="pwd" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:schema>
?
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.hqh.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="UserService" targetNamespace="http://service.hqh.com"> <wsdl:types> <!-- <xsd:schema targetNamespace="http://service.hqh.com"> <xsd:include schemaLocation="user.xsd"/> </xsd:schema> --> <!-- --> <xsd:schema> <xsd:import namespace="http://service.hqh.com" schemaLocation="user.xsd" /> </xsd:schema> </wsdl:types> <!-- 添加异常 消息 --> <wsdl:message name="UserException"> <wsdl:part name="fault" element="tns:UserException" /> </wsdl:message> <wsdl:message name="add"> <wsdl:part element="tns:add" name="parameters" /> </wsdl:message> <wsdl:message name="addResponse"> <wsdl:part element="tns:addResponse" name="parameters" /> </wsdl:message> <wsdl:message name="delete"> <wsdl:part element="tns:delete" name="parameters" /> </wsdl:message> <wsdl:message name="deleteResponse"> <wsdl:part element="tns:deleteResponse" name="parameters" /> </wsdl:message> <wsdl:message name="list"> <wsdl:part element="tns:list" name="parameters" /> </wsdl:message> <wsdl:message name="listResponse"> <wsdl:part element="tns:listResponse" name="parameters" /> </wsdl:message> <wsdl:message name="login"> <wsdl:part element="tns:login" name="parameters" /> </wsdl:message> <wsdl:message name="loginResponse"> <wsdl:part element="tns:loginResponse" name="parameters" /> </wsdl:message> <!-- 指定接口和方法 --> <wsdl:portType name="IUserService"> <wsdl:operation name="add"> <wsdl:input message="tns:add" /> <wsdl:output message="tns:addResponse" /> <!-- 异常 --> <wsdl:fault name="UserException" message="tns:UserException"></wsdl:fault> </wsdl:operation> <wsdl:operation name="delete"> <wsdl:input message="tns:delete" /> <wsdl:output message="tns:deleteResponse" /> </wsdl:operation> <wsdl:operation name="list"> <wsdl:input message="tns:list" /> <wsdl:output message="tns:listResponse" /> </wsdl:operation> <wsdl:operation name="login"> <wsdl:input message="tns:login" /> <wsdl:output message="tns:loginResponse" /> <!-- 异常 --> <wsdl:fault name="UserException" message="tns:UserException"></wsdl:fault> </wsdl:operation> </wsdl:portType> <!-- 编码格式 --> <wsdl:binding name="userServiceSOAP" type="tns:IUserService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="add"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> <!-- 异常 --> <wsdl:fault name="UserException"> <soap:fault name="UserException" use="literal" /> </wsdl:fault> </wsdl:operation> <wsdl:operation name="delete"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="list"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="login"> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> <!-- 异常 --> <wsdl:fault name="UserException"> <soap:fault name="UserException" use="literal" /> </wsdl:fault> </wsdl:operation> </wsdl:binding> <!-- 服务 --> <wsdl:service name="UserService"> <wsdl:port binding="tns:userServiceSOAP" name="userServicePort"> <!-- 通过jaxws-ri.jax中的servlet对访问进行监听,这里配置的地址很关键,根目录后跟servlet的url-pattern,保持一致 --> <soap:address location="http://localhost:8080/Demo/service" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
?2.项目中引入jaxws-ri压缩包下的lib包中的jar
?3.WEB-INF下新建一个sun-jaxws.xml
<?xml version="1.0" encoding="UTF-8"?> <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> <!-- name配置服务的名称 implementation配置对应的实现类 url-pattern配置浏览器中访问本服务的地址--> <endpoint name="UserService" implementation="com.hqh.service.UserServiceImpl" url-pattern="/service"/> </endpoints>
?4.配置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"> <!-- 配置webservice,使用 jaxws-ri.jar 进行支持--> <!-- 监听器 --> <listener> <!-- 引入jaxws-ri.jar中的监听器 --> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <!-- servlet-name与sun-jaxws.xml中的name一致 --> <servlet-name>UserService</servlet-name> <!-- 使用jaxws-ri.jar中的servlet --> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UserService</servlet-name> <!-- servlet-name与sun-jaxws.xml中的url-pattern一致 --> <url-pattern>/service</url-pattern> </servlet-mapping> </web-app>
?? 使用wsimort将本地wsdl文件转换为java文件
wsimport -d destination_folder -keep xxx.wsdl
?
5.接口(事先已经编写好wsdl文件,通过wsimport可以将其转换为java文件,此时将转换后的接口文件拷贝到项目中作为接口使用,由于已经在接口中定义好了各种注解,所以能够很好的帮助完成服务于wsdl的映射)
package com.hqh.service; import java.util.List; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; import com.hqh.model.User; /** * This class was generated by the JAX-WS RI. * JAX-WS RI 2.1.6 in JDK 6 * Generated source version: 2.1 * */ @WebService(name = "IUserService", targetNamespace = "http://service.hqh.com") public interface IUserService { /** * * @param user * @throws UserException_Exception */ @WebMethod @RequestWrapper(localName = "add", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.Add") @ResponseWrapper(localName = "addResponse", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.AddResponse") public void add( @WebParam(name = "user", targetNamespace = "") User user) throws UserException ; /** * * @param id */ @WebMethod @RequestWrapper(localName = "delete", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.Delete") @ResponseWrapper(localName = "deleteResponse", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.DeleteResponse") public void delete( @WebParam(name = "id", targetNamespace = "") int id); /** * * @return * returns java.util.List<com.hqh.service.User> */ @WebMethod @WebResult(name = "users", targetNamespace = "") @RequestWrapper(localName = "list", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.List") @ResponseWrapper(localName = "listResponse", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.ListResponse") public List<User> list(); /** * * @param pwd * @param name * @return * returns com.hqh.service.User * @throws UserException_Exception */ @WebMethod @WebResult(name = "user", targetNamespace = "") @RequestWrapper(localName = "login", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.Login") @ResponseWrapper(localName = "loginResponse", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.LoginResponse") public User login( @WebParam(name = "name", targetNamespace = "") String name, @WebParam(name = "pwd", targetNamespace = "") String pwd) throws UserException ; }
?
?6.实现类
package com.hqh.service; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.jws.WebService; import com.hqh.model.User; /**必须指定targetNamespace,否则服务无法启动*/ /*file:/E:/technology-hqh/proj/webservice/JAX-WS/Demo/build/classes/META-INF/wsdl/user.wsdl has the following services [{http://service.hqh.com}UserService] but not {http://service.hqh.com/}UserService. Maybe you forgot to specify a service name in @WebService/@WebServiceProvider?*/ @WebService(endpointInterface="com.hqh.service.IUserService", wsdlLocation="WEB-INF/wsdl/user.wsdl", serviceName="UserService", portName="userServicePort", targetNamespace="http://service.hqh.com") public class UserServiceImpl implements IUserService { private static List<User> users = new ArrayList<User>(); static { users.add(new User(1,"zs","zs")); } @Override public void add(User user) throws UserException{ for(User u:users) { if(u.getName().equals(user.getName())) { throw new UserException("用户已存在!",null); } } users.add(user); } @Override public void delete(int id) { for (Iterator iterator = users.iterator(); iterator.hasNext();) { User user = (User) iterator.next(); if(id==user.getId()) { users.remove(user); break; } } } @Override public List<User> list() { return users; } @Override public User login(String name, String pwd) throws UserException{ for(User user : users) { if(name.equals(user.getName()) && pwd.equals(user.getPwd())) { return user; } } throw new UserException("用户不存在",null); } }
?
模型
package com.hqh.model; public class User { private int id; private String name; private String pwd; public User() { super(); } public User(int id, String name, String pwd) { super(); this.id = id; this.name = name; this.pwd = pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } }
?? 异常类
package com.hqh.service; public class UserException extends Exception { public UserException() { super(); } public UserException(String message, Throwable cause) { super(message, cause); } public UserException(String message) { super(message); } public UserException(Throwable cause) { super(cause); } }?
?
部署web项目到tomcat并启动,访问http://localhost:8080/Demo/service?wsdl就能看到wsdl文件
成功!
?
?
客户端
通过服务端提供的服务地址,转换wsdl为本地java文件,将所有java文件拷贝至客户端项目中
通过getXXXServicePort()获取到接口的实现类,即可调用服务!
?
客户端Servlet
package com.hqh.service.servlet; import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.hqh.service.IUserService; import com.hqh.service.User; import com.hqh.service.UserService; /** * Servlet implementation class UserServlet */ public class UserServlet extends HttpServlet { private static final long serialVersionUID = 1L; private IUserService service; private UserService serviceImpl; public UserServlet() { super(); System.out.println("UserServlet.UserServlet()"); //初始化服务端口调用类 serviceImpl = new UserService(); service = serviceImpl.getUserServicePort(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String method = request.getParameter("method"); if(method==null || "".equals(method)) { list(request,response); } } private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<User> users = service.list(); request.setAttribute("users", users); request.getRequestDispatcher("/list.jsp").forward(request, response); } }
?? index.jsp 调用servlet,在servlet中访问webservice服务
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!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=UTF-8"> <title>Insert title here</title> </head> <body> <a href="/Demo_client/userServlet">查看user list</a> </body> </html>
?? list.jsp 显示从服务端传递回来的对象信息
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!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=UTF-8"> <title>Insert title here</title> </head> <body> <c:forEach items="${users}" var="user"> ${user.id}---${user.name }---${user.pwd } <br/> </c:forEach> </body> </html>
?备注:eclipse中使用JSTL标签需要引入两个jar包,jstl.jar和standard.jar;将tld中的c.tld,fn.tld,fmt.tld三个最常用的tld文件拷贝至WEB-INF目录下任意位置,在jsp中引入taglib标签后,即可使用。
?
?