java使用httpClient解决外部url请求访问

一,在一般项目中,涉及第三方接口调用,一般是采用webService或者httpClient。

基于项目要求,我这边做一个httpClient请求文件上传,是先从数据库表中读取二进制流,然后转存到本地服务器上面,最后调用httpClient上传至文件服务器上面,具体代码如下

package com.hxzq.s0026.my168.service.impl;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.hxzq.commons.db.mapper.SQLQueryMapResult;
import com.hxzq.commons.ioc.HxSpringUtil;
import com.hxzq.s0026.my168.constants.Constants;
import com.hxzq.s0026.my168.dao.My168PhotoInitMapper;
import com.hxzq.s0026.my168.service.My168PhotoInitService;
import com.thinkive.base.config.Configuration;
import com.thinkive.base.exception.CommonException;
import com.thinkive.base.jdbc.DataRow;
import com.thinkive.base.util.JsonHelper;
import com.thinkive.base.util.StringHelper;
import com.thinkive.server.exception.BusinessException;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

@Service
public class My168PhotoInitServiceImpl implements My168PhotoInitService {
	static Logger logger=Logger.getLogger(My168PhotoInitServiceImpl.class);
	 private static RequestConfig requestConfig;
	 private static String photoUrl;
//	 private static List<String> localPaths;//用于删除本地文件
	    static
	    {
	        //request配置超时时间
	        requestConfig = RequestConfig.custom()  
	                .setConnectTimeout(60000)//设置连接超时时间,单位毫秒
	                .setConnectionRequestTimeout(1000)//设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的
	                .setSocketTimeout(60000)//请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用
	                .build();
	        photoUrl=Configuration.getString("my168.photo_url");//获取文件上传文件服务器
	    }
	@Override
	public void initPhoto() {
		// TODO Auto-generated method stub
		My168PhotoInitMapper my168PhotoInitMapper = HxSpringUtil.getBean(Constants.sysNo, My168PhotoInitMapper.class);
		SQLQueryMapResult rs = my168PhotoInitMapper.queryPhoto();
		List<DataRow> list = rs.getDataList();
		if (list.size() == 0) {
			throw new CommonException(1, "头像不存在");
		}
		BASE64Encoder encoder = null;
		String fileName = null;
		String absolutePath = null;
		// String
		// location=request.getSession().getServletContext().getRealPath("/upload");
		// 循环读取对应的图像二进制流,转换成图片上传进文件服务器
		for (int i = 0; i < list.size(); i++) {
			try {
				byte[] bytes = (byte[]) list.get(i).get("avatar");
				if (bytes==null) {
					continue;
				}
				String userid = (String) list.get(i).get("userid");
				fileName = userid + ".jpg";
				encoder = new BASE64Encoder();
				String avatarStr = encoder.encode(bytes);
				BASE64Decoder decoder = new BASE64Decoder();
				byte[] bytes1 = decoder.decodeBuffer(avatarStr);
				InputStream bais = new ByteArrayInputStream(bytes1);
				// 使用imageIo文件流出现类型异常,推荐使用二进制流
				// JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new
				// InputStream(bais));
				// BufferedImage sourceImg = decoder.decodeAsBufferedImage();
				// BufferedImage bi1 = ImageIO.read(bais);
				// File f1 = new File(fileName);
				// ImageIO.write(bi1, "jpg", f1);
				File file = new File(fileName);// 可以是任何图片格式.jpg,.png等
				FileOutputStream fos = new FileOutputStream(file);
				byte[] b = new byte[1024];
				int nRead = 0;
				while ((nRead = bais.read(b)) != -1) {
					fos.write(b, 0, nRead);
				}
				fos.flush();
				fos.close();
				bais.close();
				absolutePath = file.getAbsolutePath();// 获取真实路径
 				DataRow data = (DataRow) this.updateFile(absolutePath);
				absolutePath = (String) data.get("file_path");
				// 同步更新对应的数据库
				my168PhotoInitMapper.updatePhotoAddrs(absolutePath, userid);
			} catch (IOException e) {
				throw new CommonException(2, "处理图片失败");
			}
		}
 
	}
	/**
	 * 
	 * @说明: 打开一个httpClient连接,然后进行单个文件上传,后续可以考虑提供批量上传
	 * @方法名称: updateFile
	 * @参数 @param filePath 本地服务器上面的真实路径
	 * @参数 @return
	 * @返回类型 Object    
	 
	 * @修改时间: 2018年10月23日 下午1:57:21
	 */
	@SuppressWarnings("all")
	private Object updateFile(String filePath) {
		if (com.thinkive.base.util.StringUtil.isEmpty(filePath)) {
			throw new BusinessException(1, "文件上传失败,附件为空!");
		}
		CloseableHttpClient httpClient = null;
		HttpPost httpPost = null;
		try {
			httpClient = HttpClients.createDefault();
			httpPost = new HttpPost(photoUrl);
			httpPost.setConfig(requestConfig);//设置访问参数
			Map<String,Object> dataMap = new HashMap<String,Object>();
			dataMap.put("business_code", "png_upload");
			//请求参数
			String data=new Gson().toJson(dataMap);
			//转成base64字符串
			data= new BASE64Encoder().encode(data.getBytes());
			//时间戳
			String timestamp=String.valueOf(System.currentTimeMillis());
			 
			//签名结果值
			String sign= encryptToMD5(signStr);
			//设置访问入参
			MultipartEntityBuilder builder = MultipartEntityBuilder.create();
			builder.setCharset(Charset.forName(HTTP.UTF_8));// 设置请求编码格式
			builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);// 设置浏览器兼容模式
			builder.addBinaryBody("upfile", new File(filePath));//设置上传路径
 			builder.addTextBody("timestamp",timestamp);
            builder.addTextBody("data", data);
            builder.addTextBody("merchant_id", merchant_id);
            builder.addTextBody("sign", sign);
			HttpEntity entity = builder.build();
			httpPost.setEntity(entity);
			//执行http访问
			HttpResponse response = httpClient.execute(httpPost);
			int statusCode = response.getStatusLine().getStatusCode();//获取访问状态吗
			if (statusCode == HttpStatus.SC_OK) {
				HttpEntity resEntity = response.getEntity();
				String jsonStr = EntityUtils.toString(resEntity);// httpClient自带的工具类读取返回数据
				EntityUtils.consume(resEntity);
				if (StringHelper.isEmpty(jsonStr)) {
					throw new BusinessException(1, "文件上传异常,响应结果为空!");
				}
				// 解析响应结果
				DataRow dataRow = JsonHelper.getObjectByJSON(jsonStr, DataRow.class);
				if (dataRow.getInt("error_no") != 0) {
					throw new BusinessException(dataRow.getInt("error_no"), dataRow.getString("error_info"));
				}
				//获取数据然后封装给对应的datarow
				List<Map> list = (List<Map>) dataRow.get("results");
				List<DataRow> newList = null;
				if (null != list) {
					newList = new ArrayList<DataRow>();
					for (Map map : list) {
						DataRow row = new DataRow();
						row.putAll(map);
						newList.add(row);
					}
					logger.info("服务端返回地址:"+newList.get(0));
					return newList.get(0);
				}
			} else {
				throw new BusinessException(1, "文件上传失败!状态码:" + statusCode);
			}
		} catch (Exception e) {
			// TODO: handle exception
			 throw new BusinessException(1,"文件下载异常!");
		} finally {
			if (null != httpPost) {
				try {
					httpPost.clone();
				} catch (CloneNotSupportedException e) {
				}
			}
			if (null != httpClient) {
				try {
					httpClient.close();
				} catch (IOException e) {
				}
			}
		}
		return null;
	}
	//设置模板加密,加密为MD5
	 public String encryptToMD5(String info)
	    {
	        byte[] digesta = null;
	        try
	        {
	            MessageDigest mDigest = MessageDigest.getInstance("MD5");

	            mDigest.update(info.getBytes());

	            digesta = mDigest.digest();
	        }
	        catch (NoSuchAlgorithmException e)
	        {
	            e.printStackTrace();
	        }
	        return bytesToHex(digesta);
	    }
	 //格式转换
	 private String bytesToHex(byte[] bytes)
	    {
	        String hex = "";

	        String temp = "";
	        for (int i = 0; i < bytes.length; i++)
	        {
	            temp = Integer.toHexString(bytes[i] & 0xFF);
	            if (temp.length() == 1) {
	                hex = hex + "0" + temp;
	            } else {
	                hex = hex + temp;
	            }
	        }
	        return hex;
	    }
	 //上传成功后删除本地图片,暂时未开发
	 private void deleteLocalPath(List<String> paths){
		 File file=null;
		 for (String path : paths) {
			file=new File(path);
			if (file.isDirectory()) {
				throw new BusinessException(-1, "不允许删除文件夹");
			}else{
				file.delete();
			}
		}
	 }
}

