计算机语言分类有很多,如C、C++、C#、Java、Php、Python等等,她们有各自的特性及擅长的领域,但她们各自又不是全能的。在一个稍微大型一点的项目都会用到多种语言共同完成,那么这些编程语言如何进行通信呢。什么意思呢,就是比如说我Java写的一个方法,其他编程语言要怎么去调用呢?这就是本文要探讨的问题了。

一般来说,方法层面的编程语言通信用的是网络接口形式,只暴露出形参和结果供别人调用。接口一般分为接口定义者和接口调用者,定义者可以规定接收参数的类型及返回形式,而接口定义者则只能完全按照接口定义者规定的参数进行访问。就叫是我们所说的webService(网络服务)。

以前的做法是利用XML作接口格式定义,然后通过Http做通讯和请求,如大名鼎鼎的SOAP,其实现在也是的,只不过现在流行RestFul风格的Rest接口形式,但用的还是XML+HTTP,那这两者有啥区别呢?最大的区别就是SOAP返回的主要是XML格式,有时还需要附带一些辅助文件,而Rest则还可以返回JSON类型的字符串,减少了很多繁乱的XML标签。本文就以Java为例,用她写一个接口,并让其他人去调用,以此来简单展示接口调用是怎么样一个过程。

步骤:

1、本机装有Java JDK运行环境及编程IDE(如Myeclipse)

2、建立一个maven项目,用以下载jar包,项目结构如下:


java写个接口让别人调用 java如何写接口给别人调用_java

3 pom.xml文件内容如下:


[html]  view plain  copy




1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
3. <modelVersion>4.0.0</modelVersion>  
4. <groupId>ws</groupId>  
5. <artifactId>restful</artifactId>  
6. <packaging>war</packaging>  
7. <version>0.0.1-SNAPSHOT</version>  
8. <name>restful-server</name>  
9. <url>http://maven.apache.org</url>  
10. <properties>  
11. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
12. <jersey.version>2.6</jersey.version>  
13. <jersey-spring.version>2.23.1</jersey-spring.version>  
14. <spring.version>4.2.7.RELEASE</spring.version>  
15. <servlet-api-version>3.1.0</servlet-api-version>  
16. <logback.version>1.1.1</logback.version>  
17. <jcloverslf4j.version>1.7.6</jcloverslf4j.version>  
18. </properties>  
19. <dependencies>  
20. <dependency>  
21. <groupId>junit</groupId>  
22. <artifactId>junit</artifactId>  
23. <version>3.8.1</version>  
24. <scope>test</scope>  
25. </dependency>  
26.       
27. <dependency>  
28. <groupId>org.glassfish.jersey.ext</groupId>  
29. <artifactId>jersey-spring3</artifactId>  
30. <version>${jersey-spring.version}</version>  
31. <exclusions>  
32. <exclusion>  
33. <groupId>org.springframework</groupId>  
34. <artifactId>spring-core</artifactId>  
35. </exclusion>  
36. <exclusion>  
37. <groupId>org.springframework</groupId>  
38. <artifactId>spring-web</artifactId>  
39. </exclusion>  
40. <exclusion>  
41. <groupId>org.springframework</groupId>  
42. <artifactId>spring-beans</artifactId>  
43. </exclusion>  
44. </exclusions>  
45. </dependency>  
46.   
47. <dependency>  
48. <groupId>org.glassfish.jersey.containers</groupId>  
49. <artifactId>jersey-container-servlet</artifactId>  
50. <version>${jersey-spring.version}</version>  
51. </dependency>  
52. <dependency>  
53. <groupId>org.glassfish.jersey.containers</groupId>  
54. <artifactId>jersey-container-servlet-core</artifactId>  
55. <version>${jersey-spring.version}</version>  
56. </dependency>  
57.   
58. <dependency>  
59. <groupId>org.glassfish.jersey.media</groupId>  
60. <artifactId>jersey-media-json-jackson</artifactId>  
61. <version>${jersey.version}</version>  
62. </dependency>  
63. <dependency>  
64. <groupId>org.glassfish.jersey.media</groupId>  
65. <artifactId>jersey-media-multipart</artifactId>  
66. <version>${jersey.version}</version>  
67. </dependency>  
68. <dependency>  
69. <groupId>org.glassfish.jersey.ext</groupId>  
70. <artifactId>jersey-entity-filtering</artifactId>  
71. <version>${jersey.version}</version>  
72. </dependency>  
73.   
74. <!-- Spring4.2 dependencies -->  
75. <dependency>  
76. <groupId>org.springframework</groupId>  
77. <artifactId>spring-core</artifactId>  
78. <version>${spring.version}</version>  
79. </dependency>  
80.   
81. <dependency>  
82. <groupId>org.springframework</groupId>  
83. <artifactId>spring-context</artifactId>  
84. <version>${spring.version}</version>  
85. </dependency>  
86.   
87. <dependency>  
88. <groupId>org.springframework</groupId>  
89. <artifactId>spring-web</artifactId>  
90. <version>${spring.version}</version>  
91. </dependency>  
92.   
93. <dependency>  
94. <groupId>org.springframework</groupId>  
95. <artifactId>spring-jdbc</artifactId>  
96. <version>${spring.version}</version>  
97. </dependency>  
98.   
99. <dependency>  
100. <groupId>org.springframework</groupId>  
101. <artifactId>spring-tx</artifactId>  
102. <version>${spring.version}</version>  
103. </dependency>  
104. <dependency>  
105. <groupId>org.springframework</groupId>  
106. <artifactId>spring-test</artifactId>  
107. <version>${spring.version}</version>  
108. <scope>test</scope>  
109. </dependency>  
110.   
111. <dependency>  
112. <groupId>javax.servlet</groupId>  
113. <artifactId>javax.servlet-api</artifactId>  
114. <version>${servlet-api-version}</version>  
115. <scope>provided</scope>  
116. </dependency>  
117.   
118. <!-- Logback dependencies -->  
119. <dependency>  
120. <groupId>ch.qos.logback</groupId>  
121. <artifactId>logback-classic</artifactId>  
122. <version>${logback.version}</version>  
123. </dependency>  
124. <dependency>  
125. <groupId>org.slf4j</groupId>  
126. <artifactId>jcl-over-slf4j</artifactId>  
127. <version>${jcloverslf4j.version}</version>  
128. </dependency>  
129.       
130. </dependencies>  
131. <build>  
132. <finalName>restful</finalName>  
133. </build>  
134. </project>


