首页>>后端>>Spring->springmvc获取请求头(springmvc获取header)

springmvc获取请求头(springmvc获取header)

时间:2023-12-02 本站 点击:0

浅谈SpringMvc HttpMessageConverter

1.HttpMessageConverter是SpringMvc框架中一个重要的组件,其主要职责是对@RequestBody的解析(该注解作用就是告诉mvc,这个参数由Http的请求头,经过HttpMessageConverter解析得到)

看一下该接口

该接口的canRead方法表示其支持的Class类型,MediaType是其支持的http的ContentType类型,假如一个Http请求是Application/json,Mvc框架会去寻找支持该MediaType的Converter,然后再判断@RequestBody注解对应的class类型是否支持,如果支持,那么就交由对应的MessageConverter去解析。

另一个问题就是,这个类是解析什么呢,实际上,HttpInputMessage是指HttpServletRequest的Body的流,可以看接口。

那么Mvc框架的部分核心我们就能猜到了,一个Http请求过来,包括Header和Body,对于其中的Body的流将会被DispatcherServlet包装成SpringMvc的HttpRequest,然后委托RequestChainExecutor,经过一系列处理,最终Body的流到了HttpMessageConverter(这里不是那么准确),重点需要理解的就是一个Http请求,头部会被HttpMessageConverter获取并解析,如果找不到对应的HttpMessageConverter,Spring框架会报异常。

一般情况下,我们常见的有StringHttpMessageConverter(text/plain+String),ByteArrayHttpMessageConverter(application/octet-stream+byte[]),FormHttpMessageConverter(好几个),FastJsonHttpMessageConverter(application/json+Object)等。

如果要自定义一个HttpMessageConverter,只要继承AbstractHttpMessageConverter就可以,其中运用了模板方法,具体的逻辑组织在AbstractHttpMessageConverter中已经实现,只需要实现以下方法和构造方法就可以使用了。

该部分就是,将HttpMessage(通过容器的HttpRequest获得相关属性),首先read请求时,直接转readInternal(子类实现),如果是write响应,则先判断返回的结果类型是不是流,是流就直接构建Message响应(返回流,如果直接读取就会被消费了,流只能读一次,对应的就是Controller(MethodHandler)的返回结果),如果是其他类型,则交由实现类将JavaObject变成流。

综上所述,HttpMessageConverter就是负责将Http请求的Body与JavaObject之间进行转换,那么在哪里可以配置呢?在WebMvcConfigurationSupport的configureMessageConverters中可以配置,默认情况boot会在存在对应classPath时自动注入mvc相关配置,而关于HttpMessageConverter在不重写configureMessageConverters时默认配置一堆,一旦自定义配置了,就只支持自己定义的几个了。

关于模板方法,在AbstractXmlHttpMessageConverter中也有使用到,同样的套路,父类定义方法模板(骨架),子类实现逻辑原语。

对于一个Http请求,Tomcat(一定猜测)首先监听端口,收到请求就委托一个Thread去初始化Servlet或者执行Servlet,并通过ThreadLocal来保存HttpServletContext和HttpRequest与HttpResponse,如果去测试的话,你会发现Tomcat基于装饰器模式用RequestFacade,ResponseFacade封装了Request和Response,请求到DispatcherServlet,SpringMvc则解析请求头(可以重复解析)和请求Body,通过请求头方法类型交给doDispatch进行解析,最终交给RequestChainExecutor去执行,通过请求头得到路径交给不同的MethodHandler(Controller接口与@Controller)去处理。根据MethodHandler对应方法的注解(@RequestBody,@ResponseBody,@PathVariable等)来交给HttpMessageConverter(Body的解析)、Converter(默认的非Body的解析)、HandlerMethodArgumentResolver(报文头解析及前置处理)、HandlerMethodReturnValueHandler(方法返回参数处理)等进行Http报文和JavaObject的转换。

我实在懒得写清除细节了,截图头疼,没必要深究源码(太细节了),先搞清楚Mvc的各个组件再说。

Mvc 数据流

