欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

浅谈java调用Restful API接口的方式

程序员文章站 2024-02-17 17:53:58
摘要:最近有一个需求,为客户提供一些restfulapi接口,qa使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程...

摘要:最近有一个需求,为客户提供一些restfulapi接口,qa使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试restfulapi接口,由于使用的是https,所以还要考虑到对于https的处理。由于我也是首次使用java调用restful接口,所以还要研究一番,自然也是查阅了一些资料。

分析:这个问题与模块之间的调用不同,比如我有两个模块frontend和backend,frontend提供前台展示,backend提供数据支持。之前使用过hession去把backend提供的服务注册成远程服务,在frontend端可以通过这种远程服务直接调到backend的接口。但这对于一个公司自己的一个项目耦合性比较高的情况下使用,没有问题。但是如果给客户注册这种远程服务,似乎不太好,耦合性太高。所以就考虑用一下方式进行处理。

基本介绍

restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多,

本次介绍三种:

1.httpurlconnection实现

2.httpclient实现

3.spring的resttemplate

一、httpclient

httpclient大家也许比较熟悉但又比较陌生,熟悉是知道他可以远程调用比如请求一个url,然后在response里获取到返回状态和返回信息,但是今天讲的稍微复杂一点,因为今天的主题是https,这个牵涉到证书或用户认证的问题。

确定使用httpclient之后,查询相关资料,发现httpclient的新版本与老版本不同,随然兼容老版本,但已经不提倡老版本是使用方式,很多都已经标记为过时的方法或类。今天就分别使用老版本4.2和最新版本4.5.3来写代码。

老版本4.2

需要认证

在准备证书阶段选择的是使用证书认证

package com.darren.test.https.v42;
import java.io.file;
import java.io.fileinputstream;
import java.security.keystore;
import org.apache.http.conn.ssl.sslsocketfactory;
public class httpscertifiedclient extends httpsclient {
	public httpscertifiedclient() {
	}
	@override 
	  public void preparecertificate() throws exception {
		// 获得密匙库 
		keystore truststore = keystore.getinstance(keystore.getdefaulttype());
		fileinputstream instream = new fileinputstream( 
		        new file("c:/users/zhda6001/downloads/software/xxx.keystore"));
		// fileinputstream instream = new fileinputstream(new file("c:/users/zhda6001/downloads/xxx.keystore")); 
		// 密匙库的密码 
		truststore.load(instream, "password".tochararray());
		// 注册密匙库 
		this.socketfactory = new sslsocketfactory(truststore);
		// 不校验域名 
		socketfactory.sethostnameverifier(sslsocketfactory.allow_all_hostname_verifier);
	}
}

跳过认证

在准备证书阶段选择的是跳过认证

package com.darren.test.https.v42;
import java.security.cert.certificateexception;
import java.security.cert.x509certificate;
import javax.net.ssl.sslcontext;
import javax.net.ssl.trustmanager;
import javax.net.ssl.x509trustmanager;
import org.apache.http.conn.ssl.sslsocketfactory;
public class httpstrustclient extends httpsclient {
	public httpstrustclient() {
	}
	@override 
	  public void preparecertificate() throws exception {
		// 跳过证书验证 
		sslcontext ctx = sslcontext.getinstance("tls");
		x509trustmanager tm = new x509trustmanager() {
			@override 
			      public void checkclienttrusted(x509certificate[] chain, string authtype) throws certificateexception {
			}
			@override 
			      public void checkservertrusted(x509certificate[] chain, string authtype) throws certificateexception {
			}
			@override 
			      public x509certificate[] getacceptedissuers() {
				return null;
			}
		}
		;
		// 设置成已信任的证书 
		ctx.init(null, new trustmanager[] {
			tm
		}
		, null);
		// 穿件ssl socket 工厂,并且设置不检查host名称 
		this.socketfactory = new sslsocketfactory(ctx, sslsocketfactory.allow_all_hostname_verifier);
	}
}

