被别人远程调用和自己远程调用别人接口的理解:
被别人调用接口:其实没有什么神秘的,就是我们写一个正常的方法提供一个访问路径。
调用别人的接口:本质时一个Request请求,实际要使用到javax.net.*包里的URL/ HttpURLConnection等相关的方法。
简单的一个接口实例:
我使用的框架是Spring mvc
被调用的接口方法:
1/创建Response的工具类
package com.gsww.sxzz.controller.service; import java.io.IOException; import javax.servlet.http.HttpServletResponse; /** * 接口json格式的工具帮助类 * @author GuoPC * @date 2017-05-31 * */ public class ResponseUtils { /** * 响应的返回json的方法 * @param response * @param text */ public static void renderJson(HttpServletResponse response,String text) { render(response,"text/json;charset=UTF-8",text); } /** * 设置响应相关的Header信息 * @param response * @param contentType * @param text */ public static void render(HttpServletResponse response,String contentType,String text){ //设置响应的头信息,具体请参考response对象 response.setContentType(contentType); response.setCharacterEncoding("utf-8"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); try{ response.getWriter().write(text); }catch(IOException e){ } } }
创建实际被调用的方法:
/** * 单点登陆接口 * @author GuoPC *@date 2017-05-031 */ @Controller @RequestMapping("/login") public class LoginService { /** * 单点登陆接口用于校验平台发送过来的校验码 * 请求方式为HTTP POST * 返回为json格式数据 * @param userCode 用户登录ID * @param userPwd 用户登录密码(32位MD5值) * @param appCode 应用编码(由平台端统一生成) */ @RequestMapping(value="/loginService",method = RequestMethod.POST) public void loginService(HttpServletRequest request,HttpServletResponse response){ /*使用request获取参数*/ String userCode=request.getParameter("userCode"); String userPwd=request.getParameter("userPwd"); String appCode=request.getParameter("appCode"); //创建map Map<String,String> map=new HashMap<String,String>(); JSONObject json=null; //判断参数是否传递 if(userCode!=null && userPwd!=null && appCode!=null){ if(userCode.equals("gyn") && userPwd.equals("gyn") && appCode.equals("1")){ //校验成功返回成功的参数信息 map.put("expires_in", "7200"); map.put("access_token", "接口成功"); //转换json json=JSONObject.fromObject(map); }else{ //校验失败返回成功的参数信息 map.put("expires_in", "7100"); map.put("access_token", "接口失败"); json=JSONObject.fromObject(map); } }else{ //校验失败返回成功的参数信息 map.put("expires_in", "7000"); map.put("access_token", "存在为null的参数"); json=JSONObject.fromObject(map); } //返回json数据 ResponseUtils.renderJson(response, json.toString()); } }
因为使用的是POST请求,在流量其地址栏输入会出现如下信息。请求方法不正确。
HTTP Status 405 - Request method 'GET' not supported
type Status report
message Request method 'GET' not supported
description The specified HTTP method is not allowed for the requested resource.
Apache Tomcat/8.5.9
我们继续写请求的实例:
/** * 单点登陆接口 * * @author GuoPC * @date 2017-05-031 */ public class LoginService { public static void main(String[] args) throws IOException { //创建访问路径 URL url=new URL("http://127.0.0.1:8080/sxzz/login/loginService?userCode=gyn&userPwd=gyn&appCode=1"); //打开访问路径 HttpURLConnection conn=(HttpURLConnection)url.openConnection(); //设置访问的方式如下 /*•GET 常用:在只是获取数据信息时使用 •POST 常用:在需要传递信息时使用 •HEAD •OPTIONS •PUT •DELETE •TRACE */ conn.setRequestMethod("POST"); //将此 URLConnection 的 doInput 字段的值设置为指定的值。 //URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输入,则将 DoInput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 true。 conn.setDoInput(true); //关键点:如果conn.setDoOutput(true)请求方法必须为POST //将此 URLConnection 的 doOutput 字段的值设置为指定的值。 //URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false。 conn.setDoOutput(true); conn.setInstanceFollowRedirects(true); /*conn.setRequestProperty("Accept", "application/json");*/ /*设置一般请求属性。如果已存在具有该关键字的属性,则用新值改写其值。 注:HTTP 要求所有能够合法拥有多个具有相同键的实例的请求属性,使用以逗号分隔的列表语法,这样可实现将多个属性添加到一个属性中。 参数: key - 用于识别请求的关键字(例如," accept")。 value - 与该键关联的值。*/ conn.setRequestProperty("content-type", "text/json"); conn.connect(); OutputStream os=conn.getOutputStream(); os.flush(); os.close(); //获取连接的输入流信息 InputStream is=conn.getInputStream(); InputStreamReader isr=new InputStreamReader(is); BufferedReader br=new BufferedReader(isr); String line=null; //获取得到输入流,并打印到控制台 while((line=br.readLine())!=null){ System.out.println(line); } br.close(); isr.close(); is.close(); } }
测试结果:
在补充下GET方式的请求:
/** * URL类封装的访问接口连接 * @return StringBuffer * @throws IOException */ public StringBuffer sendURLPost() throws IOException{ //创建访问路径 URL url=new URL("http://127.0.0.1:8080/sxzz/login/loginService?userCode=gyn&userPwd=gyn&appCode=1"); //打开访问路径 HttpURLConnection conn=(HttpURLConnection)url.openConnection(); //设置访问的方式如下 /*•GET 常用:在只是获取数据信息时使用 •POST 常用:在需要传递信息时使用 •HEAD •OPTIONS •PUT •DELETE •TRACE */ conn.setRequestMethod("POST"); //将此 URLConnection 的 doInput 字段的值设置为指定的值。 //URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输入,则将 DoInput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 true。 conn.setDoInput(true); //关键点:如果conn.setDoOutput(true)请求方法必须为POST //将此 URLConnection 的 doOutput 字段的值设置为指定的值。 //URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false。 conn.setDoOutput(true); conn.setInstanceFollowRedirects(true); conn.setRequestProperty("Accept", "text/json"); /*设置一般请求属性。如果已存在具有该关键字的属性,则用新值改写其值。 注:HTTP 要求所有能够合法拥有多个具有相同键的实例的请求属性,使用以逗号分隔的列表语法,这样可实现将多个属性添加到一个属性中。 参数: key - 用于识别请求的关键字(例如," accept")。 value - 与该键关联的值。*/ conn.setRequestProperty("content-type", "text/json"); conn.connect(); OutputStream os=conn.getOutputStream(); os.flush(); os.close(); //获取连接的输入流信息 InputStream is=conn.getInputStream(); InputStreamReader isr=new InputStreamReader(is); BufferedReader br=new BufferedReader(isr); String line=null; //创建返回对象,必须使用new创建对象初始化 StringBuffer sb = new StringBuffer(); //获取得到输入流,并打印到控制台 while((line=br.readLine())!=null){ //获取返回的值 sb.append(line); } br.close(); isr.close(); is.close(); return sb; } /** * URL类封装的访问接口连接 * @return StringBuffer * @throws IOException */ public StringBuffer sendURLGet() throws IOException{ //创建访问路径 URL url=new URL(this.http+"://"+this.host+":"+this.port+"/"+this.url+"?"+this.params); //打开访问路径 HttpURLConnection conn=(HttpURLConnection)url.openConnection(); //设置访问的方式如下 /*•GET 常用:在只是获取数据信息时使用 •POST 常用:在需要传递信息时使用 •HEAD •OPTIONS •PUT •DELETE •TRACE */ conn.setRequestMethod("GET"); //将此 URLConnection 的 doInput 字段的值设置为指定的值。 //URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输入,则将 DoInput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 true。 conn.setDoInput(true); //关键点:如果conn.setDoOutput(true)请求方法必须为POST //将此 URLConnection 的 doOutput 字段的值设置为指定的值。 //URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false。 /*conn.setDoOutput(true);*/ conn.setInstanceFollowRedirects(true); conn.setRequestProperty("Accept", "text/json"); /*设置一般请求属性。如果已存在具有该关键字的属性,则用新值改写其值。 注:HTTP 要求所有能够合法拥有多个具有相同键的实例的请求属性,使用以逗号分隔的列表语法,这样可实现将多个属性添加到一个属性中。 参数: key - 用于识别请求的关键字(例如," accept")。 value - 与该键关联的值。*/ conn.setRequestProperty("content-type", "text/json"); conn.connect(); /*OutputStream os=conn.getOutputStream(); os.flush(); os.close();*/ //获取连接的输入流信息 InputStream is=conn.getInputStream(); InputStreamReader isr=new InputStreamReader(is); BufferedReader br=new BufferedReader(isr); String line=null; //创建返回对象,必须使用new创建对象初始化 StringBuffer sb = new StringBuffer(); //获取得到输入流,并打印到控制台 while((line=br.readLine())!=null){ //获取返回的值 sb.append(line); } br.close(); isr.close(); is.close(); return sb; }
使用get方式请求是不可设置下面选项为true:
conn.setDoOutput(true);
同样下面的对象也不可以使用
OutputStream os=conn.getOutputStream();
os.flush();
os.close();
setDoOutput是设置请求的输出流为true。理解下get方式请求就明白了,get只是获取连接的数据信息,不需要像对方输出数据信息。只需要获取请求方的输入数据就可以了。
Get方式的输出结果:
总结:
此列接口的实际意义就是:Request和Response连个对象的使用,这部分要是学的够精通,作起来还是很好理解的,在基础一些就是使用到了Socket套接字的内容。URL和HttpURLConnection可能就是封装了Socket。
这只是个人理解,如果有大牛看出错误,还请多多指点。