| 知乎專欄 | 多維度架構 | | | 微信號 netkiller-ebook | | | QQ群:128659835 請註明“讀者” |
RestTemplate 是 Spring Restful Client 用於調用restful介面
首先我要禁告各位,Spring發展過程中,每個版本都有一定差異。如果你做實驗失敗後在網上搜索答案,切記看一下版本號還有文章帖子的發佈時間。否則你可能按照Spring3配置方法去Spring4。
@RestController 預設返回 @ResponseBody, 所以@ResponseBody可加可不加
Maven 增加 jackson 開發包
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> </dependency>
url-pattern匹配中增加*.xml跟*.json
<servlet>
<servlet-name>springframework</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springframework</servlet-name>
<url-pattern>/welcome.jsp</url-pattern>
<url-pattern>/welcome.html</url-pattern>
<url-pattern>*.json</url-pattern>
<url-pattern>*.xml</url-pattern>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo-1.5.xsd
">
<mvc:resources location="/images/" mapping="/images/**" />
<mvc:resources location="/css/" mapping="/css/**" />
<mvc:resources location="/js/" mapping="/js/**" />
<mvc:resources location="/zt/" mapping="/zt/**" />
<mvc:resources location="/sm/" mapping="/sm/**" />
<mvc:resources location="/module/" mapping="/module/**" />
<context:component-scan base-package="cn.netkiller.controller">
</context:component-scan>
<context:annotation-config />
<mvc:annotation-driven />
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="configuracion" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:resources/development.properties" />
</bean>
<!-- Redis Connection Factory -->
<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="192.168.2.1" p:port="6379" p:use-pool="true" />
<!-- redis template definition -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnFactory" />
<mongo:db-factory id="mongoDbFactory" host="${mongo.host}" port="${mongo.port}" dbname="${mongo.database}" />
<!-- username="${mongo.username}" password="${mongo.password}" -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
<mongo:mapping-converter id="converter" db-factory-ref="mongoDbFactory" />
<bean id="gridFsTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
<constructor-arg ref="mongoDbFactory" />
<constructor-arg ref="converter" />
</bean>
</beans>
package cn.netkiller.controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ResponseBody;
import cn.netkiller.pojo.Message;
@RestController
@RequestMapping("/rest")
public class TestRestController {
public TrackerRestController() {
// TODO Auto-generated constructor stub
}
@RequestMapping("welcome")
@ResponseStatus(HttpStatus.OK)
public String welcome() {
return "Welcome to RestTemplate Example.";
}
@RequestMapping(value = "test", method = RequestMethod.GET, produces = { "application/xml", "application/json" })
@ResponseStatus(HttpStatus.OK)
public @ResponseBody Message test(@RequestHeader(value = "accept") String accept) {
Message message = new Message();
message.setTitle("test");
message.setText("Helloworld!!!");
System.out.println("accept: " + accept);
System.out.println(message.toString());
return message;
}
@RequestMapping("message/{name}")
public ResponseEntity<Message> message(@PathVariable String name) {
Message msg = new Message();
msg.setTitle(name);
return new ResponseEntity<Message>(msg, HttpStatus.OK);
}
@RequestMapping(value = "create", method = RequestMethod.POST, produces = { "application/xml", "application/json" })
public ResponseEntity<Tracker> create(@RequestBody Tracker tracker) {
this.mongoTemplate.insert(tracker);
return new ResponseEntity<Tracker>(tracker, HttpStatus.OK);
}
@RequestMapping(value = "read", method = RequestMethod.GET, produces = { "application/xml", "application/json" })
@ResponseStatus(HttpStatus.OK)
public ArrayList<Tracker> read() {
ArrayList<Tracker> trackers = (ArrayList<Tracker>) mongoTemplate.findAll(Tracker.class);
return trackers;
}
}
package cn.netkiller.pojo;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Message {
String title;
String text;
public Message() {
// TODO Auto-generated constructor stub
}
//@XmlElement
@XmlAttribute
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
//@XmlElement
@XmlAttribute
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
@Override
public String toString() {
return "Message [title=" + title + ", text=" + text + "]";
}
}
package api.web;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import api.domain.City;
import api.repository.CityRepository;
@Controller
public class IndexController {
@Autowired
private CityRepository repository;
// Spring RESTFul Client
@RequestMapping("/restful/get")
@ResponseBody
public String restfulGet() {
RestTemplate restTemplate = new RestTemplate();
String text = restTemplate.getForObject("http://inf.netkiller.cn/detail/html/2/2/42564.html", String.class);
return text;
}
@RequestMapping("/restful/get/{id}")
@ResponseBody
private static String restfulGetId(@PathVariable String id) {
final String uri = "http://inf.netkiller.cn/detail/html/{tid}/{cid}/{id}.html";
Map<String, String> params = new HashMap<String, String>();
params.put("tid", "2");
params.put("cid", "2");
params.put("id", id);
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class, params);
return (result);
}
@RequestMapping("/restful/post/{id}")
@ResponseBody
private static String restfullPost(@PathVariable String id) {
final String uri = "http://inf.netkiller.cn/detail/html/{tid}/{cid}/{id}.html";
Map<String, String> params = new HashMap<String, String>();
params.put("tid", "2");
params.put("cid", "2");
params.put("id", id);
City city = new City("Shenzhen", "Guangdong");
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.postForObject(uri, city, String.class, params);
return result;
}
@RequestMapping("/restful/put/{id}")
private static void restfulPut(@PathVariable String id) {
final String uri = "http://inf.netkiller.cn/detail/html/{tid}/{cid}/{id}.html";
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
City city = new City("Shenzhen", "Guangdong");
RestTemplate restTemplate = new RestTemplate();
restTemplate.put(uri, city, params);
}
@RequestMapping("/restful/delete/{id}")
private static void restfulDelete(@PathVariable String id) {
final String uri = "http://inf.netkiller.cn/detail/html/{tid}/{cid}/{id}.html";
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
RestTemplate restTemplate = new RestTemplate();
restTemplate.delete(uri, params);
}
}
neo@netkiller:~/www.netkiller.cn$ curl http://172.16.0.1:8080/spring4/rest/welcome.html
Welcome to RestTemplate Example.
neo@netkiller:~/www.netkiller.cn$ curl http://172.16.0.1:8080/spring4/rest/test.json
{"title":"test","text":"Helloworld!!!"}
neo@netkiller:~/www.netkiller.cn$ curl http://172.16.0.1:8080/spring4/rest/test.xml
<Message xmlns=""><title>test</title><text>Helloworld!!!</text></Message>
neo@netkiller:~/www.netkiller.cn$ curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d '{"login":"neo", "unique":"356770257607079474","hostname":"www.example.com","referrer":"http://www.netkiller.cn","href":"http://www.netkiller.cn"}' http://172.16.0.1:8080/spring4/rest/create.json
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json
Transfer-Encoding: chunked
Date: Tue, 21 Jun 2016 03:08:26 GMT
{"name":"neo","unique":"356770257607079474","hostname":"www.netkiller.cn","referrer":"http://www.netkiller.cn","href":"http://www.netkiller.cn"}
@RequestMapping("/restful/get")
@ResponseBody
public String restfulGet() {
RestTemplate restTemplate = new RestTemplate();
String text = restTemplate.getForObject("http://inf.netkiller.cn/detail/html/2/2/42564.html", String.class);
return text;
}
@RequestMapping("/restful/get/{id}")
@ResponseBody
private static String restfulGetId(@PathVariable String id) {
final String uri = "http://inf.netkiller.cn/detail/html/{tid}/{cid}/{id}.html";
Map<String, String> params = new HashMap<String, String>();
params.put("tid", "2");
params.put("cid", "2");
params.put("id", id);
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class, params);
return (result);
}
@RequestMapping("/restful/post/{id}")
@ResponseBody
private static String restfullPost(@PathVariable String id) {
final String uri = "http://inf.netkiller.cn/detail/html/{tid}/{cid}/{id}.html";
Map<String, String> params = new HashMap<String, String>();
params.put("tid", "2");
params.put("cid", "2");
params.put("id", id);
City city = new City("Shenzhen", "Guangdong");
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.postForObject(uri, city, String.class, params);
return result;
}
@RequestMapping("/findByMobile")
public String findByMobile() {
System.out.println("****************************findByMobile******************************");
final String uri = "http://www.netkiller.cn/account/getMemberByMobile.json";
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
try {
map.add("prefix", "86");
map.add("mobile", "13698041116");
map.add("_pretty_", "false");
} catch (Exception e) {
e.printStackTrace();
}
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.postForObject(uri, map, String.class);
System.out.println(map.toString());
System.out.println(result);
return result;
}
@RequestMapping("/findByMobile")
@ResponseBody
public String findByMobile() {
System.out.println("****************************findByMobile******************************");
final String uri = "https://www.netkiller.cn/account/getMemberByMobile";
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
try {
map.add("prefix", "86");
map.add("mobile", "13698041116");
map.add("args", "[]");
map.add("_pretty_", "false");
} catch (Exception e) {
e.printStackTrace();
}
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(uri, map, String.class);
System.out.println(map.toString());
System.out.println();
return response.getBody();
}
@RequestMapping("/restful/put/{id}")
private static void restfulPut(@PathVariable String id) {
final String uri = "http://inf.netkiller.cn/detail/html/{tid}/{cid}/{id}.html";
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
City city = new City("Shenzhen", "Guangdong");
RestTemplate restTemplate = new RestTemplate();
restTemplate.put(uri, city, params);
}
@RequestMapping("/restful/delete/{id}")
private static void restfulDelete(@PathVariable String id) {
final String uri = "http://inf.netkiller.cn/detail/html/{tid}/{cid}/{id}.html";
Map<String, String> params = new HashMap<String, String>();
params.put("id", id);
RestTemplate restTemplate = new RestTemplate();
restTemplate.delete(uri, params);
}
package cn.netkiller.file;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class UploadClient {
public static void main(String[] args) throws IOException {
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
bodyMap.add("user-file", getUserFileResource());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyMap, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange("http://localhost:8080/upload", HttpMethod.POST, requestEntity, String.class);
System.out.println("response status: " + response.getStatusCode());
System.out.println("response body: " + response.getBody());
}
public static Resource getUserFileResource() throws IOException {
//todo replace tempFile with a real file
Path tempFile = Files.createTempFile("hello", ".txt");
Files.write(tempFile, "Helloworld, http://www.netkiller.cn".getBytes());
System.out.println("uploading: " + tempFile);
File file = tempFile.toFile();
//to upload in-memory bytes use ByteArrayResource instead
return new FileSystemResource(file);
}
}
HttpClient client = new HttpClient();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("your_user","your_password");
client.getState().setCredentials(new AuthScope("thehost", 9090, AuthScope.ANY_REALM), credentials);
CommonsClientHttpRequestFactory commons = new CommonsClientHttpRequestFactory(client);
RestTemplate template = new RestTemplate(commons);
Example results = template.getForObject("http://www.netkiller.cn:9090/foo.json", Example.class);
package example.controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
@Controller
public class TestController {
@Autowired
private OAuth2RestOperations restTemplate;
@GetMapping("/")
@ResponseBody
public String index() {
OAuth2AccessToken token = restTemplate.getAccessToken();
System.out.println(token.getValue());
String tmp = restTemplate.getForObject("http://api.alpha.netkiller.cn/", String.class);
System.out.println(tmp);
return tmp;
}
@GetMapping("/ssl")
@ResponseBody
public String ssl() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
String url = "https://api.alpha.netkiller.cn/";
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, (chain, authType) -> true).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, new NoopHostnameVerifier());
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
httpComponentsClientHttpRequestFactory.setConnectTimeout(60000);
httpComponentsClientHttpRequestFactory.setReadTimeout(180000);
final RestTemplate restTemplate = new RestTemplate(httpComponentsClientHttpRequestFactory);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + this.restTemplate.getAccessToken().getValue());
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
String str = response.getBody();
return str;
}
@GetMapping("/pkcs12")
@ResponseBody
public String PKCS12(String url, String data) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException, UnrecoverableKeyException {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File("/opt/xxx.p12"));
keyStore.load(instream, "netkiller".toCharArray());
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContextBuilder.create().loadKeyMaterial(keyStore, "netkiller".toCharArray()).build();
// Allow TLSv1 protocol only
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, hostnameVerifier);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpclient);
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Connection", "keep-alive");
httpHeaders.add("Accept", "*/*");
httpHeaders.add("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
httpHeaders.add("Host", "api.netkiller.cn");
httpHeaders.add("X-Requested-With", "XMLHttpRequest");
httpHeaders.add("Cache-Control", "max-age=0");
httpHeaders.add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
HttpEntity<String> httpEntity = new HttpEntity<String>(httpHeaders);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
return response.getBody();
}
}
-Dsun.net.client.defaultConnectTimeout=<TimeoutInMiliSec> -Dsun.net.client.defaultReadTimeout=<TimeoutInMiliSec>
//Create resttemplate
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
//Override timeouts in request factory
private SimpleClientHttpRequestFactory getClientHttpRequestFactory()
{
SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
// or
// HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
//Connect timeout
clientHttpRequestFactory.setConnectTimeout(10_000);
//Read timeout
clientHttpRequestFactory.setReadTimeout(10_000);
return clientHttpRequestFactory;
}
注意下面使用了 Java 11 語法 var factory = new SimpleClientHttpRequestFactory();
package cn.netkiller.consul.consumer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfiguration {
@Bean
public RestTemplate restTemplate() {
var factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(3000);
factory.setReadTimeout(3000);
return new RestTemplate(factory);
}
}