总结

现在发现这两个类都继承了同一个类httpsclient,并且httpsclient继承了defaulthttpclient类,可以发现,这里使用了模板方法模式。

package com.darren.test.https.v42;
import org.apache.http.conn.clientconnectionmanager;
import org.apache.http.conn.scheme.scheme;
import org.apache.http.conn.scheme.schemeregistry;
import org.apache.http.conn.ssl.sslsocketfactory;
import org.apache.http.impl.client.defaulthttpclient;
public abstract class httpsclient extends defaulthttpclient {
	protected sslsocketfactory socketfactory;
	/** 
   * 初始化httpsclient 
   * 
   * @return 返回当前实例 
   * @throws exception 
   */
	public httpsclient init() throws exception {
		this.preparecertificate();
		this.regist();
		return this;
	}
	/** 
   * 准备证书验证 
   * 
   * @throws exception 
   */
	public abstract void preparecertificate() throws exception;
	/** 
   * 注册协议和端口, 此方法也可以被子类重写 
   */
	protected void regist() {
		clientconnectionmanager ccm = this.getconnectionmanager();
		schemeregistry sr = ccm.getschemeregistry();
		sr.register(new scheme("https", 443, socketfactory));
	}
}

下边是工具类

package com.darren.test.https.v42;
import java.util.arraylist;
import java.util.list;
import java.util.map;
import java.util.set;
import org.apache.http.httpentity;
import org.apache.http.httpresponse;
import org.apache.http.namevaluepair;
import org.apache.http.client.entity.urlencodedformentity;
import org.apache.http.client.methods.httpget;
import org.apache.http.client.methods.httppost;
import org.apache.http.client.methods.httprequestbase;
import org.apache.http.message.basicnamevaluepair;
import org.apache.http.util.entityutils;
public class httpsclientutil {
	private static final string default_charset = "utf-8";
	public static string dopost(httpsclient httpsclient, string url, map<string, string> paramheader, 
	      map<string, string> parambody) throws exception {
		return dopost(httpsclient, url, paramheader, parambody, default_charset);
	}
	public static string dopost(httpsclient httpsclient, string url, map<string, string> paramheader, 
	      map<string, string> parambody, string charset) throws exception {
		string result = null;
		httppost httppost = new httppost(url);
		setheader(httppost, paramheader);
		setbody(httppost, parambody, charset);
		httpresponse response = httpsclient.execute(httppost);
		if (response != null) {
			httpentity resentity = response.getentity();
			if (resentity != null) {
				result = entityutils.tostring(resentity, charset);
			}
		}
		return result;
	}
	public static string doget(httpsclient httpsclient, string url, map<string, string> paramheader, 
	      map<string, string> parambody) throws exception {
		return doget(httpsclient, url, paramheader, parambody, default_charset);
	}
	public static string doget(httpsclient httpsclient, string url, map<string, string> paramheader, 
	      map<string, string> parambody, string charset) throws exception {
		string result = null;
		httpget httpget = new httpget(url);
		setheader(httpget, paramheader);
		httpresponse response = httpsclient.execute(httpget);
		if (response != null) {
			httpentity resentity = response.getentity();
			if (resentity != null) {
				result = entityutils.tostring(resentity, charset);
			}
		}
		return result;
	}
	private static void setheader(httprequestbase request, map<string, string> paramheader) {
		// 设置header 
		if (paramheader != null) {
			set<string> keyset = paramheader.keyset();
			for (string key : keyset) {
				request.addheader(key, paramheader.get(key));
			}
		}
	}
	private static void setbody(httppost httppost, map<string, string> parambody, string charset) throws exception {
		// 设置参数 
		if (parambody != null) {
			list<namevaluepair> list = new arraylist<namevaluepair>();
			set<string> keyset = parambody.keyset();
			for (string key : keyset) {
				list.add(new basicnamevaluepair(key, parambody.get(key)));
			}
			if (list.size() > 0) {
				urlencodedformentity entity = new urlencodedformentity(list, charset);
				httppost.setentity(entity);
			}
		}
	}
}

