httpclient的理解(代码理解)
一,httpclient的理解
httpcliet就是模仿浏览器在服务器内部从一个项目调用另一个项目的技术。比如说调用接口等。
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
二,httpclient的使用方法
1.1,jar包
需要把httpclient的jar包添加到工程中。只需要在工程中添加httpclient的依赖。
1.2,使用方法
1.2.1,get无参请求
@Test public void doGet() throws Exception { //创建一个httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); //创建一个GET对象 HttpGet get = new HttpGet("http://www.sogou.com"); //执行请求 CloseableHttpResponse response = httpClient.execute(get); //取响应的结果 int statusCode = response.getStatusLine().getStatusCode(); System.out.println(statusCode); HttpEntity entity = response.getEntity(); String string = EntityUtils.toString(entity, "utf-8"); System.out.println(string); //关闭httpclient response.close(); httpClient.close(); }
1.2.2,get带参请求
@Test public void doGetWithParam() throws Exception{ //创建一个httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); //创建一个uri对象 URIBuilder uriBuilder = new URIBuilder("http://www.sogou.com/web"); uriBuilder.addParameter("query", "花千骨"); HttpGet get = new HttpGet(uriBuilder.build()); //执行请求 CloseableHttpResponse response = httpClient.execute(get); //取响应的结果 int statusCode = response.getStatusLine().getStatusCode(); System.out.println(statusCode); HttpEntity entity = response.getEntity(); String string = EntityUtils.toString(entity, "utf-8"); System.out.println(string); //关闭httpclient response.close(); httpClient.close(); }
1.2.3,post无参请求
@Test public void doPost() throws Exception { CloseableHttpClient httpClient = HttpClients.createDefault(); //创建一个post对象 HttpPost post = new HttpPost("http://localhost:8082/httpclient/post.action"); //执行post请求 CloseableHttpResponse response = httpClient.execute(post); String string = EntityUtils.toString(response.getEntity()); System.out.println(string); response.close(); httpClient.close(); }
1.2.4,post带参请求
@Test public void doPostWithParam() throws Exception{ CloseableHttpClient httpClient = HttpClients.createDefault(); //创建一个post对象 HttpPost post = new HttpPost("http://localhost:8082/httpclient/post.action"); //创建一个Entity。模拟一个表单 List<NameValuePair> kvList = new ArrayList<>(); kvList.add(new BasicNameValuePair("username", "张三")); kvList.add(new BasicNameValuePair("password", "123")); //包装成一个Entity对象 StringEntity entity = new UrlEncodedFormEntity(kvList, "utf-8"); //设置请求的内容 post.setEntity(entity); //执行post请求 CloseableHttpResponse response = httpClient.execute(post); String string = EntityUtils.toString(response.getEntity()); System.out.println(string); response.close(); httpClient.close(); }
三,httpclient的案例讲解
3.1,httpclient的工具类httpclientutil
package com.http; import java.io.ByteArrayOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.UnsupportedEncodingException; import java.net.SocketException; import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.NoHttpResponseException; import org.apache.http.ParseException; import org.apache.http.ProtocolException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig.Builder; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.HttpHostConnectException; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.cookie.Cookie; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultRedirectStrategy; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HttpContext; import org.apache.http.util.ByteArrayBuffer; import org.apache.http.util.EntityUtils; /** * HttpClient工具封装类,Post,Get请求,代理请求 * 作者:<br> * 版本:1.0<br> * 创建日期:下午9:21:00<br> */ public class HttpClientUtil { /***连接超时时间*/ private Integer connectTimeout =60*1000; private Integer socketTimeout =180*1000; private CloseableHttpClient httpClient = null; private CookieStore cookieStore = new BasicCookieStore(); /** 代理请求 */ public HttpClientUtil(String proxyHost, int proxyPort) { this(proxyHost, proxyPort, -1, -1, 0, 0, true); } /** 默认*/ public HttpClientUtil() { this(null, 0, -1, -1, 0, 0, true); } /** 进行请求无代理设置连接时间 */ public HttpClientUtil(int socketTimeout, int connectTimeout) { this(null, 0, socketTimeout, connectTimeout, 0, 0, true); } /** * * @param proxyHost 代理主机地址 * @param proxyPort 代理端口 * @param socketTimeout * @param connectTimeout * @param route * @param maxTotal * @param followRedirect */ public HttpClientUtil(String proxyHost, int proxyPort, int socketTimeout, int connectTimeout, int route, int maxTotal, boolean followRedirect){ Builder builder = RequestConfig.custom(); builder.setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY); if (followRedirect) { builder.setCircularRedirectsAllowed(true); builder.setMaxRedirects(100); } if (StringUtils.isNotBlank(proxyHost) && proxyPort > 0) { builder.setProxy(new HttpHost(proxyHost, proxyPort)); } //设置连接时间 if (socketTimeout != -1) { this.socketTimeout = socketTimeout; } builder.setSocketTimeout(this.socketTimeout); if (connectTimeout != -1) { this.connectTimeout = connectTimeout; } builder.setConnectTimeout(this.connectTimeout); builder.setConnectionRequestTimeout(this.connectTimeout); RequestConfig requestConfig = builder.build(); init(requestConfig, route, maxTotal); } private void init(RequestConfig requestConfig, int route, int maxTotal) { X509TrustManager x509mgr = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] xcs, String string) { } @Override public void checkServerTrusted(X509Certificate[] xcs, String string) { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }; SSLContext sslContext = null; try { sslContext = SSLContext.getInstance("TLS"); } catch (NoSuchAlgorithmException e1) { e1.printStackTrace(); } try { sslContext.init(null, new TrustManager[] { x509mgr }, null); } catch (KeyManagementException e) { e.printStackTrace(); } SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { @Override public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { if (executionCount >= 5) {// 如果已经重试了5次,就放弃 return false; } if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试 return true; } if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常 return false; } if (exception instanceof InterruptedIOException) {// 超时 return false; } if (exception instanceof UnknownHostException) {// 目标服务器不可达 return false; } if (exception instanceof ConnectTimeoutException) {// 连接被拒绝 return false; } if (exception instanceof SSLException) {// ssl握手异常 return false; } // 2016-03-09针对broken pipe的问题做处理 if (exception instanceof SocketException) { return true; } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); // 如果请求是幂等的,就再次尝试 if (!(request instanceof HttpEntityEnclosingRequest)) { return true; } return false; } }; DefaultRedirectStrategy redirectStrategy = new DefaultRedirectStrategy() { public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) { boolean isRedirect = false; try { isRedirect = super.isRedirected(request, response, context); } catch (ProtocolException e) { e.printStackTrace(); } if (!isRedirect) { int responseCode = response.getStatusLine().getStatusCode(); if (responseCode == 301 || responseCode == 302) { return true; } } return isRedirect; } @Override protected URI createLocationURI(String location) throws ProtocolException { location = location.replace("|", "%7C"); return super.createLocationURI(location); } }; HttpClientBuilder httpClientBuilder = HttpClients.custom(); httpClientBuilder.setDefaultRequestConfig(requestConfig); if (route > 0 && maxTotal > 0) { PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setDefaultMaxPerRoute(route); connManager.setMaxTotal(maxTotal); httpClientBuilder.setConnectionManager(connManager); } httpClientBuilder.setSSLSocketFactory(sslsf); httpClientBuilder.setDefaultCookieStore(cookieStore); httpClientBuilder.setRedirectStrategy(redirectStrategy); httpClientBuilder.setRetryHandler(httpRequestRetryHandler); httpClient = httpClientBuilder.build(); } public Response sendRequest(Request request) throws Exception { // request.setHeader("Accept", // "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); // request.setHeader("Accept-Encoding", "gzip, deflate"); if (request.getHeader("User-Agent") == null) { request.setHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Firefox/24.0"); } request.setHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3"); request.setHeader("Connection", "keep-alive"); // logger.debug("发送请求:" + request); String method = request.getProperty("method").toLowerCase(); String url = request.getProperty("url"); Map<String, String> headers = request.getHeaders(); Map<String, String> params = request.getParams(); List<NameValuePair> formParams = new ArrayList<NameValuePair>(); if (params != null && params.size() != 0) { formParams = new ArrayList<NameValuePair>(); for (Entry<String, String> entry : params.entrySet()) { formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } } Response response = null; if ("post".equals(method)) { byte[] postData = request.getPostData(); if (postData != null) { response = post(url, postData, headers); } else { response = post(url, formParams, headers); } } else if ("get".equals(method)) { response = get(url, formParams, headers); } return response; } /** * Get请求 * * @param url * @param params * @return */ public Response get(String url, List<NameValuePair> params, Map<String, String> headers) { Response response = new Response(); try { // Get请求 HttpGet httpGet = new HttpGet(url); String encoding = "utf-8"; // 设置头 if (headers != null && headers.size() != 0) { for (Entry<String, String> entry : headers.entrySet()) { httpGet.setHeader(entry.getKey(), entry.getValue()); } String contentType = headers.get("Content-Type"); if (StringUtils.isNotBlank(contentType)) { if (matcher(contentType, "(charset)\\s?=\\s?(gbk)")) { encoding = "gbk"; } else if (matcher(contentType, "(charset)\\s?=\\s?(gb2312)")) { encoding = "gb2312"; } } } // 设置参数,如果url上已经有了问号,就不附加参数 if (params != null && params.size() > 0) { if (httpGet.getURI().toString().indexOf("?") == -1) { String str = EntityUtils.toString(new UrlEncodedFormEntity(params, encoding)); httpGet.setURI(new URI(httpGet.getURI().toString() + "?" + str)); } else { String str = EntityUtils.toString(new UrlEncodedFormEntity(params, encoding)); httpGet.setURI(new URI(httpGet.getURI().toString() + "&" + str)); } } // 发送请求 CloseableHttpResponse httpResponse = httpClient.execute(httpGet); try { int statusCode = httpResponse.getStatusLine().getStatusCode(); response.setStatusCode(statusCode); ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); // 获取返回数据 HttpEntity entity = httpResponse.getEntity(); Header[] responseHeaders = httpResponse.getAllHeaders(); for (Header header : responseHeaders) { response.setHeader(header.getName(), header.getValue()); } Header header = entity.getContentEncoding(); if (header != null && header.getValue().toLowerCase().equals("gzip")) { byte[] bytes = IOUtils.toByteArray(new GZIPInputStream(entity.getContent())); response.setContent(bytes); } else { byte[] bytes = getData(entity); response.setContent(bytes); } return response; } finally { httpResponse.close(); } } catch (ConnectTimeoutException e) { } catch (HttpHostConnectException e) { } catch (ParseException e) { } catch (UnsupportedEncodingException e) { } catch (IOException e) { } catch (URISyntaxException e) { } catch (Exception e) { } return null; } /** * // Post请求 * * @param url * @param params * @return */ public Response post(String url, byte[] data, Map<String, String> headers) { Response response = new Response(); try { // Post请求 HttpPost httpPost = new HttpPost(url); // 设置头 if (headers != null && headers.size() != 0) { for (Entry<String, String> entry : headers.entrySet()) { httpPost.setHeader(entry.getKey(), entry.getValue()); } } // 设置参数 httpPost.setEntity(new ByteArrayEntity(data)); // 发送请求 CloseableHttpResponse httpResponse = httpClient.execute(httpPost); try { int statusCode = httpResponse.getStatusLine().getStatusCode(); response.setStatusCode(statusCode); // 获取返回数据 HttpEntity entity = httpResponse.getEntity(); Header header = entity.getContentEncoding(); if (header != null && header.getValue().toLowerCase().equals("gzip")) { byte[] bytes = IOUtils.toByteArray(new GZIPInputStream(entity.getContent())); response.setContent(bytes); } else { byte[] bytes = EntityUtils.toByteArray(entity); response.setContent(bytes); } return response; } finally { httpResponse.close(); } } catch (ConnectTimeoutException e) { } catch (HttpHostConnectException e) { } catch (UnsupportedEncodingException e) { } catch (ClientProtocolException e) { } catch (ParseException e) { } catch (IOException e) { } catch (Exception e) { } return null; } private byte[] getData(HttpEntity entity) throws IOException { if (entity == null) { throw new IllegalArgumentException("HTTP entity may not be null"); } InputStream inputStream = entity.getContent(); if (inputStream == null) { return null; } try { if (entity.getContentLength() > Integer.MAX_VALUE) { throw new IllegalArgumentException("HTTP entity too large to be buffered in memory"); } int i = (int) entity.getContentLength(); if (i < 0) { i = 4096; } ByteArrayBuffer buffer = new ByteArrayBuffer(i); byte[] tmp = new byte[1024]; int l = -1; try { while ((l = inputStream.read(tmp)) != -1) { buffer.append(tmp, 0, l); } } catch (EOFException e) { buffer.clear(); // 针对于以没有结束符的做fix处理,减小缓存,并进行异常处理,忽略最后不能获取的数据 tmp = new byte[32]; try { while ((l = inputStream.read(tmp)) != 1) { buffer.append(tmp, 0, l); } } catch (EOFException e2) { } } // TODO 查明具体没有返回的原因 byte[] byteArray = buffer.toByteArray(); if (byteArray == null || byteArray.length == 0) { return buffer.buffer(); } return byteArray; } finally { inputStream.close(); } } /** * // Post请求 * * @param url * @param params * @return */ public Response post(String url, List<NameValuePair> params, Map<String, String> headers) { Response response = new Response(); try { // Post请求 HttpPost httpPost = new HttpPost(url); String encoding = "utf-8"; // 设置头 if (headers != null && headers.size() != 0) { for (Entry<String, String> entry : headers.entrySet()) { httpPost.setHeader(entry.getKey(), entry.getValue()); } String contentType = headers.get("Content-Type"); if (StringUtils.isNotBlank(contentType)) { if (matcher(contentType, "(charset)\\s?=\\s?(gbk)")) { encoding = "gbk"; } else if (matcher(contentType, "(charset)\\s?=\\s?(gb2312)")) { encoding = "gb2312"; } } } // 设置参数 if (params != null && params.size() > 0) { httpPost.setEntity(new UrlEncodedFormEntity(params, encoding)); } // 发送请求 CloseableHttpResponse httpResponse = httpClient.execute(httpPost); try { int statusCode = httpResponse.getStatusLine().getStatusCode(); response.setStatusCode(statusCode); // 获取返回数据 HttpEntity entity = httpResponse.getEntity(); Header header = entity.getContentEncoding(); if (header != null && header.getValue().toLowerCase().equals("gzip")) { byte[] data = IOUtils.toByteArray(new GZIPInputStream(entity.getContent())); response.setContent(data); } else { byte[] data = getData(entity); response.setContent(data); } return response; } finally { httpResponse.close(); } } catch (ConnectTimeoutException e) { } catch (HttpHostConnectException e) { } catch (UnsupportedEncodingException e) { } catch (ClientProtocolException e) { } catch (ParseException e) { } catch (IOException e) { } catch (Exception e) { } return null; } /** * 获取Response内容字符集 * * @param response * @return */ public String getContentCharset(HttpResponse response) { String charset = "ISO_8859-1"; Header header = response.getEntity().getContentType(); if (header != null) { String s = header.getValue(); if (matcher(s, "(charset)\\s?=\\s?(utf-?8)")) { charset = "utf-8"; } else if (matcher(s, "(charset)\\s?=\\s?(gbk)")) { charset = "gbk"; } else if (matcher(s, "(charset)\\s?=\\s?(gb2312)")) { charset = "gb2312"; } } Header encoding = response.getEntity().getContentEncoding(); return charset; } /** * 正则匹配 * * @param s * @param pattern * @return */ private boolean matcher(String s, String pattern) { Pattern p = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE + Pattern.UNICODE_CASE); Matcher matcher = p.matcher(s); if (matcher.find()) { return true; } else { return false; } } public Integer getConnectTimeout() { return connectTimeout; } public void setConnectTimeout(Integer connectTimeout) { this.connectTimeout = connectTimeout; } public Integer getSocketTimeout() { return socketTimeout; } public void setSocketTimeout(Integer socketTimeout) { this.socketTimeout = socketTimeout; } public CloseableHttpClient getHttpClient() { return httpClient; } public void setHttpClient(CloseableHttpClient httpClient) { this.httpClient = httpClient; } public CookieStore getCookieStore() { return cookieStore; } public void setCookieStore(CookieStore cookieStore) { for(Cookie cookie:cookieStore.getCookies()){ this.cookieStore.addCookie(cookie); } } }
3.2, resource的property的文件
REST_BASE_URL=http://192.168.25.136:8080/rest REST_INDEX_AD_URL=/content/list/89
3.3,类中的调用
public class ContentServiceImpl implements ContentService { @Value("${REST_BASE_URL}") private String REST_BASE_URL; @Value("${REST_INDEX_AD_URL}") private String REST_INDEX_AD_URL; @Override public String getContentList() { //调用服务层的服务 String result = HttpClientUtil.doGet(REST_BASE_URL + REST_INDEX_AD_URL); //把字符串转换成TaotaoResult try { TaotaoResult taotaoResult = TaotaoResult.formatToList(result, TbContent.class); //取内容列表 List<TbContent> list = (List<TbContent>) taotaoResult.getData(); List<Map> resultList = new ArrayList<>(); //创建一个jsp页码要求的pojo列表 for (TbContent tbContent : list) { Map map = new HashMap<>(); map.put("src", tbContent.getPic()); map.put("height", 240); map.put("width", 670); map.put("srcB", tbContent.getPic2()); map.put("widthB", 550); map.put("heightB", 240); map.put("href", tbContent.getUrl()); map.put("alt", tbContent.getSubTitle()); resultList.add(map); } return JsonUtils.objectToJson(resultList); } catch (Exception e) { e.printStackTrace(); } return null; } }
httpclient的理解(代码理解)的更多相关文章
- linux io的cfq代码理解
内核版本: 3.10内核. CFQ,即Completely Fair Queueing绝对公平调度器,原理是基于时间片的角度去保证公平,其实如果一台设备既有单队列,又有多队列,既有快速的NVME,又有 ...
- 通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
秦鼎涛 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验一 通过汇编一个简单的C程序,分析汇编代码 ...
- 『TensorFlow』通过代码理解gan网络_中
『cs231n』通过代码理解gan网络&tensorflow共享变量机制_上 上篇是一个尝试生成minist手写体数据的简单GAN网络,之前有介绍过,图片维度是28*28*1,生成器的上采样使 ...
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
实验一:通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处 <Linux内核分析>MOOC课程http: ...
- httpclient的主要业务代码逻辑(图解)
一,主要代码逻辑(图解) 二,两个案例的对比(图解) 三,详细案例 3.1,博文一 httppost的用法(NameValuePair(简单名称值对节点类型)核心对象) 3.2,博文二 httpcli ...
- 理解Javascript_01_理解内存分配
理解Javascript_01_理解内存分配 转载自:http://www.cnblogs.com/fool/archive/2010/10/07/1845226.html 在正式开始之前,我想先 ...
- 【转】对于HttpClient和HtmlUnit的理解
原文地址:http://www.haohaoblog.com/?p=1327&utm_source=tuicool 做Java编程的人其实,很多不懂SEO,也不知道如何让百度收录等等,当然,对 ...
- JAVA装饰者模式(从现实生活角度理解代码原理)
装饰者模式可以动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比生成子类更为灵活. 该模式的适用环境为: (1)在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职 ...
- JAVA适配器模式(从现实生活角度理解代码原理)
说道JAVA中的适配器模式,不得不引用该设计模式的固定表述"适配器模式(Adapter ):将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类 ...
随机推荐
- BZOJ 1969: [Ahoi2005]LANE 航线规划 [树链剖分 时间倒流]
题意: 一张图,删除边,求两点之间的割边数量.保证任意时刻图连通 任求一棵生成树,只有树边可能是割边 时间倒流,加入一条边,就是两点路径上的边都不可能是割边,区间覆盖... 然后本题需要把边哈希一下, ...
- 网络编程之socketserver
网络编程之socketserver """ socketserver.py 中的5个基础类 +------------+ | BaseServer | +-------- ...
- [记]Debian alias 设置, 不设置貌似有点不方便习惯
备忘录,记录下. 不知道 当前有那些 alias 的话 直接输入 alias ,回车就可以看到 alias 列表. 终端输入: vim ~/bash_aliases 然后输入: # some more ...
- ubuntu:通过封装验证码类库一步步安装php的gd扩展
我相信很多人的lamp环境都是直接复制一堆参数安装进去的,这里有可能成功,也有可能失败,如果是新手,估计要碰到各种错误,就算安装成功,也未必知道那些参数是干嘛的,反正装进去能用就行. 我当初开始的时候 ...
- 【数据结构】——搜索二叉树的插入,查找和删除(递归&非递归)
一.搜索二叉树的插入,查找,删除 简单说说搜索二叉树概念: 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右 ...
- Mock摆脱后端拖拉(借鉴官网)(一)
mock是一个模拟数据生成器,旨在帮助前端独立于后端进行开发,帮助编写单元测试.mock有如下功能 根据数据模板生成模板数据 模拟ajax请求,生成请求数据 基于html模板生成模拟数据 下载安装 n ...
- 让互联网更快:新一代QUIC协议在腾讯的技术实践分享
本文来自腾讯资深研发工程师罗成在InfoQ的技术分享. 1.前言 如果:你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度,特别是弱网络的时候能够提升 20% 以上的访问速度. 如 ...
- TP3.2 中使用 PHPMailer 发送邮件
第一步.添加PHPMailer类库 http://pan.baidu.com/s/1o7Zc7V0 第二步.添加发送邮件函数 在common目录中的公共函数文件加入函数 <?php /***** ...
- Django里使用open函数
Django里使用open函数 前言 在Django里使用open函数打开一个文件的时候,常常会遇到路径错误的问题.我在Django APP里写了一个爬虫用于为网站提供数据,但是需要打开文件,也就是在 ...
- Android开发之组件
Android应用程序由组件组成,组件是可以解决被调用的基本功能模块.Android系统利用组件实现程序内部或程序间的模块调用,以解决代码复用问题,这是Android系统非常重要的特性.在程序设计时, ...