Http(Header+Body)-HttpMessage(Body)-HttpMessageConverter-JavaObject

                                                       (Header)-Converter+Format SPI

Mvc Controller拓展

MethodHandler+MethodHandlerInterceptor+HandlerMethodArgumentResolver+

HandlerMethodReturnValueHandler+Aspect(有些拓展基于代理)

springmvc是怎样接受websocket请求的

浏览器客户端和服务器建立起websocket的链接,最初也是http请求握手,通过httpServletRequest发送http请求到服务器,其中头部就包含需要请求websocket链接的一系列信息,大概过程如下

1.客户端请求一个链接,头部中包含如下信息

GET /demo HTTP/1.1

Host: example.com

Connection: Upgrade

Sec-WebSocket-Key2: 12998 5 Y3 1 .P00

Upgrade: WebSocket

Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5

Origin:

[8-byte security key]

2.服务器根据头部中的Sec-WebSocket-Key2,Sec-WebSocket-Key1,Upgrade,[8-byte security key] 知道客户端需要一个websocket协议链接,于是返回一个消息,包含如下头部

HTTP/1.1 101 WebSocket Protocol Handshake

Upgrade: WebSocket

Connection: Upgrade

WebSocket-Origin:

WebSocket-Location: ws://example.com/demo

[16-byte hash response]

3.客户端收到消息之后,建立起websocket链接,这时就可以进行实时通信了

我们可以定义一个处理器来实现WebSocketHandler处理请求

public class MyWebSocketHandler implements WebSocketHandler{

/**

* webscoket建立好链接之后的处理函数

* @param session 当前websocket的会话id,打开一个websocket通过都会生成唯一的一个会话,可以通过该id进行发送消息到浏览器客户端

*/

@Override

public void afterConnectionEstablished(WebSocketSession session) throws Exception {

// TODO Auto-generated method stub

}

/**

* 客户端发送服务器的消息时,的处理函数,在这里收到消息之后可以分发消息

*/

@Override

public void handleMessage(WebSocketSession session, WebSocketMessage? message) throws Exception {

// TODO Auto-generated method stub

}

/**

* 消息传输过程中出现的异常处理函数

*/

@Override

public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

// TODO Auto-generated method stub

}

/**

* websocket链接关闭的回调

*/

@Override

public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {

// TODO Auto-generated method stub

}

/**

* 是否支持处理拆分消息,返回true返回拆分消息

*/

@Override

public boolean supportsPartialMessages() {

// TODO Auto-generated method stub

return false;

}

}

websocket的链接建立是基于http握手协议,我们可以添加一个拦截器处理握手之前和握手之后过程

public class MyHandShakeInterceptor implements HandshakeInterceptor{

/**

* 握手之前,若返回false,则不建立链接

*/

@Override

public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,

MapString, Object attributes) throws Exception {

// TODO Auto-generated method stub

return true;

}

/**

* 握手之后

*/

@Override

public void afterHandshake(ServerHttpRequest requestscjgcj.comServerHttpResponse response, WebSocketHandler wsHandler,

Exception exception) {

// TODO Auto-generated method stub

}

}

接下来,需要我们把处理器和拦截器注册到spring websocket中

@Configuration

@EnableWebSocket

public class WebSocketConfig implements WebSocketConfigurer {

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

registry.addHandler(new MyWebSocketHandler(), "/portfolio")//添加一个处理器还有定义处理器的处理路径

.addInterceptors(new MyHandShakeInterceptor())

.withSockJS();

}

}

在这里我们用到.withSockJS(),SockJS是spring用来处理浏览器对websocket的兼容性,目前浏览器支持websocket还不是很好,特别是IE11以下.SockJS能关键浏览器能否支持websocket来提供三种方式用于websocket请求,三种方式分别是 WebSocket, HTTP Streaming以及 HTTP Long Polling

SockJS提供了浏览器客户端的js库,在浏览器我们请求websocket就这么用

var socket = new SockJS('/whats/portfolio');//项目名称 + 处理器拦截路径名就会打开的目的websocket链接口

