8.HttpEntity,ResponseEntity

@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)
字节数组以输出流的形式写出去
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值