4 applicationContext.xml内容如下:



[html]  view plain  copy





1. <?xml version="1.0" encoding="UTF-8"?>  
2. <beans xmlns="http://www.springframework.org/schema/beans"  
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
4. xmlns:context="http://www.springframework.org/schema/context"  
5. xmlns:tx="http://www.springframework.org/schema/tx"  
6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
7. >  
8.   
9. <context:component-scan base-package="com.kendy.*"></context:component-scan>  
10. </beans>


5 web.xml则主要配置采用的容器、日志管理及拦截器,拦截器可以实现到达请求郑涛之前进行身份认证,踢除没有访问资格的请求,而rest项目一般是用Jersey容器。配置如下:(kendy只是我的英文名,你们可以自己定义路径)



[html]  view plain  copy





1. <?xml version="1.0" encoding="UTF-8"?>  
2. <web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
3. <display-name></display-name>  
4. <context-param>  
5. <param-name>contextConfigLocation</param-name>  
6. <param-value>classpath:applicationContext.xml</param-value>  
7. </context-param>  
8. <listener>  
9. <listener-class>  
10.             org.springframework.web.context.ContextLoaderListener  
11. </listener-class>  
12. </listener>  
13. <servlet>  
14. <servlet-name>jersey-serlvet</servlet-name>  
15. <servlet-class>  
16.             org.glassfish.jersey.servlet.ServletContainer  
17. </servlet-class>  
18. <init-param>  
19. <param-name>javax.ws.rs.Application</param-name>  
20. <param-value>com.kendy.filter.RestJaxRsApplication</param-value>  
21. </init-param>  
22. <load-on-startup>1</load-on-startup>  
23. </servlet>  
24. <servlet-mapping>  
25. <servlet-name>jersey-serlvet</servlet-name>  
26. <url-pattern>/*</url-pattern>  
27. </servlet-mapping>  
28. </web-app>


6 拦截器如下:


[java]  view plain  copy




1. import java.io.IOException;  
2. import java.io.InputStream;  
3. import java.util.List;  
4. import java.util.Map.Entry;  
5.   
6. import javax.ws.rs.WebApplicationException;  
7. import javax.ws.rs.container.ContainerRequestContext;  
8. import javax.ws.rs.container.ContainerRequestFilter;  
9. import javax.ws.rs.core.MultivaluedMap;  
10. import javax.ws.rs.core.Response.Status;  
11. import javax.ws.rs.ext.Provider;  
12.   
13. /**
14.  * 拦截请求
15.  */  
16. @Provider  
17. public class MyFilter implements ContainerRequestFilter {  
18.   
19. @Override  
20. public void filter(ContainerRequestContext context) throws IOException {  
21.       
22. //打印出所有请求头  
23.     MultivaluedMap<String, String> map =  context.getHeaders();  
24. for(Entry<String, List<String>> entry : map.entrySet()){  
25.         String key = entry.getKey();  
26.         List<String> valueList = entry.getValue();  
27.         String values = valueList.toString();  
28. ":"+values.substring(1,values.length()-1));  
29.     }


7 注册Jersey容器所要管理的类



[java]  view plain  copy





1. import org.codehaus.jackson.jaxrs.JacksonJsonProvider;  
2. import org.glassfish.jersey.server.ResourceConfig;  
3.   
4. import com.kendy.restful.AccountManager;  
5. import com.kendy.restful.AuthorityManager;  
6. import com.kendy.restful.CardManager;  
7. import com.kendy.restful.DeviceManager;  
8. import com.kendy.restful.UserResource;  
9.   
10. /**
11.  * ${DESCRIPTION}
12.  */  
13. public class RestJaxRsApplication extends ResourceConfig {  
14.   
15. /**
16.      * Register JAX-RS application components.
17.      */  
18. public RestJaxRsApplication() {  
19.   
20. //服务类所在的包路径  
21. "com.kendy.*");  
22.           
23. // register application resources  
24. this.register(YouClass.class);  
25.        
26. // register filters  
27. this.register(MyFilter.class);  
28. //this.register(RequestContextFilter.class);  
29.           
30. class);  
31. //register(MultiPartFeature.class);  
32.     }  
33. }