/**

* 建立成功的回调函数

*/

socket.onopen = function() {

console.log('open');

};

/**

* 服务器有消息返回的回调函数

*/

socket.onmessage = function(e) {

console.log('message', e.data);

};

/**

* websocket链接关闭的回调函数

*/

socket.onclose = function() {

console.log('close');

};

然后客户端发送一个消息

document.getElementById("ws").onclick = function() {

socket.send("fff");

}

服务器MyWebSocketHandler中,通过handlemessage接收消息并进行分发

/**

* 客户端发送服务器的消息时,的处理函数,在这里收到消息之后可以分发消息

*/

@Override

public void handleMessage(WebSocketSession session, WebSocketMessage? message) throws Exception {

//获取消息

String body = (String) message.getPayload();

//一系列的处理之后...

//发送消息

session.sendMessage(message);

}

session可以用来标注客户端id,相对于我们的httpsession,这样,如果我们想做一个精准推送和全部推送,我们可以这么做

首先在自定义的处理其中,建一个队列来存储连进来的websocketsession

public class MyWebSocketHandler implements WebSocketHandler{

private ListWebSocketSession users = new ArrayListWebSocketSession(); //存放WebSocketSession的队列

/**

* webscoket建立好链接之后的处理函数

* @param session 当前websocket的会话id,打开一个websocket通过都会生成唯一的一个会话,可以通过该id进行发送消息到浏览器客户端

*/

@Override

public void afterConnectionEstablished(WebSocketSession session) throws Exception {

session.getAttributes().put("userid", "xxxx");//如果有用户登录,可以把用户的id绑定到session里面,便于后面做精准推送

users.add(session); //每个链接来的客户端都把WebSocketSession保存进来

}

//...

}

然后呢,我们在接收到消息的时候,就可以直接的根据需要精准推送到用户或者全部推送了

/**

* 客户端发送服务器的消息时,的处理函数,在这里收到消息之后可以分发消息

*/

@Override

public void handleMessage(WebSocketSession session, WebSocketMessage? message) throws Exception {

// TODO Auto-generated method stub

for (WebSocketSession webSocketSession : users) {

//Long id = (Long) session.getAttributes().get("userid");//可以通过获取userid进行匹配,从而进行精准推送

message = new TextMessage("ggg");

webSocketSession.sendMessage(message); //全部推送

}

}

spring websocket大概的请求过程就是这样子,这是基础的请求过程,细心的同学可能发现,如果我有很多种不同的业务请求,是不是要写很多个处理器??能不能只实现一个处理器,然后由这个处理器来进行分发处理,做到类似springmvc的DispatcherServlet那样子??下次研究看看

springmvc的注解都有哪些

spring mvc常用的注解:

@Controller

@Controller 负责注册一个bean 到spring 上下文中,bean 的ID 默认为

类名称开头字母小写,你也可以自己指定,如下

方法一:

@Controller

public class TestController {}

方法二:

@Controller("tmpController")

public class TestController {}

@RequestMapping

1.@RequestMapping用来定义访问的URL,你可以为整个类定义一个

@RequestMapping,或者为每个方法指定一个。

把@RequestMapping放在类级别上,这可令它与方法级别上的

@RequestMapping注解协同工作,取得缩小选择范围的效果。

例如:

@RequestMapping("/test")

public class TestController {}

则,该类下的所有访问路径都在/test之下。

2.将@RequestMapping用于整个类不是必须的,如果没有配置,所有的方法

的访问路径配置将是完全独立的,没有任何关联。

3.完整的参数项为:@RequestMapping(value="",method =

{"",""},headers={},params={"",""}),各参数说明如下:

value :String[] 设置访问地址

method: RequestMethod[]设置访问方式,字符数组,查看RequestMethod

类,包括GET, HEAD, POST, PUT, DELETE, OPTIONS, TRACE,常用

RequestMethod.GET,RequestMethod.POST

headers:String[] headers一般结合method = RequestMethod.POST使用

params: String[] 访问参数设置,字符数组 例如:userId=id

