赞
踩
@RequestBody | 请求体,获取一个请求的请求体内容 |
---|---|
就不用@RequestParam |
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println("请求体: "+body);
return "success";
}
只有表单才有请求体,点链接没有请求体。
enctype就是encodetype就是编码类型的意思。
multipart/form-data
multipart是指表单数据有多部分构成,
既有文本数据(form),又有文件等二进制数据(data)。
multipart/form-data是将文件以二进制的形式上传
<form action="${ctp}/testRequestBody" method="post" enctype="multipart/form-data">
<input name="username" value="tomcat"/>
<input name="password" value="123456">
<input type="file" name="file"/>
<input type="submit"/>
</form>
图片没在字符集范围的,所以她显示乱码正常的。
文本数据是字符编码的。
HttpEntity除了获取请求的请求体(表单),还可以获取请求的请求头。
@RequestMapping("/testHttpEntity")
public String testHttpEntity(HttpEntity<String> Body){
System.out.println("请求体: "+Body);
return "success";
}
请求头的全部信息。
,{accept=[image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, /],
referer=[http://localhost:8080/ssm/testOther.jsp],
accept-language=[zh-Hans-CN,zh-Hans;q=0.5],
ua-cpu=[AMD64],
accept-encoding=[gzip, deflate],
user-agent=[Mozilla/5.0 (Windows NT 10.0; Win64; x64; Trident/7.0; rv:11.0) like Gecko],
host=[localhost:8080],
content-length=[487],
connection=[Keep-Alive],
cache-control=[no-cache],
cookie=[JSESSIONID=6A5B641C8EF5F4C9E2BDF3641CC546F2; com.springsource.sts.run.embedded=true],
Content-Type=[multipart/form-data;boundary=7e415f2730424;
charset=UTF-8]}
1.@ResponseBody 将返回的数据转化成json字符串,放在响应体中。
2.如果返回的是页面,能转化成json字符串吗,然后放在响应体里面。
@ResponseBody
@RequestMapping("/testreturn")
public String testreturn(){
System.out.println("能转成json吗");
return "sucess";
如果返回的是String类型的ResponseEntity
泛型的意义:返回的响应体(body)中内容的类型
public ResponseEntity<String> testreturn(){
new ResponseEntity<String>(body,headers,statusCode);
body:响应体 |
---|
headers:响应头 |
statusCode:状态码 |
ResponseEntity可以定义
返回的HttpStatus(状态码)和HttpHeaders(响应头),body(响应体)
@RequestMapping("/testreturn")
public ResponseEntity<String> testreturn(){
HttpStatus statusCode;
String body ="<h1>success</h1>";
MultiValueMap<String,String> headers = new HttpHeaders();
headers.add("Set-Cookie", "username=hahhahahaha");
返回就 new一个
return new ResponseEntity<String>(body,headers,HttpStatus.OK);
响应体
响应头:
扩展:
ResponseEntity<> 可以规定返回的响应体,它的内容类型
如果是文件下载的话,响应体应该是个字节流 byte[ ]
比如:
服务器(Servlet容器)一部署启动web应用,
要下载的资源在web应用的WebRoot的scripts文件夹下
怎么找呢,还要拿到ServletContext实例。
说起ServletContext,一些人会产生误解,以为一个servlet对应一个ServletContext。其实不是这样的,事实是一个web应用对应一个ServletContext,所以ServletContext的作用范围是整个应用,明确这点很重要,这是基础中的基础。
我曾经想,为什么不起名叫WebContext或者ApplicationContext或者WebApplicationContext?这样见名知意多好。后来我想这也可能是有历史原因的:最初的客户端-服务端的架构模型非常简单,服务端运行着一些servlet用来处理客户端的请求。那个时候服务器很轻量级,运行一个应用,应用就由一堆servlet组成。所以这样简单的服务器也被称作servlet容器,主要作用就是运行servlet的。那么提供给应用的上下文就叫做ServletContext。(这个纯属个人意淫_,不对勿喷)
一个web应用对应一个ServletContext实例,这个实例是应用部署启动后,servlet容器为应用创建的。ServletContext实例包含了所有servlet共享的资源信息。通过提供一组方法给servlet使用,用来和servlet容器通讯,比如获取文件的MIME类型、分发请求、记录日志等。
这里需要注意一点,如果你的应用是分布式部署的,那么每台服务器实例上部署的Web应用实例都各自拥有一个ServletContext实例。
getRealPath
根据资源(所有servlet共享的资源)虚拟路径,返回实际路径(绝对路径)。
比如说web应用中有个JSP页面index.jsp,调用getRealPath(“index.jsp”),则返回index.jsp文件在文件系统中的绝对路径。在windows下或许是这样:D:\xxx\xxx\index.jsp,
这里可能存在web应用中有多个index.jsp,它们在不同的路径下。
这时候servlet容器
1.先从web应用的根目录下向下查找,
2.从/WEB-INF/lib目录下的各JAR包里面的/META-INF/resources目录查找
1.得到要下载的文件的流
new FileInputStream(realPath);
2.文件流多大,字节数组多大
fileinputstream.available();
3.要把文件流里面的所有数据,读到字节数组中。
fileinputstream.read(tmp);
4.关闭文件流
fileinputstream.close();
5.要下载文件的话,那就要定制返回的响应头,要用ResponseEntity
返回的响应体的内容类型就是一个byte[] 字节数组
文件下载的响应头:Content-Disposition
1.表明这是一个需要下载的文件 2.告诉浏览器默认文件名
处理一个downlowd请求(文件下载的请求) @SuppressWarnings({ "unchecked", "rawtypes" }) @RequestMapping("/download") public ResponseEntity<byte[]> download(HttpServletRequest request) throws Exception { ServletContext servletcontext = request.getServletContext(); 1.知道下载的文件的真实路径; String realPath=servletcontext.getRealPath("/scripts/jquery.min.js"); 2.得到下载的文件的流; FileInputStream fileinputstream=new FileInputStream(realPath); 3.文件流有多大,字节数组就有多大 byte[] tmp = new byte[fileinputstream.available()]; 4.要把文件流里面的所有数据,读到字节数组中 fileinputstream.read(tmp); 5关闭文件流 fileinputstream.close(); 6.要下载文件的话,那就要定制返回的响应头,要用ResponseEntity 返回的响应体的内容类型是一个 byte[] 字节数组 下载文件的响应头: Content-Disposition 1.表明这是一个要下载的文件 2.告诉浏览器,它的默认文件名 HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.set("Content-Disposition","attachment;filename="+"jquery.min.js"); return new ResponseEntity(tmp,httpHeaders,HttpStatus.OK); }
如果是返回RoponseEntity,视图解析器就不拼串了。
用到HttpEntity(获取请求的请求体,或者请求头)
起作用的是HttpMessageConverter<T>接口
将请求信息流转换为一个对象(类型为T),将对象写到响应流
根据请求头的mediaType,我能不能读取这种类型的数据
Boolean canRead(Class<?> clazz,MediaType mediaType);
根据响应,我能不能写出这种类型
Boolean canWrite(Class<?> clazz,MediaType mediaType);
List<Meida Type> getSupportMediaTypes();
能支持哪些媒体类型
read write
适配器有MessageConverter,
适配器执行目标方法,
一旦发现目标方法的参数,不是我们默认能处理的。
或者发现目标方法的返回值,不是以前的逻辑可以处理的。
调用MessageConverter处理。
HttpMessageConverter:
ByteArrayHttpMessageConverter:
将请求信息流(HttpMessage)转换成字节数组(ByteArray)对象
StringHttpMessageConverter:
将请求信息流(HttpMessage)转换成字符串(String)对象
将字符串(String)对象写到响应流
来看一下ByteArrayHttpMessageConverter
有个supports方法,看他只支持处理字节数组类型
如果是读取,看readInternal,把请求信息流(HttpMessage)
里面的信息,转换成一个字节数组对象。
如果是写,看writeInternal,把字节数组对象 写到响应流
getBody() 获取一个输出流(OutputStream)
字节数组以输出流的形式写出去
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。