然后是测试类:

package com.darren.test.https.v42;
import java.util.hashmap;
import java.util.map;
public class httpsclienttest {
	public static void main(string[] args) throws exception {
		httpsclient httpsclient = null;
		httpsclient = new httpstrustclient().init();
		//httpsclient = new httpscertifiedclient().init(); 
		string url = "https://1.2.6.2:8011/xxx/api/gettoken";
		//string url = "https://1.2.6.2:8011/xxx/api/gethealth"; 
		map<string, string> paramheader = new hashmap<>();
		//paramheader.put("content-type", "application/json"); 
		paramheader.put("accept", "application/xml");
		map<string, string> parambody = new hashmap<>();
		parambody.put("client_id", "ankur.tandon.ap@xxx.com");
		parambody.put("client_secret", "p@ssword_1");
		string result = httpsclientutil.dopost(httpsclient, url, paramheader, parambody);
		//string result = httpsclientutil.doget(httpsclient, url, null, null); 
		system.out.println(result);
	}
}

返回信息:

<?xml version="1.0" encoding="utf-8"?> 
 <token>jkf8rl0sw+skkflj8rbki5hp1beqk8prcutzppbinqmykrmxy1kwcjmcft191zpp88vv1aghw8oynwjeys0axplugax89ejcownbikcc1uvfyesxhlktcjqyufivjevhreqxjphnclqywp+xse5od9x8vkfkk7inntmrzqk7ybtz/e3u7gswm/5cvahfl6o9req9cwpxavznohyvnxsohszdo+bxatxxa1xpedly/8h/uap4n4dlzdjj3b8t1xh+crriomopxf7c5wkhhtokeoexw+xopqkksx5ckwwjppugiifwf/paqwg+juosvt7qgdpv8pmwj9dwewjtdxgudg==</token> 

新版本4.5.3

需要认证

package com.darren.test.https.v45;
import java.io.file;
import java.io.fileinputstream;
import java.security.keystore;
import javax.net.ssl.sslcontext;
import org.apache.http.conn.ssl.sslconnectionsocketfactory;
import org.apache.http.conn.ssl.trustselfsignedstrategy;
import org.apache.http.ssl.sslcontexts;
public class httpscertifiedclient extends httpsclient {
	public httpscertifiedclient() {
	}
	@override 
	  public void preparecertificate() throws exception {
		// 获得密匙库 
		keystore truststore = keystore.getinstance(keystore.getdefaulttype());
		fileinputstream instream = new fileinputstream( 
		        new file("c:/users/zhda6001/downloads/software/xxx.keystore"));
		// fileinputstream instream = new fileinputstream(new file("c:/users/zhda6001/downloads/xxx.keystore")); 
		try {
			// 密匙库的密码 
			truststore.load(instream, "password".tochararray());
		}
		finally {
			instream.close();
		}
		sslcontext sslcontext = sslcontexts.custom().loadtrustmaterial(truststore, trustselfsignedstrategy.instance) 
		        .build();
		this.connectionsocketfactory = new sslconnectionsocketfactory(sslcontext);
	}
}

跳过认证

package com.darren.test.https.v45;
import java.security.cert.certificateexception;
import java.security.cert.x509certificate;
import javax.net.ssl.sslcontext;
import javax.net.ssl.trustmanager;
import javax.net.ssl.x509trustmanager;
import org.apache.http.conn.ssl.sslconnectionsocketfactory;
public class httpstrustclient extends httpsclient {
	public httpstrustclient() {
	}
	@override 
	  public void preparecertificate() throws exception {
		// 跳过证书验证 
		sslcontext ctx = sslcontext.getinstance("tls");
		x509trustmanager tm = new x509trustmanager() {
			@override 
			      public void checkclienttrusted(x509certificate[] chain, string authtype) throws certificateexception {
			}
			@override 
			      public void checkservertrusted(x509certificate[] chain, string authtype) throws certificateexception {
			}
			@override 
			      public x509certificate[] getacceptedissuers() {
				return null;
			}
		}
		;
		// 设置成已信任的证书 
		ctx.init(null, new trustmanager[] {
			tm
		}
		, null);
		this.connectionsocketfactory = new sslconnectionsocketfactory(ctx);
	}
}

