Java发布Webservice之一:出现小问题及解决

        最近学习做Webservice项目,模仿物流发货,A公司每向B公司一车货,发2次消息,分A出发时和到达B时,2消息内容相同。消息包含车号、司机、货物清单及可能是集装箱等。wsdl文件:



	
	
	
		
			
		
		
			
		
	
	
		
	
	
		
	
	
		
	
	
		
			
			
		
		
			
			
		
	
	
		
		
			
			
				
			
			
				
			
		
		
			
			
				
			
			
				
			
		
	
	
		
			
		
	
	


         用wsimport生成相应的类,主要的是接口LGSService,

@WebService(name = "LGSService", targetNamespace = "http://hjs.com/services/atob/lgsservice/v1.0/")
@XmlSeeAlso({
    com.hjs.schema.atob.logistics.ObjectFactory.class,
    com.hjs.schema.atob.common.ObjectFactory.class
})
public interface LGSService {
    @WebMethod(operationName = "CargoArrival", action = "http://hjs.com/services/atob/lgsservice/v1.0/CargoArrival")
    @RequestWrapper(localName = "CargoArrival", targetNamespace = "http://hjs.com/schema/atob/logistics/", className = "com.hjs.schema.atob.logistics.CargoArrival")
    @ResponseWrapper(localName = "ResponseMessage", targetNamespace = "http://hjs.com/schema/atob/common/", className = "com.hjs.schema.atob.common.ResponseMessageType")
    public void cargoArrival(
        @WebParam(name = "Head", targetNamespace = "http://hjs.com/schema/atob/logistics/")
        com.hjs.schema.atob.logistics.BaseMessageType.Head head,
        @WebParam(name = "LGS", targetNamespace = "http://hjs.com/schema/atob/logistics/")
        List lgs,
        @WebParam(name = "REFF_NO", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder reffNO,
        @WebParam(name = "SENDER", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder sender,
        @WebParam(name = "RECEIVER", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder receiver,
        @WebParam(name = "RECEIVED_DTTM", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder receivedDTTM,
        @WebParam(name = "ACKNSTAT", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder acknstat,
        @WebParam(name = "ACKNREMARK", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder acknremark);

    
    @WebMethod(operationName = "CargoPreannounce", action = "http://hjs.com/services/atob/lgsservice/v1.0/CargoPreannounce")
    @RequestWrapper(localName = "CargoPreannounce", targetNamespace = "http://hjs.com/schema/atob/logistics/", className = "com.hjs.schema.atob.logistics.CargoPreannounce")
    @ResponseWrapper(localName = "ResponseMessage", targetNamespace = "http://hjs.com/schema/atob/common/", className = "com.hjs.schema.atob.common.ResponseMessageType")
    public void cargoPreannounce(
        @WebParam(name = "Head", targetNamespace = "http://hjs.com/schema/atob/logistics/")
        com.hjs.schema.atob.logistics.BaseMessageType.Head head,
        @WebParam(name = "LGS", targetNamespace = "")
        List lgs,
        @WebParam(name = "REFF_NO", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder reffNO,
        @WebParam(name = "SENDER", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder sender,
        @WebParam(name = "RECEIVER", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder receiver,
        @WebParam(name = "RECEIVED_DTTM", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder receivedDTTM,
        @WebParam(name = "ACKNSTAT", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder acknstat,
        @WebParam(name = "ACKNREMARK", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
        Holder acknremark);

}


再做一个类LGSServiceImpl实现此接口

@WebService(name = "LGSService", targetNamespace = "http://hjs.com/services/atob/lgsservice/v1.0/")
@BindingType(value = javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public class LGSServiceImpl implements LGSService {

	@Override
	public void cargoArrival(Head head, List lgs, Holder reffNO, Holder sender,
			Holder receiver, Holder receivedDTTM, Holder acknstat,
			Holder acknremark) {
		// 代码省略。。。
	}

	@Override
	public void cargoPreannounce(Head head, List lgs, Holder reffNO, Holder sender,
			Holder receiver, Holder receivedDTTM, Holder acknstat,
			Holder acknremark) {
		// 代码省略。。。
	}

}

发布此服务

	LGSService ls = new LGSServiceImpl();
	Endpoint.publish("http://localhost:8090/services/atob/lgsservice/v1.0/", ls);


可以正常发布,打开http://localhost:8090/services/atob/lgsservice/v1.0/?wsdl,可以看到wsdl,但那是系统生成的,看起来别扭,也不方便客户端查看。

为了能让客户端查看原装的wsdl和其它schema,可以以META-DATA方式发布,如

	LGSService ls = new LGSServiceImpl();
	Endpoint lgsendpoint = Endpoint.create(ls);
	List metadataFile = new ArrayList();
	     metadataFile.add( new File("src/META-INF/wsdl/LGSService.wsdl"));
	     metadataFile.add( new File("src/META-INF/wsdl/BaseMessage.xsd"));
	     metadataFile.add( new File("src/META-INF/wsdl/ABAWBS.xsd"));
	     metadataFile.add( new File("src/META-INF/wsdl/CONTAINER.xsd"));
	     metadataFile.add( new File("src/META-INF/wsdl/ABLGS.xsd"));
	     metadataFile.add( new File("src/META-INF/wsdl/ResponseMessage.xsd"));
	     
	     List metadata = new ArrayList();
	     try {
	    	for(File file : metadataFile){
	    	 	Source source = new StreamSource(new FileInputStream(file));
	    	 	source.setSystemId(file.toURI().toURL().toExternalForm());
	    	 	metadata.add(source);
	    	}
			lgsendpoint.setMetadata(metadata);
			lgsendpoint.publish("http://localhost:8090/services/atob/lgsservice/v1.0/");
			
		} catch (FileNotFoundException | MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

不能成功发布,系统报错:

服务器运行时错误: More than one schema for the target namespace http://hjs.com/schema/atob/logistics/

想了好久,什么问题?查看JAX-WS文档及网上资料,感觉是系统无法辨别是生成的wsdl和xsd还是原装META的,应该在类上指定,加上注释

	serviceName = "LGSService", portName = "LGSServiceSOAP",

再发布,系统报:

Method cargoPreannounce is exposed as WebMethod,
 but there is no corresponding wsdl operation with name {http://hjs.com/services/atob/lgsservice/v1.0/}cargoPreannounce in the wsdl:portType{http://hjs.com/services/atob/lgsservice/v1.0/}LGSService

原来是方法上没有加注释,那就加上吧

	@WebMethod(operationName = "CargoArrival", action = "http://hjs.com/services/atob/lgsservice/v1.0/CargoArrival")
    @RequestWrapper(localName = "CargoArrival", targetNamespace = "http://hjs.com/schema/atob/logistics/", className = "com.hjs.schema.atob.logistics.CargoArrival")
    @ResponseWrapper(localName = "ResponseMessage", targetNamespace = "http://hjs.com/schema/atob/common/", className = "com.hjs.schema.atob.common.ResponseMessageType")

再发布,还有错:

javax.xml.ws.WebServiceException: class com.hjs.schema.atob.logistics.CargoPreannounce do not have a property of the name arg0
再找资料,认为类内的方法参数与xsd不一致。参考接口方法的参数,全部复制到实现类里

public void cargoArrival(
		@WebParam(name = "Head", targetNamespace = "http://hjs.com/schema/atob/logistics/")
	        com.hjs.schema.atob.logistics.BaseMessageType.Head head,
	       @WebParam(name = "LGS", targetNamespace = "http://hjs.com/schema/atob/logistics/")
	        List lgs,
	        @WebParam(name = "REFF_NO", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
	        Holder reffNO,
	        @WebParam(name = "SENDER", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
	        Holder sender,
	        @WebParam(name = "RECEIVER", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
	        Holder receiver,
	      @WebParam(name = "RECEIVED_DTTM", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
	        Holder receivedDTTM,
	        @WebParam(name = "ACKNSTAT", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
	        Holder acknstat,
	        @WebParam(name = "ACKNREMARK", targetNamespace = "http://hjs.com/schema/atob/common/", mode = WebParam.Mode.OUT)
	        Holder acknremark
			) {
		// 省略代码。。。
	}


发布!OK啦!打开wsdl,与原装的一致。




















































分别打开每一个xsd,也与原装发布的一致。算是成功发布了吧。


总结:在写实现类时,要按JAX-WS的要求,或参考接口,分别加上相应的注释,不只是简单实现。





你可能感兴趣的:(java)