WebService开发(C#)+Java调用-教程

5 篇文章 0 订阅

 

注:1.本文重点讲如何实现

        2.本文包括WebService接口开发、JavaWeb调用等问题

        3.源代码已提交到github,Webservice接口:https://github.com/Bobo-peng/WebService

                                                      JavaWeb调用:https://github.com/Bobo-peng/JavaWebService     

一、WebService简介

1.什么是WebService?

        WebService是一种跨语言、夸平台的远程调用技术,或者说叫作一种技术标准。之所以叫WebService,是因为和Web服务类似,基于http协议(使用抓包就可以看到是http发送请求和接收结果),其主要作用在于向外暴露接口。

       说直白一点,就是这个技术标准想要达到的目的是:开启一个服务,并留出接口,让其他人来调用(重点是可以远程调用)。举例:用户查看一个网站的数据,一般就是查看该网站就完了;但是用户不喜欢用该网站公司的网页布局,想自己做一个炫酷的网页来展示一下数据,但是获取不到网站公司的数据库(数据库不可能对外公开),这时就用WebService开发几个接口提供给用户,这些接口返回用户想要的数据(数据格式可以自定义,使用json或者xml等),用户就像调函数一样间接获取了想要的数据,然后去开发自己的网页、展示。

2.WebService接口体验

       看一下常用的WebService接口-天气预报,这是国家气象局提供的天气预报接口:

http://www.webxml.com.cn/WebServices/WeatherWebService.asmx

第一个接口:

不传参数,返回所以可查询的城市:

    其他的接口可以自己点开根据说明看看。

    在连接的后面加上?wsdl

http://www.webxml.com.cn/webservices/weatherwebservice.asmx?wsdl

     这个相当于接口的说明文件,上面有每个接口的接口名称,接口参数等信息,通过查看这个文件,就知道怎调用的时候填什么参数(后面详细介绍)。

所以,自己开发一个天气预报的网站其实很简单(从这里调用接口即可)。

二、C# 开发WebService接口

       这里用C#开发,是因为刚做了个项目用的是C#,后面调用使用Java开发,后面介绍。

1.新建工程

开发环境:VS2013

自动生成一个接口:HelloWorld()

[WebMethod]的意思是向外暴露接口

什么都不用开发,点击运行:

点击调用:返回Hello World

2.添加接口函数

添加一个两个int型的数相加的函数接口,感受一下:

[WebMethod]
        public int Add(int a, int b)
        {
            return a + b;
        }

传入参数、调用:

3.接口返回数据库数据

为了让功能更丰富一些,通过接口获取数据库的数据。大概步骤是:

(1)接口传进参数

(2)WebService服务连接收据库,根据传入的参数查询数据库

(3)将数据封装成xml返回给用户

举例:用户输入"Tom"同学的名字,想要查询他的成绩。

为了说明问题,用sqlserver建一张表:

假设数据库数据是这样的(没有实际意义,只说明问题):

目标是将根据Name查询数据并以Xml的数据格式返回。

首先定义函数接口:

 [WebMethod]
        public string GetdbData(string Name)
        {
            //数据库操作
            string strcon = "server = localhost,1433;uid = sa; pwd = 123456; database = MyDataBase";
            string strSQL = "select Name,Chinese,Math,English from Student where Name = @name";
            SqlConnection con = new SqlConnection(strcon);
            SqlCommand cmd = new SqlCommand(strSQL, con);
            cmd.Parameters.Add("@name", SqlDbType.VarChar);
            cmd.Parameters["@name"].Value = Name;
            DataSet ds = new DataSet();
            try
            {
                SqlDataAdapter DA = new SqlDataAdapter(cmd);
                DA.Fill(ds, "tb");
            }
            catch (SqlException E)
            {
                throw new Exception(E.Message);
            }
            con.Close();//关闭数据库
            
            //封装xml
             XDocument xDoc = new XDocument();
             //创建一个根节点
             XElement root = new XElement("Root");
             xDoc.Add(root); //将根节点加入到XML对象中
             try
             {
                 for (int i = 0; ds.Tables.Count > 0 && i < ds.Tables[0].Rows.Count; i++)
                 {
                     //创建一个子节点
                     XElement xele = new XElement("Data" + (i + 1).ToString());
                     root.Add(xele);
                     for (int j = 0; j < e.Length; j++)
                     {
                         xele.SetElementValue(e[j], ds.Tables[0].Rows[i].ItemArray[j]);
                     }
                 }
                 //保存xml文件   
                 LogWriteLock.EnterWriteLock();
                 xDoc.Save(CurrPath + "student.xml");
                 LogWriteLock.ExitWriteLock();

             }
             catch (SqlException E)
             {
                 throw new Exception(E.Message);
             }

             return xDoc.ToString();
        
            
        }

    }