ps:这边有一部分代码调用是调用本地库,传入的url是读取的配置文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Java中,你可以使用以下几种方式来请求外部接口: 1. 使用 `java.net` 包中的类,如 `URL` 和 `HttpURLConnection`。你可以使用这些类来发送 HTTP 请求并获取响应。 2. 使用第三方库,如 Apache HttpClient、OkHttp 或 Retrofit。这些库都可以帮助你简化请求外部接口的流程,并提供了更丰富的功能。 下面是使用 `java.net` 包的示例代码: ``` URL url = new URL("http://www.example.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); int responseCode = connection.getResponseCode(); if (responseCode == 200) { InputStream inputStream = connection.getInputStream(); // 读取响应内容 } else { // 处理错误 } ``` 如果你使用的是第三方库,可能会有所不同,但大体流程是类似的。 ### 回答2: 在Java请求外部接口可以使用Java提供的相关库和工具来实现。主要有以下几种方式: 1. 使用HttpURLConnection类:Java提供了HttpURLConnection类来发送HTTP请求,可以通过该类发送GET、POST等请求,获取接口返回的数据。可以使用该类来建立连接、设置请求方法、添加请求头、发送请求、获取响应等。 2. 使用HttpClient类:HttpClient是Apache提供的一个开源工具包,用于发送HTTP请求。可以使用该工具包发送GET、POST等请求,设置请求参数、请求头等,并获取接口返回的数据。 3. 使用第三方库OkHttp:OkHttp是Square公司开发的一个优秀的HTTP客户端库。它简化了与网站的通信过程,提供了易于使用的API来处理HTTP请求和响应。可以使用OkHttp发送GET、POST等请求,设置请求参数、请求头等,并获取接口返回的数据。 4. 使用RestTemplate类:RestTemplate是Spring框架中提供的一个用于访问Rest服务的模板类,它封装了HTTP请求的处理逻辑。可以使用RestTemplate发送GET、POST等请求,并通过设置请求参数、请求头等来访问外部接口。 以上是几种常见的在Java请求外部接口的方式。根据项目的需求和开发的场景,可以选择合适的方式来实现数据的请求和处理。 ### 回答3: Java请求外部接口的方式有多种。其中比较常见的方式是使用Java的网络编程库来发送HTTP请求。 首先,需要引入Java的网络编程相关的库,如Java自带的URLConnection类或者第三方库如HttpClient等。 然后,可以使用以下步骤来请求外部接口: 1. 构建URL对象:使用接口的URL地址创建一个URL对象。 2. 打开连接:通过URL对象的openConnection方法打开一个连接对象,得到URLConnection实例。 3. 设置请求属性:如果需要,可以设置一些请求头信息,如User-Agent、请求方法、超时时间等。 4. 发送请求:通过调用URLConnection对象的connect()方法发送请求。 5. 获取响应:可以通过getResponseCode()方法获取响应的状态码,通过getInputStream()方法获取响应的输入流,从而获取返回的数据。 6. 处理响应:根据接口的返回格式进行解析和处理,可以使用Java内置的JSON库或第三方库让数据解析更加方便。 7. 关闭连接:最后,一定要关闭连接,可以通过调用URLConnection对象的disconnect()方法来关闭连接。 总之,使用Java请求外部接口需要通过网络编程库构建URL对象,设置请求方式和请求头,发送请求并获取响应,最后对响应进行处理和关闭连接。具体的实现和处理方式会根据接口的具体要求和返回格式而有所不同。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值