4.value的配置还可以采用模版变量的形式 ,例如:@RequestMapping

(value="/owners/{ownerId}", method=RequestMethod.GET),这点将在介

绍@PathVariable中详细说明。

5.@RequestMapping params的补充说明,你可以通过设置参数条件来限制

访问地址,例如params="myParam=myValue"表达式,访问地址中参数只有

包含了该规定的值"myParam=myValue"才能匹配得上,类似"myParam"之类

的表达式也是支持的,表示当前请求的地址必须有该参数(参数的值可以是

任意),"!myParam"之类的表达式表明当前请求的地址不能包含具体指定的

参数"myParam"。

6.有一点需要注意的,如果为类定义了访问地址为*.do,*.html之类的,则

在方法级的@RequestMapping,不能再定义value值,否则会报错,例如

Java代码

@RequestMapping("/bbs.do")

public class BbsController {

@RequestMapping(params = "method=getList")

public String getList() {

return "list";

}

@RequestMapping(value= "/spList")

public String getSpecialList() {

return "splist";

}

}

如上例:/bbs.do?method=getList 可以访问到方法getList() ;而访

问/bbs.do/spList则会报错.

@PathVariable

1.@PathVariable用于方法中的参数,表示方法参数绑定到地址URL的模板

变量。

例如:

Java代码

@RequestMapping(value="/owners/{ownerId}",

method=RequestMethod.GET)

public String findOwner(@PathVariable String ownerId, Model

model) {

Owner owner = ownerService.findOwner(ownerId);

model.addAttribute("owner", owner);

return "displayOwner";

}

2.@PathVariable用于地址栏使用{xxx}模版变量时使用。

如果@RequestMapping没有定义类似"/{ownerId}" ,这种变量,则使用在

方法中@PathVariable会报错。

@ModelAttribute

1.应用于方法参数,参数可以在页面直接获取,相当于

request.setAttribute(,)

2.应用于方法,将任何一个拥有返回值的方法标注上 @ModelAttribute,使

其返回值将会进入到模型对象的属性列表中.

3.应用于方法参数时@ModelAttribute("xx"),须关联到Object的数据类型

,基本数据类型 如:int,String不起作用

例如:

Java代码

@ModelAttribute("items")//——①向模型对象中添加一个名为items的

属性

public ListString populateItems() {

ListString lists = new ArrayListString();

lists.add("item1");

lists.add("item2");

return lists;

}

@RequestMapping(params = "method=listAllBoard")

public String listAllBoard(@ModelAttribute("currUser")User user,

ModelMap model) {

bbtForumService.getAllBoard();

//——②在此访问模型中的items属性

System.out.println("model.items:" + ((ListString)

model.get("items")).size());

return "listBoard";

}

在 ① 处,通过使用 @ModelAttribute 注解,populateItem() 方法将在

任何请求处理方法执行前调用,Spring MVC 会将该方法返回值以“items

”为名放入到隐含的模型对象属性列表中。

所以在 ② 处,我们就可以通过 ModelMap 入参访问到 items 属性,当执

行 listAllBoard() 请求处理方法时,② 处将在控制台打印

出“model.items:2”的信息。当然我们也可以在请求的视图中访问到模型

对象中的 items 属性。

@ResponseBody

这个注解可以直接放在方法上,表示返回类型将会直接作为HTTP响应字节

流输出(不被放置在Model,也不被拦截为视图页面名称)。可以用于ajax。

@RequestParam

@RequestParam是一个可选参数,例如:@RequestParam("id") 注解,所以

它将和URL所带参数 id进行绑定

如果入参是基本数据类型(如 int、long、float 等),URL 请求参数中

一定要有对应的参数,否则将抛出

org.springframework.web.util.NestedServletException 异常,提示无

法将 null 转换为基本数据类型.

@RequestParam包含3个配置 @RequestParam(required = ,value="",

defaultValue = "")

required :参数是否必须,boolean类型,可选项,默认为true

value: 传递的参数名称,String类型,可选项,如果有值,对应到设置方