测试:

并保存为student.xml文件

查询的结果和数据库里的数据相符合,数据库有4个Tom,查询到4个。

这里的数据库连接操作可以查看另外一篇:C# SqlCommand 数据库连接操作

4.部署服务

开题说了WebService接口可以远程调用,这是它的优势或者说是主要的功能。首先得把开发好的部署起来,这里只说明在C#开发,部署在Windows平台,其他的形式的货平台的开发和部署不做讲述。

步骤:

  (1)打开IIS: 计算机管理->服务和应用程序->Internet信息服务(IIS)管理器;

(2)添加网站: 在网站选项上右键->添加网站… 。键入网站名称,选择webservice发布文件包的路径,分配端口,点击确定即可。

(3)设置.NET版本:(开发的时候选的4.0)

(4)开启目录浏览权限

紧接着就和调试的时候一样了:

三、Java调用

1.Java的简单调用

开发环境:Eclipse

新建一个Java工程:

新建一个类:WebServiceTest

Java调用WebService需要依赖几个jar包:

在工程下建一个lib文件夹,将依赖的jar包放进去(依赖包可以下载本文Java工程需要的所有jar包

然后需要把路径也需要添加进来:

路径加进来,图标和没加是有区别的:

定义一个方法:public static void GetStudent()

public static void GetStudent()
	{  
        try {
        	    String url ="http://localhost:9999/WebService.asmx";
        	    String namespace = "http://tempuri.org/";
		        Service service = new Service();  
		        Call call = (Call) service.createCall(); 
		        QName qname = new QName(namespace, "GetdbData"); //设置命名空间和需要调用的方法名
		        call.setOperationName(qname);
		        call.setTargetEndpointAddress(url);  
		        call.setSOAPActionURI(namespace + "GetdbData");
		        call.addParameter(new QName(namespace,"Name"), org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);// 接口的参数  
		        call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);//设置返回类型
		        String result = (String) call.invoke(new Object[] {"Tom"});  
		        System.out.println("结果: \n" + result);  
              } catch (Exception e) {  
             System.err.println(e.toString());  
	       }
	}

说明:(1)url是刚才部署的路径,这里如果部署在远程,就填远程的IP和端口

             (2)namespace是C#开发WebService接口时候自动生成的,也可以自己任意修改,两边保持一致即可。

                    

              (3)"GetdbData"是接口名,"Name"是参数名,"Tom"是参数值,如果没有参数就不需要call.addParameter这个函数,而invoke函数变为:String result = (String) call.invoke(new Object[] {});  如果有多个参数,就需要call.addParameter多次,然后

call.invoke(new Object[] {“参数1”,"参数2"}

运行结果:

2.JavaWeb简单的展示

     既然都做到这了,索性做个页面展示一下。

     (1)新建一个Web工程(选择动态Web工程):

工程名:StudentShow

新建完,工程包含这么多:

(2)在src下新建一个Class,命名为Student

编写Get和Set方法:

package com.service.entity;

public class Student {
	    private String Name;//学生姓名
	    private String Chinese;//语文
	    private String Math;//数学
	    private String English;//英语
	    public String getName() {  
	        return Name;  
	    }  
	    public void setName(String name) {  
	        this.Name = name;  
	    } 
	    public String getChinese() {  
	        return Chinese;  
	    }  
	    public void setChinese(String chinese) {  
	        this.Chinese = chinese;  
	    }   
	    public String getMath() {  
	        return Math;  
	    }  
	    public void setMath(String math) {  
	        this.Math = math;  
	    }  
	    public String getEnglish() {  
	        return English;  
	    }  
	    public void setEnglish(String english) {  
	        this.English = english;  
	    }  

}

(3)再新建一个Class,命名为:StudentService

作用:调用WebService接口,解析xml文件

package com.service;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.service.entity.Student;

public class StudentService {
	
	public List<Student> GetStudentInfo(String Name)
	{
		List<Student> stulist = new ArrayList<Student>(); 
		   try {  
				    String url ="http://localhost:9999/WebService.asmx";
	       	        String namespace = "http://tempuri.org/";
			        Service service = new Service();  
			        Call call = (Call) service.createCall(); 
			        QName qname = new QName(namespace, "GetdbData"); //设置命名空间和需要调用的方法名
			        call.setOperationName(qname);
			        call.setTargetEndpointAddress(url);  
			        call.setSOAPActionURI(namespace + "GetdbData");
			        call.addParameter(new QName(namespace,"Name"), org.apache.axis.encoding.XMLType.XSD_STRING, javax.xml.rpc.ParameterMode.IN);// 接口的参数  
			        call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);//设置返回类型
			        String result = (String) call.invoke(new Object[] {Name});  
			        System.out.println("结果: \n" + result);  
				    stulist = PreaseXml(result);
                } 
	          catch (Exception e) {  
	            System.err.println(e.toString());  
	    	}
		return stulist;

        }
	//解析Xml
	private List<Student> PreaseXml(String resxml)
	{
		List<Student> tlist = new ArrayList<Student>(); 
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();  
            StringReader sr = new StringReader(resxml);
            InputSource is = new InputSource(sr);
            Document document = builder.parse(is);
            //获取所有Root所有节点的集合
            NodeList rootList = document.getElementsByTagName("Root");
            //通过NodeList的getLength()
            int rootCnt = rootList.getLength();
            for(int i = 0; i < rootCnt; i++){
                Node root = rootList.item(i);
                NodeList childNodes = root.getChildNodes();
                //遍历childNodes获取每隔节点的节点名和节点值
                for(int j = 1; j < childNodes.getLength();){
                	Student mlist=new Student(); 
                    if(childNodes.item(j).getNodeType() == Node.ELEMENT_NODE){
                        //获取节点的节点名
                        System.out.print("第"+ (j+1) + "节点:"+childNodes.item(j).getNodeName()+"  ");
                        //获取类型节点的节点值
                        System.out.println("节点值:" + childNodes.item(j).getTextContent());
                         mlist.setName(childNodes.item(j).getChildNodes().item(1).getTextContent());
                         mlist.setChinese(childNodes.item(j).getChildNodes().item(3).getTextContent());
                         mlist.setMath(childNodes.item(j).getChildNodes().item(5).getTextContent());
                         mlist.setEnglish(childNodes.item(j).getChildNodes().item(7).getTextContent());
                        j +=2;
                    } 
                    tlist.add(mlist); 
                } 
                
            }
        } catch (ParserConfigurationException e) {          
            e.printStackTrace();
        } catch (SAXException e) {   
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
	  return tlist;
	}

}