8 接口定义(Restful风格)



[java]  view plain  copy



1. package com.kendy.restful;  
2.   
3. import java.text.SimpleDateFormat;  
4. import java.util.ArrayList;  
5. import java.util.Date;  
6. import java.util.HashMap;  
7. import java.util.List;  
8. import java.util.Map;  
9.   
10. import javax.ws.rs.Consumes;  
11. import javax.ws.rs.POST;  
12. import javax.ws.rs.Path;  
13. import javax.ws.rs.Produces;  
14. import javax.ws.rs.core.MediaType;  
15.   
16. import org.springframework.stereotype.Component;  
17.   
18. @Component  
19. @Path("/CardManager")  
20. public class CardManager {  
21.       
22. private SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
23.   
24. @POST  
25. @Path("size")  
26. @Consumes(MediaType.APPLICATION_JSON)  
27. @Produces(MediaType.APPLICATION_JSON)  
28. public Map<String,Object> size(){  
29. new HashMap<>();  
30. //do something here  
31. "Size", 1024);  
32. return map;  
33.     }  
34.       
35. @POST  
36. @Path("getDetail")  
37. @Consumes(MediaType.APPLICATION_JSON)  
38. @Produces(MediaType.APPLICATION_JSON)  
39. public Map<String,List<Map<String,Object>>> getDetail(){  
40. new HashMap<>();  
41. //do something here  
42. new ArrayList<>();  
43. new HashMap<>();  
44. "UUID", 10086);  
45. "CardID", 10081);  
46. "StartTime", sdf.format(new Date()));  
47. "EndTime", sdf.format(new Date()));  
48.         list.add(subMap);  
49. "Card", list);  
50.           
51. return map;  
52.     }  
53. }


9 调用接口,有多种方式,本文用HttpClient



[java]  view plain  copy