法的参数

defaultValue:String类型,参数没有传递时为参数默认指定的值

@SessionAttributes session管理

Spring 允许我们有选择地指定 ModelMap 中的哪些属性需要转存到

session 中,以便下一个请求属对应的 ModelMap 的属性列表中还能访问

到这些属性。这一功能是通过类定义处标注 @SessionAttributes 注解来

实现的。@SessionAttributes 只能声明在类上,而不能声明在方法上。

例如

@SessionAttributes("currUser") // 将ModelMap 中属性名为currUser 的属性

@SessionAttributes({"attr1","attr2"})

@SessionAttributes(types = User.class)

@SessionAttributes(types = {User.class,Dept.class})

@SessionAttributes(types = {User.class,Dept.class},value={"attr1","attr2"})

@CookieValue 获取cookie信息

@RequestHeader 获取请求的头部信息

springmvc 请求头和请求体 有什么用

1. Content-Type

MediaType,即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。

[html] view plain copy

类型格式:type/subtype(;parameter)? type

主类型,任意的字符串,如text,如果是*号代表所有;

subtype 子类型,任意的字符串,如html,如果是*号代表所有;

parameter 可选,一些参数,如Accept请求头的q参数, Content-Type的 charset参数。

例如: Content-Type: text/html;charset:utf-8;

常见的媒体格式类型如下:

text/html : HTML格式

text/plain :纯文本格式

text/xml : XML格式

image/gif :gif图片格式

image/jpeg :jpg图片格式

image/png:png图片格式

以application开头的媒体格式类型:

application/xhtml+xml :XHTML格式

application/xml : XML数据格式

application/atom+xml :Atom XML聚合格式

application/json : JSON数据格式

application/pdf :pdf格式

application/msword : Word文档格式

application/octet-stream : 二进制流数据(如常见的文件下载)

application/x-www-form-urlencoded : form encType=””中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

另外一种常见的媒体格式是上传文件之时使用的:

multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式

以上就是我们在日常的开发中,经常会用到的若干content-type的内容格式。

2. Spring MVC中关于关于Content-Type类型信息的使用

首先我们来看看RequestMapping中的Class定义:

[html] view plain copy