总结

package com.darren.test.https.v45;
import org.apache.http.config.registry;
import org.apache.http.config.registrybuilder;
import org.apache.http.conn.socket.connectionsocketfactory;
import org.apache.http.conn.socket.plainconnectionsocketfactory;
import org.apache.http.impl.client.closeablehttpclient;
import org.apache.http.impl.client.httpclientbuilder;
import org.apache.http.impl.client.httpclients;
import org.apache.http.impl.conn.poolinghttpclientconnectionmanager;
public abstract class httpsclient extends httpclientbuilder {
	private closeablehttpclient client;
	protected connectionsocketfactory connectionsocketfactory;
	/** 
   * 初始化httpsclient 
   * 
   * @return 返回当前实例 
   * @throws exception 
   */
	public closeablehttpclient init() throws exception {
		this.preparecertificate();
		this.regist();
		return this.client;
	}
	/** 
   * 准备证书验证 
   * 
   * @throws exception 
   */
	public abstract void preparecertificate() throws exception;
	/** 
   * 注册协议和端口, 此方法也可以被子类重写 
   */
	protected void regist() {
		// 设置协议http和https对应的处理socket链接工厂的对象 
		registry<connectionsocketfactory> socketfactoryregistry = registrybuilder.<connectionsocketfactory>create() 
		        .register("http", plainconnectionsocketfactory.instance) 
		        .register("https", this.connectionsocketfactory) 
		        .build();
		poolinghttpclientconnectionmanager connmanager = new poolinghttpclientconnectionmanager(socketfactoryregistry);
		httpclients.custom().setconnectionmanager(connmanager);
		// 创建自定义的httpclient对象 
		this.client = httpclients.custom().setconnectionmanager(connmanager).build();
		// closeablehttpclient client = httpclients.createdefault();
	}
}

工具类:

package com.darren.test.https.v45;
import java.util.arraylist;
import java.util.list;
import java.util.map;
import java.util.set;
import org.apache.http.httpentity;
import org.apache.http.httpresponse;
import org.apache.http.namevaluepair;
import org.apache.http.client.httpclient;
import org.apache.http.client.entity.urlencodedformentity;
import org.apache.http.client.methods.httpget;
import org.apache.http.client.methods.httppost;
import org.apache.http.client.methods.httprequestbase;
import org.apache.http.message.basicnamevaluepair;
import org.apache.http.util.entityutils;
public class httpsclientutil {
	private static final string default_charset = "utf-8";
	public static string dopost(httpclient httpclient, string url, map<string, string> paramheader, 
	      map<string, string> parambody) throws exception {
		return dopost(httpclient, url, paramheader, parambody, default_charset);
	}
	public static string dopost(httpclient httpclient, string url, map<string, string> paramheader, 
	      map<string, string> parambody, string charset) throws exception {
		string result = null;
		httppost httppost = new httppost(url);
		setheader(httppost, paramheader);
		setbody(httppost, parambody, charset);
		httpresponse response = httpclient.execute(httppost);
		if (response != null) {
			httpentity resentity = response.getentity();
			if (resentity != null) {
				result = entityutils.tostring(resentity, charset);
			}
		}
		return result;
	}
	public static string doget(httpclient httpclient, string url, map<string, string> paramheader, 
	      map<string, string> parambody) throws exception {
		return doget(httpclient, url, paramheader, parambody, default_charset);
	}
	public static string doget(httpclient httpclient, string url, map<string, string> paramheader, 
	      map<string, string> parambody, string charset) throws exception {
		string result = null;
		httpget httpget = new httpget(url);
		setheader(httpget, paramheader);
		httpresponse response = httpclient.execute(httpget);
		if (response != null) {
			httpentity resentity = response.getentity();
			if (resentity != null) {
				result = entityutils.tostring(resentity, charset);
			}
		}
		return result;
	}
	private static void setheader(httprequestbase request, map<string, string> paramheader) {
		// 设置header 
		if (paramheader != null) {
			set<string> keyset = paramheader.keyset();
			for (string key : keyset) {
				request.addheader(key, paramheader.get(key));
			}
		}
	}
	private static void setbody(httppost httppost, map<string, string> parambody, string charset) throws exception {
		// 设置参数 
		if (parambody != null) {
			list<namevaluepair> list = new arraylist<namevaluepair>();
			set<string> keyset = parambody.keyset();
			for (string key : keyset) {
				list.add(new basicnamevaluepair(key, parambody.get(key)));
			}
			if (list.size() > 0) {
				urlencodedformentity entity = new urlencodedformentity(list, charset);
				httppost.setentity(entity);
			}
		}
	}
}