1. /**
2.      * 发送 post请求webService接口
3.      * @param url 访问的接口地址
4.      * @param account 用户名
5.      * @param code 密码
6.      * @param param 查询参数
7.      * @return HttpResponse 该类包含请求方法的态码及返回的数据
8.      */    
9. public static HttpResponse post(String url,String account,String code,Map<String,Object> param) {    
10. //创建HttpClient实例及Post方法  
11. new DefaultHttpClient();    
12. new HttpPost(url);   
13. //对用户密码MD5加密  
14.         code = getMD5(code);  
15. //添加相关请求头,依情况而定  
16. "Authorization","WSSE profile=\"UsernameToken\"");    
17. "X-WSSE","UsernameToken Username=\""+account+"\",PasswordDigest=\""+code+"\"");    
18. "Content-type","application/json; charset=utf-8");    
19. "Accept", "application/json");    
20. "Connection","keep-alive");    
21. "Accept-Encoding","gzip");    
22. "Accept-Language", "zh-CN,en,*");    
23. "User-Agent","Mozilla/5.0");   
24. //传递请求参数  
25.         String paramJsonStr = JSON.toJSONString(param);  
26. if(param != null)  
27. new StringEntity(paramJsonStr, Charset.forName("UTF-8")));    
28. null;  
29. try {    
30. //执行post请求  
31.             response = httpclient.execute(httppost);    
32. catch (Exception e) {    
33.             e.printStackTrace();    
34.         }   
35. return response;  
36.     }


10 返回接口



java写个接口让别人调用 java如何写接口给别人调用_webservice 接口_02

11 最后通过Map、List和Json工具对返回来的字面量进行各种处理。


[java]  view plain  copy




1. /**
2.  * 将从接口返回的JSON数据转换为实体集合等待插入数据表
3.  * 实体 IgmAccessControlChannelModel --> IGM_ACCESSCONTROL_CHANNEL
4.  *     IgmStationDoorModel --> IGM_STATION_DOOR
5.  */  
6. @SuppressWarnings({ "unchecked", "rawtypes" })  
7. private Map<String,Object> getDeviceEntityList(String data){  
8. new HashMap<>();  
9. //把以下三个结果放到totalMap里返回  
10. new ArrayList<>();  
11. new ArrayList<>();  
12. new ArrayList<>();  
13.       
14. null;  
15. null;  
16.       
17. class);  
18.     map = (Map<String,List<Map<String,Object>>>)map;  
19. "Device");  
20.       
21. for(Map<String,Object> deviceMap : deviceList){  
22. "DeviceID")+"");  
23. "Channels");  
24.         List<Map<String,Object>> channelList = (List<Map<String,Object>>)channels;  
25.           
26. ""; //用于设置igmaccessControlchannel表和igmstationDoor表的stationDoorid  
27. //判断该门禁设备ID在本平台是否匹配  
28. boolean isMatched = isDeviceIdMatched(deviceId);  
29.           
30. if(isMatched){  
31. for(Map<String,Object> chnnelMap : channelList){  
32. new IgmAccessControlChannelModel();  
33. new IgmStationDoorModel();  
34. for(Map.Entry<String, Object> entry : chnnelMap.entrySet()){  
35.                     String key =  entry.getKey().trim();  
36. "";  
37. if(key.equals("Channel")){  
38. "";  
39. else{  
40.                         value = (String)entry.getValue();  
41.                     }  
42.                       
43. switch(key){  
44. case "Channel":  
45.                         accessControlModel.setCommandCode(Integer.parseInt(value));  
46. "控制通道"+value);  
47.                         stationDoorModel.setDoorCode(value);  
48. break;  
49. case "Description":  
50.                         stationDoorModel.setStationDoorName(value);  
51. break;  
52. default: break;  
53.                     }  
54.                 }  
55.                 id = UUID.randomUUID().toString();  
56.                   
57.                 accessControlModel.setAccessControlChannelId(UUID.randomUUID().toString());  
58.                 accessControlModel.setDeviceId(deviceId);  
59.                 accessControlModel.setStationDoorId(id);  
60.                   
61.                 stationDoorModel.setStationDoorId(id);  
62.                 stationDoorModel.setDeviceId(deviceId);  
63. "指纹门禁");  
64.                   
65.                 accessControlList.add(accessControlModel);  
66.                 doorList.add(stationDoorModel);  
67.             }  
68.             deviceIds.add(deviceId);  
69. else{  
70. //deviceId不匹配的跳过  
71.         }  
72.     }