Java Http请求方式RestTemplate
Real_ma 人气:0引言
在开发中有时候经常需要一些Http请求,请求数据,下载内容,也有一些简单的分布式应用直接使用Http请求作为跨应用的交互协议。
在Java中有不同的Http请求方式,主要就是HttpURLConnection或者ApacheHttpClient,但是这两个用起来都感觉有那么一点点的复杂;
好在Spring内置了RestTemplate作为Http请求的工具类,简化了很多操作,虽然Spring5推出了WebClient,但是整体感觉还是RestTemplate用起来更简单方便一些。
这里记录分享下RestTemplate的常见使用方式,RestTemplate作为Java中最简单好用的Http请求工具类一定要了解一下
常见用法
简单Get\Post请求
@Test public void testGetPost(){ RestTemplate restTemplate = new RestTemplate(); restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter()); String res = restTemplate.postForObject("http://test.aihe.space/", null, String.class); System.out.println(res); String res2 = restTemplate.getForObject("http://test.aihe.space/", String.class); System.out.println(res2); }
Post提交常规表单
@Test public void testPostFrom(){ RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); MultiValueMap<String, String> map= new LinkedMultiValueMap<>(); map.add("id", "1"); HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers); String fooResourceUrl = "http://test.aihe.space/"; ResponseEntity<String> response = restTemplate.postForEntity(fooResourceUrl, request, String.class); System.out.println(response.getStatusCode()); System.out.println(response.getBody()); }
Post上传文件
注意:上传文件时的value为FileSystemResource
@Test public void testPostFile(){ RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap<String, Object> map= new LinkedMultiValueMap<>(); map.add("id", "1"); map.add("file",new FileSystemResource("/Users/aihe/code/init/src/test/java/me/aihe/RestTemplateTest.java")); HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers); String fooResourceUrl = "http://test.aihe.space/"; ResponseEntity<String> response = restTemplate.postForEntity(fooResourceUrl, request, String.class); System.out.println(response.getStatusCode()); System.out.println(response.getBody()); }
配置项
请求添加Cookie\Header
@Test public void testCookieHeader(){ RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap<String, Object> map= new LinkedMultiValueMap<>(); // 常见的Header都可以直接设置 // headers.set headers.set("custom1","customValue1"); // 设置Cookie headers.set(HttpHeaders.COOKIE,"xxxx"); map.add("id", "1"); HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers); String fooResourceUrl = "http://test.aihe.space/"; ResponseEntity<String> response = restTemplate.postForEntity(fooResourceUrl, request, String.class); System.out.println(response.getStatusCode()); System.out.println(response.getBody()); }
配置请求工厂 超时、代理
使用Rest请求的时候注意设置超时时间
@Test public void testHttpFactory(){ RestTemplate restTemplate = new RestTemplate(); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setReadTimeout(5000); requestFactory.setConnectTimeout(3000); Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 7890)); requestFactory.setProxy(proxy); restTemplate.setRequestFactory(requestFactory); restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter()); String res = restTemplate.postForObject("http://test.aihe.space/", null, String.class); System.out.println(res); }
配置拦截器、转换器,错误处理
@Test public void testConverterInterceptor(){ RestTemplate restTemplate = new RestTemplate(); restTemplate.setInterceptors(Collections.singletonList(new BasicAuthenticationInterceptor("admin","admin"))); restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter()); restTemplate.setErrorHandler(new DefaultResponseErrorHandler()); String res = restTemplate.postForObject("http://test.aihe.space/", null, String.class); System.out.println(res); }
错误重试(额外)
可以考虑使用Spring Retry,但是相当于引入了新的东西,如果没有特殊必要,可以自己简单用for循环做下;
SSL请求
参考:stackoverflow.com/questions/1…
@Test public void testSSL() throws FileNotFoundException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException { String keyStorePassword = "123456"; KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(new FileInputStream(new File("keyStoreFile")), keyStorePassword.toCharArray()); SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( new SSLContextBuilder() .loadTrustMaterial(null, new TrustSelfSignedStrategy()) .loadKeyMaterial(keyStore, keyStorePassword.toCharArray()) .build(), NoopHostnameVerifier.INSTANCE); HttpClient httpClient = HttpClients.custom().setSSLSocketFactory( socketFactory).build(); ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory( httpClient); RestTemplate restTemplate = new RestTemplate(requestFactory); String res = restTemplate.postForObject("http://test.aihe.space/", null, String.class); System.out.println(res); }
基于RestTemplate一些工具
钉钉机器人通知
可以支持发送普通文本、ActionCard,Markdown的消息
import java.util.ArrayList; import java.util.List; import lombok.Data; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; /** * 使用场景: * 功能描述:https://developers.dingtalk.com/document/app/custom-robot-access/title-72m-8ag-pqw */ @Slf4j public class RobotUtils { private static RestTemplate restTemplate = new RestTemplate(); private static String URL = ""; public static void main(String[] args) { sendMarkDownMsg( URL, "测试", "测试", new ArrayList<>() ); } /** * { * "msgtype": "text", * "text": { * "content": "我就是我, @150XXXXXXXX 是不一样的烟火" * }, * "at": { * "atMobiles": [ * "150XXXXXXXX" * ], * "isAtAll": false * } * } */ public static void sendTextMsg(String url, String content, List<String> atPerson) { RobotMsg robotMsg = new RobotMsg(); robotMsg.setMsgtype("text"); RobotAt robotAt = new RobotAt(); robotAt.setAtAll(false); if (atPerson != null && atPerson.size() > 0) { robotAt.setAtMobiles(atPerson); } robotMsg.setAt(robotAt); RobotText robotText = new RobotText(); robotText.setContent(content); robotMsg.setText(robotText); ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, robotMsg, String.class); log.info("sendTextMsg {}",responseEntity.getBody()); } /** * @param url 机器人地址 * @param title actionCard标题 * @param text 缩略内容 * @param vertical 按钮方向 * @param btns 按钮内容 */ public static void sendActionCardMsg(String url, String title, String text, Boolean vertical, List<RobotBtn> btns) { RobotMsg robotMsg = new RobotMsg(); robotMsg.setMsgtype("actionCard"); RobotAt robotAt = new RobotAt(); robotAt.setAtAll(false); RobotActionCard robotActionCard = new RobotActionCard(); robotActionCard.setTitle(title); robotActionCard.setText(text); robotActionCard.setBtnOrientation((vertical == null || vertical) ? "0" : "1"); robotActionCard.setBtns(btns); robotMsg.setActionCard(robotActionCard); ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, robotMsg, String.class); System.out.println(responseEntity.getBody()); } public static void sendMarkDownMsg(String url,String title,String text,List<String> atPerson){ RobotMarkDownMsg markDownMsg = new RobotMarkDownMsg(); markDownMsg.setMsgtype("markdown"); RobotAt robotAt = new RobotAt(); robotAt.setAtAll(false); if (atPerson != null && atPerson.size() > 0) { robotAt.setAtMobiles(atPerson); } markDownMsg.setAt(robotAt); RobotMarkdownText markdownText = new RobotMarkdownText(); markdownText.setTitle(title); markdownText.setText(text); markDownMsg.setMarkdown(markdownText); ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, markDownMsg, String.class); System.out.println(responseEntity.getBody()); } public enum SupportRobotEnum { /** * 测试机器人群 */ CESHI("测试机器人群", ""); @Getter private String desc; @Getter private String url; SupportRobotEnum(String desc, String url) { this.desc = desc; this.url = url; } } @Data public static class RobotAt { public List<String> atMobiles; public boolean isAtAll; } @Data public static class RobotMarkDownMsg{ public String msgtype; public RobotAt at; public RobotMarkdownText markdown; } @Data public static class RobotMarkdownText { String title; String text; } @Data public static class RobotMsg { public String msgtype; public RobotAt at; /** * 普通文字消息类型消息 */ public RobotText text; /** * actionCard类型消息时支持 */ public RobotActionCard actionCard; } @Data public static class RobotText { public String content; } @Data public static class RobotActionCard { public String title; public String text; public String hideAvatar; public String btnOrientation; public List<RobotBtn> btns; } @Data public static class RobotBtn { public String title; public String actionURL; public static RobotBtn buildBtn(String title, String actionUrl) { RobotBtn robotBtn = new RobotBtn(); robotBtn.setActionURL(actionUrl); robotBtn.setTitle(title); return robotBtn; } } }
总结
1、 Http请求在开发过程中也是一个常见的高频操作;
2、Spring封装了Http的工具类RestTemplate非常好用,基本上满足了所有Http相关的需求。
3、这里介绍整理了下RestTemplate的常见使用方式,遇到有对应的内容,直接翻阅使用即可。
加载全部内容