测试类:

package com.darren.test.https.v45;
import java.util.hashmap;
import java.util.map;
import org.apache.http.client.httpclient;
public class httpsclienttest {
	public static void main(string[] args) throws exception {
		httpclient httpclient = null;
		//httpclient = new httpstrustclient().init(); 
		httpclient = new httpscertifiedclient().init();
		string url = "https://1.2.6.2:8011/xxx/api/gettoken";
		//string url = "https://1.2.6.2:8011/xxx/api/gethealth"; 
		map<string, string> paramheader = new hashmap<>();
		paramheader.put("accept", "application/xml");
		map<string, string> parambody = new hashmap<>();
		parambody.put("client_id", "ankur.tandon.ap@xxx.com");
		parambody.put("client_secret", "p@ssword_1");
		string result = httpsclientutil.dopost(httpclient, url, paramheader, parambody);
		//string result = httpsclientutil.doget(httpsclient, url, null, null); 
		system.out.println(result);
	}
}

结果:

<?xml version="1.0" encoding="utf-8"?> 
 
<token>rxitf9//7nxwxjs2cjijyhltvzunvmzxxeqtgn0u07sc9ysjeibpqte3hcjulskoxpeuyguveyi9jv7/wiklrzxykc3ospatsm0kcbckphu0tb2cn/nfzv9fmlueowfbdyz+n0seii9k+0gp7920dfencn17wujvmc0u2jwvm5fajqkmilwodxz6a0dq+d7dqdjwvcwxbvj2ilhyib3pr805vppmi9atxrvako0oda006wejfofcgyg5p70wpj5rrbl85vfy9wcvkd1r7j6nvjhxgh2gnimhkjejormjdxw2gkiusiwseli/xpswao7/ctwnwtnctgk8px2zub0zfa==</token> 

二、httpurlconnection