@Target({ElementType.METHOD, ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Mapping

public @interface RequestMapping {

String[] value() default {};

RequestMethod[] method() default {};

String[] params() default {};

String[] headers() default {};

String[] consumes() default {};

String[] produces() default {};

}

value: 指定请求的实际地址, 比如 /action/info之类。

method: 指定请求的method类型, GET、POST、PUT、DELETE等

consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回

params: 指定request中必须包含某些参数值是,才让该方法处理

headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求

其中,consumes, produces使用content-typ信息进行过滤信息;headers中可以使用content-type进行过滤和判断。

3. 使用示例

3.1 headers

[html] view plain copy

@RequestMapping(value = "/test", method = RequestMethod.GET, headers="Referer=")

public void testHeaders(@PathVariable String ownerId, @PathVariable String petId) {

// implementation omitted

}

这里的Headers里面可以匹配所有Header里面可以出现的信息,不局限在Referer信息。

示例2

[html] view plain copy

@RequestMapping(value = "/response/ContentType", headers = "Accept=application/json")

public void response2(HttpServletResponse response) throws IOException {

//表示响应的内容区数据的媒体类型为json格式,且编码为utf-8(客户端应该以utf-8解码)

response.setContentType("application/json;charset=utf-8");

//写出响应体内容

String jsonData = "{\"username\":\"zhang\", \"password\":\"123\"}";

response.getWriter().write(jsonData);

}

服务器根据请求头“Accept=application/json”生产json数据。

当你有如下Accept头,将遵守如下规则进行应用:

①Accept:text/html,application/xml,application/json

将按照如下顺序进行produces的匹配 ①text/html ②application/xml ③application/json

②Accept:application/xml;q=0.5,application/json;q=0.9,text/html

将按照如下顺序进行produces的匹配 ①text/html ②application/json ③application/xml

参数为媒体类型的质量因子,越大则优先权越高(从0到1)

③Accept:*/*,text/*,text/html

将按照如下顺序进行produces的匹配 ①text/html ②text/* ③*/*

即匹配规则为:最明确的优先匹配。

Requests部分

Header

解释

示例

Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html

Accept-Charset 浏览器可以接受的字符编码集。 Accept-Charset: iso-8859-5

Accept-Encoding 指定浏览器可以支持的web服务器返回内容压缩编码类型。 Accept-Encoding: compress, gzip

Accept-Language 浏览器可接受的语言 Accept-Language: en,zh

Accept-Ranges 可以请求网页实体的一个或者多个子范围字段 Accept-Ranges: bytes

Authorization HTTP授权的授权证书 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Cache-Control 指定请求和响应遵循的缓存机制 Cache-Control: no-cache

Connection 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) Connection: close

Cookie HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 Cookie: $Version=1; Skin=new;

Content-Length 请求的内容长度 Content-Length: 348

Content-Type 请求的与实体对应的MIME信息 Content-Type: application/x-www-form-urlencoded

Date 请求发送的日期和时间 Date: Tue, 15 Nov 2010 08:12:31 GMT

Expect 请求的特定的服务器行为 Expect: 100-continue

From 发出请求的用户的Email From: user@email.com

Host 指定请求的服务器的域名和端口号 Host:

If-Match 只有请求内容与实体相匹配才有效 If-Match: “737060cd8c284d8af7ad3082f209582d”

If-Modified-Since 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT

If-None-Match 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 If-None-Match: “737060cd8c284d8af7ad3082f209582d”

If-Range 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag If-Range: “737060cd8c284d8af7ad3082f209582d”

If-Unmodified-Since 只在实体在指定时间之后未被修改才请求成功 If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT

Max-Forwards 限制信息通过代理和网关传送的时间 Max-Forwards: 10

Pragma 用来包含实现特定的指令 Pragma: no-cache

Proxy-Authorization 连接到代理的授权证书 Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Range 只请求实体的一部分,指定范围 Range: bytes=500-999

Referer 先前网页的地址,当前请求网页紧随其后,即来路 Referer:

TE 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 TE: trailers,deflate;q=0.5

Upgrade 向服务器指定某种传输协议以便服务器进行转换(如果支持) Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11

User-Agent User-Agent的内容包含发出请求的用户信息 User-Agent: Mozilla/5.0 (Linux; X11)

Via 通知中间网关或代理服务器地址,通信协议 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)

Warning 关于消息实体的警告信息 Warn: 199 Miscellaneous warning

Responses 部分

Header

解释

示例

Accept-Ranges 表明服务器是否支持指定范围请求及哪种类型的分段请求 Accept-Ranges: bytes

Age 从原始服务器到代理缓存形成的估算时间(以秒计,非负) Age: 12

Allow 对某网络资源的有效的请求行为,不允许则返回405 Allow: GET, HEAD

Cache-Control 告诉所有的缓存机制是否可以缓存及哪种类型 Cache-Control: no-cache

Content-Encoding web服务器支持的返回内容压缩编码类型。 Content-Encoding: gzip

Content-Language 响应体的语言 Content-Language: en,zh

Content-Length 响应体的长度 Content-Length: 348

Content-Location 请求资源可替代的备用的另一地址 Content-Location: /index.htm

Content-MD5 返回资源的MD5校验值 Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==

Content-Range 在整个返回体中本部分的字节位置 Content-Range: bytes 21010-47021/47022

Content-Type 返回内容的MIME类型 Content-Type: text/html; charset=utf-8

Date 原始服务器消息发出的时间 Date: Tue, 15 Nov 2010 08:12:31 GMT

ETag 请求变量的实体标签的当前值 ETag: “737060cd8c284d8af7ad3082f209582d”

Expires 响应过期的日期和时间 Expires: Thu, 01 Dec 2010 16:00:00 GMT

Last-Modified 请求资源的最后修改时间 Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT

Location 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 Location:

