java如何写接口给别人调用的示例代码
计算机语言分类有很多,如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包,项目结构如下:
3 pom.xml文件内容如下:
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelversion>4.0.0</modelversion> <groupid>ws</groupid> <artifactid>restful</artifactid> <packaging>war</packaging> <version>0.0.1-snapshot</version> <name>restful-server</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceencoding>utf-8</project.build.sourceencoding> <jersey.version>2.6</jersey.version> <jersey-spring.version>2.23.1</jersey-spring.version> <spring.version>4.2.7.release</spring.version> <servlet-api-version>3.1.0</servlet-api-version> <logback.version>1.1.1</logback.version> <jcloverslf4j.version>1.7.6</jcloverslf4j.version> </properties> <dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupid>org.glassfish.jersey.ext</groupid> <artifactid>jersey-spring3</artifactid> <version>${jersey-spring.version}</version> <exclusions> <exclusion> <groupid>org.springframework</groupid> <artifactid>spring-core</artifactid> </exclusion> <exclusion> <groupid>org.springframework</groupid> <artifactid>spring-web</artifactid> </exclusion> <exclusion> <groupid>org.springframework</groupid> <artifactid>spring-beans</artifactid> </exclusion> </exclusions> </dependency> <dependency> <groupid>org.glassfish.jersey.containers</groupid> <artifactid>jersey-container-servlet</artifactid> <version>${jersey-spring.version}</version> </dependency> <dependency> <groupid>org.glassfish.jersey.containers</groupid> <artifactid>jersey-container-servlet-core</artifactid> <version>${jersey-spring.version}</version> </dependency> <dependency> <groupid>org.glassfish.jersey.media</groupid> <artifactid>jersey-media-json-jackson</artifactid> <version>${jersey.version}</version> </dependency> <dependency> <groupid>org.glassfish.jersey.media</groupid> <artifactid>jersey-media-multipart</artifactid> <version>${jersey.version}</version> </dependency> <dependency> <groupid>org.glassfish.jersey.ext</groupid> <artifactid>jersey-entity-filtering</artifactid> <version>${jersey.version}</version> </dependency> <!-- spring4.2 dependencies --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-core</artifactid> <version>${spring.version}</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-context</artifactid> <version>${spring.version}</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-web</artifactid> <version>${spring.version}</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-jdbc</artifactid> <version>${spring.version}</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-tx</artifactid> <version>${spring.version}</version> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-test</artifactid> <version>${spring.version}</version> <scope>test</scope> </dependency> <dependency> <groupid>javax.servlet</groupid> <artifactid>javax.servlet-api</artifactid> <version>${servlet-api-version}</version> <scope>provided</scope> </dependency> <!-- logback dependencies --> <dependency> <groupid>ch.qos.logback</groupid> <artifactid>logback-classic</artifactid> <version>${logback.version}</version> </dependency> <dependency> <groupid>org.slf4j</groupid> <artifactid>jcl-over-slf4j</artifactid> <version>${jcloverslf4j.version}</version> </dependency> </dependencies> <build> <finalname>restful</finalname> </build> </project>
4 applicationcontext.xml内容如下:
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <context:component-scan base-package="com.kendy.*"></context:component-scan> </beans>
5 web.xml则主要配置采用的容器、日志管理及拦截器,拦截器可以实现到达请求郑涛之前进行身份认证,踢除没有访问资格的请求,而rest项目一般是用jersey容器。配置如下:(kendy只是我的英文名,你们可以自己定义路径)
<?xml version="1.0" encoding="utf-8"?> <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"> <display-name></display-name> <context-param> <param-name>contextconfiglocation</param-name> <param-value>classpath:applicationcontext.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.contextloaderlistener </listener-class> </listener> <servlet> <servlet-name>jersey-serlvet</servlet-name> <servlet-class> org.glassfish.jersey.servlet.servletcontainer </servlet-class> <init-param> <param-name>javax.ws.rs.application</param-name> <param-value>com.kendy.filter.restjaxrsapplication</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey-serlvet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
6 拦截器如下:
import java.io.ioexception; import java.io.inputstream; import java.util.list; import java.util.map.entry; import javax.ws.rs.webapplicationexception; import javax.ws.rs.container.containerrequestcontext; import javax.ws.rs.container.containerrequestfilter; import javax.ws.rs.core.multivaluedmap; import javax.ws.rs.core.response.status; import javax.ws.rs.ext.provider; /** * 拦截请求 */ @provider public class myfilter implements containerrequestfilter { @override public void filter(containerrequestcontext context) throws ioexception { //打印出所有请求头 multivaluedmap<string, string> map = context.getheaders(); for(entry<string, list<string>> entry : map.entryset()){ string key = entry.getkey(); list<string> valuelist = entry.getvalue(); string values = valuelist.tostring(); system.out.println(key + ":"+values.substring(1,values.length()-1)); }
7 注册jersey容器所要管理的类
import org.codehaus.jackson.jaxrs.jacksonjsonprovider; import org.glassfish.jersey.server.resourceconfig; import com.kendy.restful.accountmanager; import com.kendy.restful.authoritymanager; import com.kendy.restful.cardmanager; import com.kendy.restful.devicemanager; import com.kendy.restful.userresource; /** * ${description} */ public class restjaxrsapplication extends resourceconfig { /** * register jax-rs application components. */ public restjaxrsapplication() { //服务类所在的包路径 packages("com.kendy.*"); // register application resources this.register(youclass.class); // register filters this.register(myfilter.class); //this.register(requestcontextfilter.class); register(jacksonjsonprovider.class); //register(multipartfeature.class); } }
8 接口定义(restful风格)
package com.kendy.restful; import java.text.simpledateformat; import java.util.arraylist; import java.util.date; import java.util.hashmap; import java.util.list; import java.util.map; import javax.ws.rs.consumes; import javax.ws.rs.post; import javax.ws.rs.path; import javax.ws.rs.produces; import javax.ws.rs.core.mediatype; import org.springframework.stereotype.component; @component @path("/cardmanager") public class cardmanager { private simpledateformat sdf =new simpledateformat("yyyy-mm-dd hh:mm:ss"); @post @path("size") @consumes(mediatype.application_json) @produces(mediatype.application_json) public map<string,object> size(){ map<string,object> map = new hashmap<>(); //do something here map.put("size", 1024); return map; } @post @path("getdetail") @consumes(mediatype.application_json) @produces(mediatype.application_json) public map<string,list<map<string,object>>> getdetail(){ map<string,list<map<string,object>>> map = new hashmap<>(); //do something here list<map<string,object>> list = new arraylist<>(); map<string,object> submap = new hashmap<>(); submap.put("uuid", 10086); submap.put("cardid", 10081); submap.put("starttime", sdf.format(new date())); submap.put("endtime", sdf.format(new date())); list.add(submap); map.put("card", list); return map; } }
9 调用接口,有多种方式,本文用httpclient
/** * 发送 post请求webservice接口 * @param url 访问的接口地址 * @param account 用户名 * @param code 密码 * @param param 查询参数 * @return httpresponse 该类包含请求方法的态码及返回的数据 */ public static httpresponse post(string url,string account,string code,map<string,object> param) { //创建httpclient实例及post方法 httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(url); //对用户密码md5加密 code = getmd5(code); //添加相关请求头,依情况而定 httppost.setheader("authorization","wsse profile=\"usernametoken\""); httppost.setheader("x-wsse","usernametoken username=\""+account+"\",passworddigest=\""+code+"\""); httppost.addheader("content-type","application/json; charset=utf-8"); httppost.setheader("accept", "application/json"); httppost.setheader("connection","keep-alive"); httppost.setheader("accept-encoding","gzip"); httppost.setheader("accept-language", "zh-cn,en,*"); httppost.setheader("user-agent","mozilla/5.0"); //传递请求参数 string paramjsonstr = json.tojsonstring(param); if(param != null) httppost.setentity(new stringentity(paramjsonstr, charset.forname("utf-8"))); httpresponse response = null; try { //执行post请求 response = httpclient.execute(httppost); } catch (exception e) { e.printstacktrace(); } return response; }
10 返回接口
11 最后通过map、list和json工具对返回来的字面量进行各种处理。
/** * 将从接口返回的json数据转换为实体集合等待插入数据表 * 实体 igmaccesscontrolchannelmodel --> igm_accesscontrol_channel * igmstationdoormodel --> igm_station_door */ @suppresswarnings({ "unchecked", "rawtypes" }) private map<string,object> getdeviceentitylist(string data){ map<string,object> totalmap = new hashmap<>(); //把以下三个结果放到totalmap里返回 list<igmaccesscontrolchannelmodel> accesscontrollist = new arraylist<>(); list<igmstationdoormodel> doorlist = new arraylist<>(); list<string> deviceids = new arraylist<>(); igmaccesscontrolchannelmodel accesscontrolmodel = null; igmstationdoormodel stationdoormodel = null; map map = json.parseobject(data, map.class); map = (map<string,list<map<string,object>>>)map; list<map<string,object>> devicelist = (list<map<string, object>>) map.get("device"); for(map<string,object> devicemap : devicelist){ string deviceid = (string)(devicemap.get("deviceid")+""); object channels = devicemap.get("channels"); list<map<string,object>> channellist = (list<map<string,object>>)channels; string id = ""; //用于设置igmaccesscontrolchannel表和igmstationdoor表的stationdoorid //判断该门禁设备id在本平台是否匹配 boolean ismatched = isdeviceidmatched(deviceid); if(ismatched){ for(map<string,object> chnnelmap : channellist){ accesscontrolmodel = new igmaccesscontrolchannelmodel(); stationdoormodel = new igmstationdoormodel(); for(map.entry<string, object> entry : chnnelmap.entryset()){ string key = entry.getkey().trim(); string value = ""; if(key.equals("channel")){ value =(integer)entry.getvalue()+""; }else{ value = (string)entry.getvalue(); } switch(key){ case "channel": accesscontrolmodel.setcommandcode(integer.parseint(value)); accesscontrolmodel.setcontrolchannelname("控制通道"+value); stationdoormodel.setdoorcode(value); break; case "description": stationdoormodel.setstationdoorname(value); break; default: break; } } id = uuid.randomuuid().tostring(); accesscontrolmodel.setaccesscontrolchannelid(uuid.randomuuid().tostring()); accesscontrolmodel.setdeviceid(deviceid); accesscontrolmodel.setstationdoorid(id); stationdoormodel.setstationdoorid(id); stationdoormodel.setdeviceid(deviceid); stationdoormodel.setremark("指纹门禁"); accesscontrollist.add(accesscontrolmodel); doorlist.add(stationdoormodel); } deviceids.add(deviceid); }else{ //deviceid不匹配的跳过 } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。