@controller
public class restfulaction {
	@autowired
	  private userservice userservice;
	// 修改
	@requestmapping(value = "put/{param}", method = requestmethod.put)
	  public @responsebody string put(@pathvariable string param) {
		return "put:" + param;
	}
	// 新增
	@requestmapping(value = "post/{param}", method = requestmethod.post)
	  public @responsebody string post(@pathvariable string param,string id,string name) {
		system.out.println("id:"+id);
		system.out.println("name:"+name);
		return "post:" + param;
	}
	// 删除
	@requestmapping(value = "delete/{param}", method = requestmethod.delete)
	  public @responsebody string delete(@pathvariable string param) {
		return "delete:" + param;
	}
	// 查找
	@requestmapping(value = "get/{param}", method = requestmethod.get)
	  public @responsebody string get(@pathvariable string param) {
		return "get:" + param;
	}
	// httpurlconnection 方式调用restful接口
	// 调用接口
	@requestmapping(value = "dealcon/{param}")
	  public @responsebody string dealcon(@pathvariable string param) {
		try {
			string url = "http://localhost:8080/tao-manager-web/";
			url+=(param+"/xxx");
			url restserviceurl = new url(url);
			httpurlconnection httpconnection = (httpurlconnection) restserviceurl
			          .openconnection();
			//param 输入小写,转换成 get post delete put 
			httpconnection.setrequestmethod(param.touppercase());
			//      httpconnection.setrequestproperty("accept", "application/json");
			if("post".equals(param)){
				//打开输出开关
				httpconnection.setdooutput(true);
				//        httpconnection.setdoinput(true);
				//传递参数
				string input = "&id="+ urlencoder.encode("abc", "utf-8");
				input+="&name="+ urlencoder.encode("啊啊啊", "utf-8");
				outputstream outputstream = httpconnection.getoutputstream();
				outputstream.write(input.getbytes());
				outputstream.flush();
			}
			if (httpconnection.getresponsecode() != 200) {
				throw new runtimeexception(
				            "http get request failed with error code : "
				                + httpconnection.getresponsecode());
			}
			bufferedreader responsebuffer = new bufferedreader(
			          new inputstreamreader((httpconnection.getinputstream())));
			string output;
			system.out.println("output from server: \n");
			while ((output = responsebuffer.readline()) != null) {
				system.out.println(output);
			}
			httpconnection.disconnect();
		}
		catch (malformedurlexception e) {
			e.printstacktrace();
		}
		catch (ioexception e) {
			e.printstacktrace();
		}
		return "success";
	}
}

三、spring的resttemplate

springmvc.xml增加

<!-- 配置resttemplate -->
  <!--http client factory -->
  <bean id="httpclientfactory"
    class="org.springframework.http.client.simpleclienthttprequestfactory">
    <property name="connecttimeout" value="10000" />
    <property name="readtimeout" value="10000" />
  </bean>

  <!--resttemplate -->
  <bean id="resttemplate" class="org.springframework.web.client.resttemplate">
    <constructor-arg ref="httpclientfactory" />
  </bean>

controller

@controller
public class resttemplateaction {
	@autowired
	  private resttemplate template;
	@requestmapping("resttem")
	  public @responsebody user resttem(string method) {
		user user = null;
		//查找
		if ("get".equals(method)) {
			user = template.getforobject(
			          "http://localhost:8080/tao-manager-web/get/{id}",
			          user.class, "呜呜呜呜");
			//getforentity与getforobject的区别是可以获取返回值和状态、头等信息
			responseentity<user> re = template.
			          getforentity("http://localhost:8080/tao-manager-web/get/{id}",
			          user.class, "呜呜呜呜");
			system.out.println(re.getstatuscode());
			system.out.println(re.getbody().getusername());
			//新增
		} else if ("post".equals(method)) {
			httpheaders headers = new httpheaders();
			headers.add("x-auth-token", uuid.randomuuid().tostring());
			multivaluemap<string, string> postparameters = new linkedmultivaluemap<string, string>();
			postparameters.add("id", "啊啊啊");
			postparameters.add("name", "部版本");
			httpentity<multivaluemap<string, string>> requestentity = new httpentity<multivaluemap<string, string>>(
			          postparameters, headers);
			user = template.postforobject(
			          "http://localhost:8080/tao-manager-web/post/aaa", requestentity,
			          user.class);
			//删除
		} else if ("delete".equals(method)) {
			template.delete("http://localhost:8080/tao-manager-web/delete/{id}","aaa");
			//修改
		} else if ("put".equals(method)) {
			template.put("http://localhost:8080/tao-manager-web/put/{id}",null,"bbb");
		}
		return user;
	}
}

以上就是本文关于浅谈java调用restful api接口的方式的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他java相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!