仅仅适用在controller方法上。当Spring接收到HTTP请求时,会寻找一个合适的方法来处理该请求。如果该方法参数上标注了@RequestMapping或@Get、@Post等注解,Spring就会将HttpServletRequest对象注入到该参数中。
@RestController
public class Controller {
@RequestMapping("/test")
public String test(HttpServletRequest request,HttpServletResponse response) {
return "success";
}
}
适用于所有的bean
@Autowired
private HttpServletRequest request;
@Autowired
private HttpServletResponse response;
@RequestMapping("/test")
public String test() {
Enumeration<String> headerNames = request.getHeaderNames();
response.setHeader("header","header_value");
return "success";
}
通过调试可以看到,注入的Reques是一个代理类,而这个被代理的目标由RequestObjectFactory.getObject() 获取
我们再看一下RequestObjectFactory.getObject() 的方法,最终还是走到了RequestContextHolder.getRequestAttributes()方法
private static class RequestObjectFactory implements ObjectFactory<ServletRequest>, Serializable {
@Override
public ServletRequest getObject() {
return currentRequestAttributes().getRequest();
}
@Override
public String toString() {
return "Current HttpServletRequest";
}
}
private static ServletRequestAttributes currentRequestAttributes() {
RequestAttributes requestAttr = RequestContextHolder.currentRequestAttributes();
if (!(requestAttr instanceof ServletRequestAttributes)) {
throw new IllegalStateException("Current request is not a servlet request");
}
return (ServletRequestAttributes) requestAttr;
}
适用于所有的方法,spring会通过RequestContextHolder.setRequestAttributes方法将RequestAttributes设置到ThreadLocal中。
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attr.getRequest();
HttpServletResponse response = attr.getResponse();