(4)再新建一个Class,命名为:StudentServlet

作用:接收jsp请求

package com.service.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.annotation.WebServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.service.StudentService;
@WebServlet("/StudentServlet")
public class StudentServlet extends HttpServlet{
	 private static final long serialVersionUID = 1L;  
	    
	    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
	        // TODO Auto-generated method stub 
	    	// 处理响应数据的格式和编码,通知浏览器数据的显示方式
	     response.setCharacterEncoding("utf-8");
	     response.setContentType("text/html;charset=utf-8");
	     PrintWriter pw = response.getWriter();  
         pw.println("doGet!"); 
         System.out.println ("doGet1");  
         String Name=request.getParameter("name");   
         StudentService ws = new StudentService();
	     List list =  ws.GetStudentInfo(Name); 
	     request.setAttribute("list",list);  
	     request.getRequestDispatcher("/student.jsp").forward(request, response);  
	    }  

	    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
	        // TODO Auto-generated method stub  
	    }  


}

(5)新建student.jsp文件,style是从网上找的

<%@ page language="java" contentType="text/html; charset=utf-8"  pageEncoding="utf-8" import="com.service.entity.*,java.util.*"%>  
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
<!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>学生信息</title>
</head>
<body>
<style type="text/css">
table.dataintable {
	margin-top:15px;
	border-collapse:collapse;
	border:1px solid #aaa;
	width:100%;
	}

table.dataintable th {
	vertical-align:baseline;
	padding:5px 15px 5px 6px;
	background-color:#3F3F3F;
	border:1px solid #3F3F3F;
	text-align:left;
	color:#fff;
	}

table.dataintable td {
	vertical-align:text-top;
	padding:6px 15px 6px 6px;
	border:1px solid #aaa;
	}

table.dataintable tr:nth-child(odd) {
	background-color:#F5F5F5;
}

table.dataintable tr:nth-child(even) {
	background-color:#fff;
}
</style>
<form action ="StudentServlet" method="get">
输入姓名:<input type="text" name="name"/>
<input type="submit" value="查询" />
</form>
&nbsp;
&nbsp;</div>
<table class="dataintable">
<tr>
  <th>姓名</th>
  <th>语文</th>
  <th>数学</th>
  <th>英语</th>
</tr>

<c:forEach items="${list}" var="stu">  
    <tr>  
        <td><b>${stu.getName()}</b></td>  	
		<td>${stu.getChinese()}</td>  
        <td>${stu.getMath()}</td>   
    	<td>${stu.getEnglish()}</td>  
    </tr>  
</c:forEach> 
</body>
</html>

对于JavaWeb中页面请求和servlet返回请求结果可以参考Jsp页面请求-Servlet返回结果

(6)最后的效果:

  • 7
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值