天天看點

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

上一節實踐了Webservice的用戶端開發,那麼核心問題服務是如何開發和釋出呢?Webservice 服務端的開發有多種方式:

1、利用jdk+myeclipse  ,釋出和開發一個背景服務(适合獨立服務)

2、利用axis2+myeclipse+tomcat  開發和釋出(适合web工程)

3、利用cxf +  myeclipse +tomcat  開發和釋出(适合web工程)

4、利用 xfire +myeclipse+tomcat  開發和釋出(适合web工程)

從本節開始,将實踐這些不同的釋出webservice的方法,本節就先實踐第一種,利用 jdk+myeclipse來釋出一個背景服務

一、目标

1、掌握jdk中編寫webservice服務端工程的設定和開發過程

2、編寫用戶端

3、服務端和用戶端釋出,并進行調試

二、服務端編寫

1、建立一個服務端工程StudyWsStudent   ( 關于學生的webservice 服務)

為了便于服務端的程式進行擴充,在服務端的設計上,采用接口程式設計的方式,即采用  實體類,dao接口,dao實作,接口類的方式才組織。 代碼都很簡單。

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

進入後的選項要注意一下

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

Framework這裡,注意選JAX-WS,  另外JTL 這裡選none

先看一下工程的結構:

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

代碼如下:

實體類Student

package com.study.entity;

import java.util.List;

public class Student {
	
	
	String Name;
	String Sex;	
	String Birth;	
	String DateIn;	
	
	//已經選擇的課程
	List<String> ListLesson;
	
	public String getName() {
		return Name;
	}

	public void setName(String name) {
		Name = name;
	}

	public String getSex() {
		return Sex;
	}

	public void setSex(String sex) {
		Sex = sex;
	}

	public String getBirth() {
		return Birth;
	}

	public void setBirth(String birth) {
		Birth = birth;
	}

	public String getDateIn() {
		return DateIn;
	}

	public void setDateIn(String dateIn) {
		DateIn = dateIn;
	}

	
	
	//采用dao 方式開發的情況下,實體類是否要設計action?
	boolean selectLesson( String Lesson ){
		if(ListLesson.size()>10)
		{
			System.out.println("You have select ten Lesson, cannot select more!");
			return  false;
		}
		else{
			ListLesson.add(Lesson);
		}
		
		return true;
		
	}
	

}

           

實體操作接口StudentDAO

package com.study.dao;

import com.study.entity.Student;

public interface StudentDAO {
	
	//學生操作,新增學生
	boolean addStudent(Student student);
	
	//學生操作,删除學生
	boolean delStudent(Student  student);
	
	//學生操作,修改學生資訊
	boolean modifyStudent(Student  student);
	
	//學生操作,查詢學生資訊,查詢到傳回學生對象,否則傳回null
	Student queryStudent( String  StudentName);
		
	
}

           

操作接口實作 StudentDAOImpl

package com.study.dao.impl;

import com.study.dao.StudentDAO;
import com.study.entity.Student;

public class StudentDAOImpl implements StudentDAO {

	@Override
	public boolean addStudent(Student student) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean delStudent(Student student) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean modifyStudent(Student student) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Student queryStudent(String StudentName) {
		// TODO Auto-generated method stub
		return null;
	}

}

           

最後是Webservice 接口服務StudentOptApi

package com.study.student.service;

import java.util.ArrayList;
import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;

import com.study.dao.StudentDAO;
import com.study.dao.impl.StudentDAOImpl;
import com.study.entity.Student;

@WebService 
public class StudentOptApi {
	
	List<String > listStudentInfo=new ArrayList<String>();
	
	StudentDAO studentDAO ;
	
//	public  StudentOptApi(){
//		System.out.println("studentDAO is init");
//		studentDAO= new StudentDAOImpl();
//	}
	
	@WebMethod(exclude = true)
	public StudentDAO getStudentDAO() {
		return studentDAO;
	}
	
	@WebMethod(exclude = true)
	public void setStudentDAO(StudentDAO studentDAO) {
		this.studentDAO = studentDAO;
	}

	
	public boolean addStudent( Student  student){
		//調用studentDAO.addStudent 方法入庫
		System.out.println("Now put student into DB!");
		studentDAO.addStudent(student);
		
		//listStudent模拟資料庫中的student對象集合
		listStudentInfo.add("Name:"+student.getName()+",sex:"+student.getSex()+",birthday:"+student.getBirth());
//		for( Student aStudent : listStudent ){
//			System.out.println(aStudent.getName());
//		}
		
		return true;
		
	}
	
	@WebMethod(operationName = "queryStudent")	
	public String queryStudent( @WebParam(name = "StudentName")String  studentName){
		
		for(String  aStudentInfo : listStudentInfo )
		{
			if(aStudentInfo.startsWith("Name:"+studentName+",")){
				System.out.println("queryStudent Infomation successfully !");
				return   aStudentInfo;
			}
			else{
				System.out.println("queryStudent Infomation failture !");
				
			}
		}
		
		return "null";
		
	}
	
	
	 public static void main(String[] args) {   
		 
		 // create and publish an endpoint   
		 StudentOptApi studentWs = new StudentOptApi();   
		 studentWs.studentDAO= new StudentDAOImpl();
		 
	 
		 Student student1 = new Student();
		 student1.setName("Tom");
		 student1.setSex("male");
		 student1.setBirth("1970/05/08");
		 
		 Student student2 = new Student();
		 student2.setName("Lili");
		 student2.setSex("female");
		 student2.setBirth("1972/05/23");
		 
		 studentWs.addStudent(student1);
		 studentWs.addStudent(student2);
		 
		 //Endpoint endpoint = Endpoint.publish("http://localhost:8080/StudentService/", studentWs);    
		 Endpoint endpoint = Endpoint.publish("http://localhost:8080/StudentService/queryStudent", studentWs);
	 }   

}

           

