webservice系统学习笔记10-使用jax-ws创建基于tomcat类型的容器的ws服务
1、在web-info目录下新建目录wsdl
2、在1步的目录下
新建文件user.wsdl
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.zttc.edu.cn" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="UserService" targetNamespace="http://service.zttc.edu.cn"> <!-- wrappered推荐使用的方式 --> <wsdl:types> <xsd:schema targetNamespace="http://service.zttc.edu.cn"> <xsd:include schemaLocation="user.xsd"></xsd:include> </xsd:schema> </wsdl:types> <wsdl:message name="licenceInfo"> <wsdl:part name="licenceInfo" element="tns:licenceInfo"></wsdl:part> </wsdl:message> <wsdl:message name="UserException"> <wsdl:part name="fault" element="tns:UserException"></wsdl:part> </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:message name="upload"> <wsdl:part element="tns:upload" name="parameters"/> </wsdl:message> <wsdl:message name="uploadResponse"> <wsdl:part element="tns:uploadResponse" 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:fault name="UserException" message="tns:UserException"></wsdl:fault> </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:operation name="upload"> <wsdl:input message="tns:upload"/> <wsdl:output message="tns:uploadResponse"/> <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"/> <soap:header use="literal" part="licenceInfo" message="tns:licenceInfo"></soap:header> </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"/> <soap:header use="literal" part="licenceInfo" message="tns:licenceInfo"></soap:header> </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="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:operation name="upload"> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="UserService"> <wsdl:port binding="tns:userServiceSOAP" name="UserServicePort"> <soap:address location="http://localhost:8080/07_soa/us"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
user.xsd的文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.zttc.edu.cn" xmlns:tns="http://service.zttc.edu.cn" elementFormDefault="qualified"> <xsd:element name="add" type="tns:add"></xsd:element> <xsd:element name="addResponse" type="tns:addResponse"></xsd:element> <xsd:element name="delete" type="tns:delete"></xsd:element> <xsd:element name="deleteResponse" type="tns:deleteResponse"></xsd:element> <xsd:element name="list" type="tns:list"></xsd:element> <xsd:element name="listResponse" type="tns:listResponse"></xsd:element> <xsd:element name="login" type="tns:login"></xsd:element> <xsd:element name="loginResponse" type="tns:loginResponse"></xsd:element> <xsd:element name="UserException" type="tns:UserException"></xsd:element> <xsd:element name="licenceInfo" type="tns:licenceInfo"></xsd:element> <xsd:element name="upload" type="tns:upload"></xsd:element> <xsd:element name="uploadResponse" type="tns:uploadResponse"></xsd:element> <xsd:complexType name="uploadResponse"> <xsd:sequence/> </xsd:complexType> <!-- 文件上传的byte类型 --> <xsd:complexType name="upload"> <xsd:sequence> <xsd:element name="file" type="xsd:base64Binary"></xsd:element> </xsd:sequence> </xsd:complexType> <xsd:complexType name="licenceInfo"> <xsd:sequence> <xsd:element name="registerUser" type="tns:user"></xsd:element> </xsd:sequence> </xsd:complexType> <xsd:complexType name="UserException"> <xsd:sequence> <xsd:element name="message" type="xsd:string"></xsd:element> </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="username" type="xsd:string"/> </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="user" type="tns:user"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="login"> <xsd:sequence> <xsd:element name="username" type="xsd:string"/> <xsd:element name="password" 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="username" type="xsd:string"/> <xsd:element name="password" type="xsd:string"/> <xsd:element name="nickname" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema>
3、修改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"> <listener> <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class> </listener> <servlet> <servlet-name>UserService</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UserService</servlet-name> <url-pattern>/us</url-pattern> </servlet-mapping> </web-app>
4、在web-info下新建文件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"> <endpoint name="UserService" implementation="cn.edu.zttc.service.UserServiceImpl" url-pattern="/us"/> </endpoints>
5、使用wsimport命令生成服务端的服务接口类
6、编写服务端接口类
package cn.edu.zttc.service; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.List; import javax.annotation.Resource; import javax.jws.WebService; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.events.XMLEvent; import javax.xml.ws.WebServiceContext; import javax.xml.ws.soap.MTOM; import org.zttc.dao.UserDao; import org.zttc.dao.UserException; import org.zttc.vo.User; import com.sun.xml.ws.api.message.Header; import com.sun.xml.ws.api.message.HeaderList; import com.sun.xml.ws.developer.JAXWSProperties; @WebService(endpointInterface="cn.edu.zttc.service.IUserService", wsdlLocation="WEB-INF/wsdl/user.wsdl", serviceName="UserService", portName="UserServicePort", targetNamespace="http://service.zttc.edu.cn") @MTOM public class UserServiceImpl implements IUserService { private UserDao userDao = UserDao.newInstance(); //注入webservice的上下文对象
@Resource private WebServiceContext ctx; @Override public void add(User user) throws UserException { checkRegister(); userDao.add(user); } private void checkRegister() throws UserException { try { HeaderList headers = (HeaderList)ctx.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY); QName qname = new QName("http://service.zttc.edu.cn","licenceInfo"); if(headers==null) throw new UserException("该功能需要进行权限控制"); Header header = headers.get(qname,true); if(header==null) throw new UserException("该功能需要进行权限控制"); XMLStreamReader xsr = header.readHeader(); User u = x2user(xsr); User tu = userDao.loadByUsername(u.getUsername()); if(tu==null) throw new UserException("你所使用的用户不是系统的授权用户"); if(!tu.getPassword().equals(u.getPassword())) throw new UserException("授权用户的密码信息不正确!"); } catch (XMLStreamException e) { e.printStackTrace(); } } private User x2user(XMLStreamReader xsr) throws XMLStreamException { User u = new User(); while(xsr.hasNext()) { int event = xsr.next(); if(event==XMLEvent.START_ELEMENT) { String name = xsr.getName().toString(); if(name.equals("username")) { u.setUsername(xsr.getElementText()); } else if(name.equals("password")) { u.setPassword(xsr.getElementText()); } else if(name.equals("nickname")) { u.setNickname(xsr.getElementText()); } } } return u; } @Override public void delete(String username) throws UserException { checkRegister(); userDao.delete(username); } @Override public List<User> list() { return userDao.list(); } @Override public User login(String username, String password) throws UserException { return userDao.login(username, password); } @Override public void upload(byte[] file) { FileOutputStream fos = null; System.out.println(file); try { fos = new FileOutputStream("d:/webservice/1.jpg"); fos.write(file); fos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
需要导入的jax-ws的jar包如下:
这里服务端获取header的信息的方法又多了一个,具体看上面的实现类的代码中的方法checkRegister
客户端设置heade的方式还有如下方法:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.ws.soap.MTOMFeature;
import com.sun.xml.ws.api.message.Headers;
import com.sun.xml.ws.developer.WSBindingProvider;
@Test public void testAdd() { try { //1、将一个对象转换为xml通过JAXB JAXBContext ctx = JAXBContext.newInstance(LicenceInfo.class); User ru = new User(); ru.setNickname("超级管理"); ru.setUsername("admin"); ru.setPassword("1232323"); LicenceInfo info = new LicenceInfo(); info.setRegisterUser(ru); QName name = new QName(ns,"licenceInfo"); JAXBElement<LicenceInfo> jele = new JAXBElement<LicenceInfo>(name,LicenceInfo.class,info); Marshaller mars = ctx.createMarshaller(); mars.setProperty(Marshaller.JAXB_FRAGMENT,true); mars.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); //2、转换为DOM Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); mars.marshal(jele, doc); //3、通过Headers.create方法完成header的添加 //获取WSBindingProvider WSBindingProvider wsb = (WSBindingProvider)port; wsb.setOutboundHeaders(Headers.create(doc.getDocumentElement())); User u = new User(); u.setNickname("张三"); u.setPassword("123"); u.setUsername("zs"); port.add(u); }catch(Exception e) { System.out.println(e.getMessage()); } } @Test public void testUpload() { try { byte[] file = FileUtils.readFileToByteArray(new File("d:/kh/img/美女01.jpg")); port.upload(file); } catch (IOException e) { e.printStackTrace(); } }
关于附件的传输可以参考如下文章:https://www.ibm.com/developerworks/cn/webservices/ws-tip-jaxwsrpc5/