multipart/form-data 请求体本质上就是。一个请求体包含多个Part,每个Part有自己独立的header和body。
一般用于文件上传,以及一次性提交多种不同数据格式的请求。
这里演示提交一个文件的时,还提交一个json,一个表单数据到服务器,由SpringBoot处理请求。
import java.io.IOException; import java.nio.file.Paths; import java.util.Arrays; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.MultipartBodyBuilder; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; public class MainTest { public static void main(String[] args) throws IOException { RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); // 多部件表单体 MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder(); // ----------------- 表单 part multipartBodyBuilder.part("name", "KevinBlandy"); /** * 每个表单项都有独立的header * 在这个表单项后额外添加了一个header */ multipartBodyBuilder.part("skill", Arrays.asList("Java", "Python", "Javascript")).header("myHeader", "myHeaderVal"); // ----------------- 文件 part // 从磁盘读取文件 multipartBodyBuilder.part("file", new FileSystemResource(Paths.get("D:\\17979625.jpg")), MediaType.IMAGE_JPEG); // 从classpath读取文件 multipartBodyBuilder.part("file", new ClassPathResource("app.log"), MediaType.TEXT_PLAIN); // ----------------- json part // json表单项 multipartBodyBuilder.part("json", "{\"website\": \"SpringBoot中文社区\"}", MediaType.APPLICATION_JSON); // build完整的消息体 MultiValueMap<String, HttpEntity<?>> multipartBody = multipartBodyBuilder.build(); ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/test", multipartBody, String.class); System.out.println(responseEntity); } }
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.Part; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController @RequestMapping("/test") public class TestController { private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class); @PostMapping public Object test (HttpServletRequest request, @RequestParam("name") String name, @RequestParam("skill") String[] skills, @RequestParam("file") MultipartFile[] multipartFiles, @RequestParam("json") String json) throws IOException, ServletException { // 获取封装后的数据 LOGGER.debug("name={}", name); LOGGER.debug("skill=[{}]", String.join(",", skills)); for (MultipartFile multipartFile : multipartFiles) { LOGGER.debug("file,fileName={},size={},contentType={}", multipartFile.getOriginalFilename(), multipartFile.getSize(), multipartFile.getContentType()); } LOGGER.debug("json={}", json); // 获取指定part中定义的header Part part = request.getPart("skill"); String headerVal = part.getHeader("myHeader"); LOGGER.debug("myHeader={}", headerVal); return "ok"; } }
o.s.web.servlet.DispatcherServlet : POST "/test", parameters={masked} s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to io.springboot.twitter.web.controller.TestController#test(HttpServletRequest, String, String[], MultipartFile[], String) i.s.t.web.controller.TestController : name=KevinBlandy i.s.t.web.controller.TestController : skill=[["Java","Python","Javascript"]] i.s.t.web.controller.TestController : file,fileName=17979625.jpg,size=11224,contentType=image/jpeg i.s.t.web.controller.TestController : file,fileName=app.log,size=77,contentType=text/plain i.s.t.web.controller.TestController : json={"website": "SpringBoot中文社区"} i.s.t.web.controller.TestController : myHeader=myHeaderVal m.m.a.RequestResponseBodyMethodProcessor : Using 'text/plain', given [text/plain, application/json, application/*+json, */*] and supported [application/json, application/*+json, text/plain, */*, text/plain, */*, application/json, application/*+json] m.m.a.RequestResponseBodyMethodProcessor : Writing ["ok"] o.s.web.servlet.DispatcherServlet : Completed 200 OK
准确无误的读取到了客户端所有的提交的数据