這裡需要注意一下 StudentService 類,它采用了Webservice的annotation,@WebMethod(operationName = "addStudent",exclude = true), 如果不加 exclude = true  會報告下列錯誤

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

錯誤這裡說明了,JAXB 不支援interfaces類。 而我們的服務是面向接口的程式設計,是以需要通過 exclude = true 來解決這個問題。

另外,如果沒有寫類的初始化方法,也會報下面的異常

Exception in thread "main" com.sun.xml.internal.ws.model.RuntimeModelerException: The web service defined by the class

 com.study.student.service.StudentService does not contain any valid WebMethods.

at com.sun.xml.internal.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:233)

at com.sun.xml.internal.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:328)

at com.sun.xml.internal.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:190)

好,現在運作一下這個服務類,我們通過URL來打開這個服務

http://localhost:8080/StudentService/queryStudent

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

也給出了wsdl的位址,可以通過這個位址擷取wsdl檔案,并編寫用戶端

三、用戶端編寫

根據上一篇的說明,用戶端的開發步驟如下:

1)擷取wsdl 檔案

2)并寫編譯成本地java 檔案

3)編寫用戶端代碼

在本例中,由于服務在本地搭建的,是以可以1),2) 兩步合并處理,使用的指令為:

C:\jdk1.6.0_43\bin\wsimport  -d  E:\tmp  -s E:\cwqwork\myeclipse_workspace\StudyDubboCli\src -keep -verbose http://localhost:8080/StudentService/queryStudent?wsdl  

      wsimport 的幾個參數含義這裡列一下:

-keep:是否生成java源檔案

-d:指定輸出目錄

-s:指定源代碼輸出目錄

-p:以package的形式生成檔案

-verbose:在控制台顯示輸出資訊

執行上面的指令後,就可以生成用戶端需要的java檔案,如下圖:

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

下面,列一下用戶端的編碼: StudentWsCli.java

package com.study.webservice.client;

import com.study.student.service.StudentOptApi;
import com.study.student.service.StudentOptApiService;

public class StudentWsCli {
	
	public static void main(String[] args) {
		
		//從webservice接口中擷取到接口對象
		StudentOptApi  studentService = new StudentOptApiService().getStudentOptApiPort() ;    
        
		String info1 = studentService.queryStudent("Tom");
        System.out.println(info1);
        
        String info2 = studentService.queryStudent("Lili");
        System.out.println(info2);
        
        String info3 = studentService.queryStudent("Jerry");
        System.out.println(info3);

	}

}


           

在myeclipse裡面,工程情況如下:

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

運作用戶端,用戶端列印如下:

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

查詢"Tom", “Lili”,接口傳回 Tom的相關資訊,查詢“Jerry",接口傳回null

四、服務端釋出

下面嘗試将服務端釋出到虛拟機上運作,實踐一下服務端部署的過程。

因為是部署到虛拟機,用戶端要從主控端連接配接,是以修改一下服務端的endpoint代碼,将localhost修改為 0.0.0.0  表示允許全部的外部ip接入。将服務端用fatjar 打包後,傳送到虛拟機192.168.136.144上, 運作 java -jar StudyWsStudent_fat.jar

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

打開http://192.168.136.144:8080/StudentService/queryStudent  無法打開(原因後面說)

http://192.168.136.144:8080/StudentService/queryStudent?wsdl 正常打開

用用戶端連接配接,注意用戶端要修改一下StudentOptApiService.java檔案中的ip位址,否則要用http://192.168.136.144:8080/StudentService/queryStudent?wsdl 這個位址重新編譯。

用戶端連接配接正常,說明程式是釋出正常的。

現在回過來檢查 http://192.168.136.144:8080/StudentService/queryStudent  無法打開的原因,因為我們是用java自帶的編寫webservice服務,是以檢查一下144上的java版本,發現jar包是用jdk 1.6而 144上是java 1.8 。 144上有另外一個java 1.7,用1.7來運作,這下可以正常打開URL了

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試
Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

五、soap工具調試

最後介紹一個soap工具,因為webservice是基于soap協定的,是以可以用soap工具來進行測試,這裡簡單介紹一個soap工具soapUi

通過這個工具可以不用開發webservice用戶端直接通過工具調測接口。

建立一個工程:

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試

點OK後,在左邊的樹上選擇要測試的接口,輕按兩下打開測試界面,輸入參數,執行,可以在輸出區看到輸出結果。

Webservice實踐(三)基于JDK的jax ws進行服務端開發一、目标二、服務端編寫三、用戶端編寫四、服務端釋出五、soap工具調試