Pragma 包括实现特定的指令,它可应用到响应链上的任何接收方 Pragma: no-cache

Proxy-Authenticate 它指出认证方案和可应用到代理的该URL上的参数 Proxy-Authenticate: Basic

refresh 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持)

Refresh: 5; url=

Retry-After 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 Retry-After: 120

Server web服务器软件名称 Server: Apache/1.3.27 (Unix) (Red-Hat/Linux)

Set-Cookie 设置Http Cookie Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1

Trailer 指出头域在分块传输编码的尾部存在 Trailer: Max-Forwards

Transfer-Encoding 文件传输编码 Transfer-Encoding:chunked

Vary 告诉下游代理是使用缓存响应还是从原始服务器请求 Vary: *

Via 告知代理客户端响应是通过哪里发送的 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)

Warning 警告实体可能存在的问题 Warning: 199 Miscellaneous warning

WWW-Authenticate 表明客户端请求实体应该使用的授权方案 WWW-Authenticate: Basic

3.2 params的示例

[html] view plain copy

@RequestMapping(value = "/test/{userId}", method = RequestMethod.GET, params="myParam=myValue")

public void findUser(@PathVariable String userId) {

// implementation omitted

}

仅处理请求中包含了名为“myParam”,值为“myValue”的请求,起到了一个过滤的作用。

3.3 consumes/produces

[html] view plain copy

@Controller

@RequestMapping(value = "/users", method = RequestMethod.POST, consumes="application/json", produces="application/json")

@ResponseBody

public ListUser addUser(@RequestBody User userl) {

// implementation omitted

return ListUser users;

}

方法仅处理request Content-Type为“application/json”类型的请求. produces标识==处理request请求中Accept头中包含了"application/json"的请求,同时暗示了返回的内容类型为application/json;

4. 总结

在本文中,首先介绍了Content-Type主要支持的格式内容,然后基于@RequestMapping标注的内容介绍了主要的使用方法,其中,headers, consumes,produces,都是使用Content-Type中使用的各种媒体格式内容,可以基于这个格式内容来进行访问的控制和过滤。

spring mvc 常用注解详解

前言

现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了。不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理。

Spring mvc 介绍

Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发

image.png

spring mvc 常用注解详解

@Controller

在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 等一些注解用以定义请求URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。其标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用@RequestMapping 注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。此外我们还需要将controller注册到spring里

@RequestMapping

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径,作用于方法上,表明该处理器的请求地址=父路径+方法上url+method,其拥有6个属性

1、 value, method;定义处理器访问的具体体质

value: 指定请求的实际地址,指定的地址可以是URI Template 模式;

method: 指定请求的method类型, GET、POST、PUT、DELETE等;

2、consumes,produces 定义处理器内容类型

consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

3、params,headers 定义处理器处理类型

params: 指定request中必须包含某些参数值,才让该方法处理!

headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

@PathVariable

用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。如:

@requestParam

@requestParam主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter("name"),它有三个常用参数:defaultValue = "0", required = false, value = "isApp";defaultValue 表示设置默认值,required 铜过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。

@ResponseBody

作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json等)使用;

@RequestBody

该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。

spring mvc 拦截器配置

preHandle:预处理回调方法,返回值:true表示继续流程,false表示流程中断(如登录检查失败),不会继续续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;

postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。

afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。

spring mvc 静态资源放问配置

image.png

spring mvc 文件上传

前端

后端

spring mvc 工作流程详解

image.png

1、 用户发送请求至前端控制器DispatcherServlet。

2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。

3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

4、 DispatcherServlet调用HandlerAdapter处理器适配器。

5、 HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

6、 Controller执行完成返回ModelAndView。

7、 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

8、 DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

9、 ViewReslover解析后返回具体View。

10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。

11、 DispatcherServlet响应用户。

如果你也对Java架构比如分布式、微服务、源码分析、性能优化、高并发高可用等技术感兴趣可以在手机上面私信我,回复「架构」二字即可免费领取一套价值3880的架构资料哦。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Spring/10013.html