비즈니스 시나리오 : 일상적인 개발에서는 물류 인터페이스 호출과 같은 타사 인터페이스를 호출해야 하는 경우가 많습니다. 이때 urlConnection 또는 RestTemplate을 사용하여 우편 배달부가 요청을 보내는 것을 시뮬레이션해야 합니다. 요청은 헤더 추가 및 설정을 지원합니다. 콘텐츠 유형은 json 전달을 지원하며 요청 방법은 get, post. 이며 파일이나 파일 스트림을 전달해야 할 수도 있습니다.
다음 예제에는 일상적인 개발 요청의 대부분이 포함되어 있어 직접 실행할 수 있습니다. 유용하다고 생각하시면 좋아요를 눌러주시고 헤매지 않도록 저장해 주세요.
새로운 springmvc 프로젝트, 프로젝트 구조 다이어그램 생성
폼 파일
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
</dependencies>
구성 파일
server.port=8089
spring.servlet.multipart.max-file-size = 100MB
spring.servlet.multipart.max-request-size = 1000MB
사용자 클래스
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
String name;
int age;
public User(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
UserController 클래스
import com.alibaba.fastjson.JSON;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.LinkedHashMap;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/loginGet")
public String loginGet(String name,Integer age){
System.out.println(name+""+age);
User user=new User(name,age);
return JSON.toJSONString(user);
}
@PostMapping("/login")
public String login(User user){
System.out.println(user);
return JSON.toJSONString(user);
}
@PostMapping("/upload")
public Map<String, String> login(User user, @RequestParam("file") MultipartFile file){
System.out.println(user);
System.out.println(file.getName());
Map<String, String> fileMetadata = new LinkedHashMap<>();
fileMetadata.put("文件名", file.getOriginalFilename());
fileMetadata.put("文件类型", file.getContentType());
fileMetadata.put("文件大小(byte)", String.valueOf(file.getSize()));
return fileMetadata;
}
@PostMapping("/loginJson")
public String loginJson(@RequestBody User user){
System.out.println(user);
return JSON.toJSONString(user);
}
}
사후 모드 x-www-form-urlencoded 키-값은 문자열만 가능합니다.
해당 자바 코드
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @ClassName JavaNice
* post x-www-form-urlencoded key-value只能是string
**/
@Slf4j
public class PostUtils {
private static final String ENCODING = "UTF-8";
/**
* post x-www-form-urlencoded key-value只能是string*
* @param url
* @param paramsMap
* @return
*/
public static String sendPost(String url, Map<String, String> paramsMap) {
CloseableHttpClient client = HttpClients.createDefault();
String responseText = "";
CloseableHttpResponse response = null;
try {
HttpPost method = new HttpPost(url);
if (paramsMap != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> param : paramsMap.entrySet()) {
NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
paramList.add(pair);
}
method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING));
}
response = client.execute(method);
HttpEntity entity = response.getEntity();
if (entity != null) {
responseText = EntityUtils.toString(entity);
}
} catch (Exception e) {
log.error("http request failed",e);
} finally {
try {
response.close();
} catch (Exception e) {
log.error("",e);
}
}
return responseText;
}
}
호출 코드
@Test
void postString() {
//post x-www-form-urlencoded key-value只能是string
Map<String,String> user=new HashMap<>();
user.put("name","javaNice");
String json = JSONObject.toJSONString(user);
Map<String,String> paramsMap = JSONObject.parseObject(json,Map.class);
System.out.println(json);
String resp = PostUtils.sendPost("http://localhost:8089/user/login",paramsMap);
System.out.println(resp);
}
get 메소드에 전달된 매개변수는 URL에 이어져 있습니다.
매개변수 URL 접합을 전달하는 게시 방법
포스트 모드에서 전달되는 매개변수는 json입니다.
도구
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.StringUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
public class HttpRequestUtil {
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
if (!url.contains("?")) {
url += "?1=1";
}
if (!param.startsWith("&")) {
url += "&";
}
String urlNameString = url + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
// for (String key : map.keySet()) {
// System.out.println(key + "--->" + map.get(key));
// }
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
public static String sendPost(String url, String param) {
HttpURLConnection httpURLConnection = null;
OutputStream out = null; //写
InputStream in = null; //读
int responseCode = 0; //远程主机响应的HTTP状态码
String result = "";
try {
URL sendUrl = new URL(url);
httpURLConnection = (HttpURLConnection) sendUrl.openConnection();
//post方式请求
httpURLConnection.setRequestMethod("POST");
//一定要设置 Content-Type 要不然服务端接收不到参数
httpURLConnection.setRequestProperty("Content-Type", "application/json");
//指示应用程序要将数据写入URL连接,其值默认为false(是否传参)
httpURLConnection.setDoOutput(true);
//httpURLConnection.setDoInput(true);
httpURLConnection.setUseCaches(false);
httpURLConnection.setConnectTimeout(30000); //30秒连接超时
httpURLConnection.setReadTimeout(30000); //30秒读取超时
//获取输出流
out = httpURLConnection.getOutputStream();
//输出流里写入POST参数
out.write(param.getBytes());
out.flush();
out.close();
responseCode = httpURLConnection.getResponseCode();
BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
result = br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String objectToUrlParam(Object object) {
if (object != null) {
StringBuilder builder = new StringBuilder();
// JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(object));
Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(object), Map.class);
for (Map.Entry<String, Object> entry :
map.entrySet()) {
if (entry.getValue() != null && !StringUtils.isEmpty(entry.getValue().toString())) {
builder.append("&").append(entry.getKey()).append("=").append(encode(entry.getValue()));
}
}
return builder.toString();
}
return "";
}
public static String encode(Object object) {
if (object != null) {
try {
return URLEncoder.encode(object.toString(), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException("字符串编码失败");
}
}
return "";
}
}
호출 코드
@Test
void get() {
//get 方式 传递参数拼接在url上
User user=new User("javaNice",666);
String paramsMap = HttpRequestUtil.objectToUrlParam(user);
String resp = HttpRequestUtil.sendGet("http://localhost:8089/user/loginGet",paramsMap);
System.out.println(resp);
}
@Test
void postUrl() {
//post 方式 传递参数url拼接
User user=new User("javaNice",666);
String paramsMap = HttpRequestUtil.objectToUrlParam(user);
System.out.println("传递参数"+paramsMap);
String url="http://localhost:8089/user/login?1=1"+paramsMap;
String resp = HttpRequestUtil.sendPost(url,"");
System.out.println("返回参数"+resp);
}
@Test
void post() {
//post 方式 传递参数为json
User user=new User("javaNice",666);
String paramsMap = JSON.toJSONString(user);
System.out.println("传递参数"+paramsMap);
String resp = HttpRequestUtil.sendPost("http://localhost:8089/user/loginJson",paramsMap);
System.out.println("返回参数"+resp);
}
RestTemplate 메서드
포스트 모드에서 전달되는 매개변수는 json입니다.
@Test
void post() {
//post 方式 传递参数为json
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8089/user/loginJson";
User body = new User("javaNice", 666);
User result = restTemplate.postForObject(url, body, User.class);
System.out.println("返回参数" + result);
}
post 메소드는 매개변수를 form-data로 전달하고 파일을 전달하며 요청 헤더를 추가합니다.
@Test
void postFormFile() {
//post 方式 传递参数为form-data 并且传递文件
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8089/user/upload";
//①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
//调用add方法放入表单元素(表单名称:值)
//②:文件对应的类型,需要是org.springframework.core.io.Resource类型的,常见的有[FileSystemResource、InputStreamResource、ByteArrayResource]
body.add("file", new FileSystemResource("/java/com/example/springmvc/22c017e48ea445199708dc1d2832dae5.pdf"));
body.add("name", "javaNice");
body.add("age", "666");
//③:头
HttpHeaders headers = new HttpHeaders();
headers.add("header1", "v1");
headers.add("header2", "v2");
//④:请求实体
RequestEntity<MultiValueMap<String, Object>> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
//⑤:发送请求(请求实体,返回值需要转换的类型)
ResponseEntity<Map<String, String>> responseEntity = restTemplate.exchange(
requestEntity,
new ParameterizedTypeReference<Map<String, String>>() {
});
Map<String, String> result = responseEntity.getBody();
System.out.println(result);
}
post 스트리밍을 통해 파일 업로드
@Test
void postFormFileStream() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8089/user/upload";
//①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
/**
* ②:通过流的方式上传文件,流的方式需要用到InputStreamResource类,需要重写2个方法
* getFilename:文件名称
* contentLength:长度
*/
File file = new File("/java/com/example/springmvc/22c017e48ea445199708dc1d2832dae5.pdf");
//2、建立数据通道
try {
InputStream inputStream = new FileInputStream(file);
InputStreamResource inputStreamResource = new InputStreamResource(inputStream) {
@Override
public String getFilename() {
return "22c017e48ea445199708dc1d2832dae5.pdf";
}
@Override
public long contentLength() throws IOException {
return inputStream.available();
}
};
body.add("file", inputStreamResource);
body.add("name", "javaNice");
body.add("age", "666");
//③:头
HttpHeaders headers = new HttpHeaders();
headers.add("header1", "v1");
headers.add("header2", "v2");
//④:请求实体
RequestEntity<MultiValueMap<String, Object>> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
//⑤:发送请求(请求实体,返回值需要转换的类型)
ResponseEntity<Map<String, String>> responseEntity = restTemplate.exchange(
requestEntity,
new ParameterizedTypeReference<Map<String, String>>() {
});
Map<String, String> result = responseEntity.getBody();
System.out.println(result);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}