request/response 简介
- request 和 response 是对应一次Http通信中的request请求和response返回结果
- Java 的Servlet 协议将其分别封装为 HttpServletRequest 和 HttpServletResponse
- 从中可以获得原始 Http 请求的详细信息,也可控制response操作
- 屏蔽了直接操作底层 Http 的复杂性
方法一
在 Controller 层获取
直接在 controller 的方法参数中加入HttpServletRequest 和 HttpServletResponse 对象参数
@RestController
public class AppController {
@RequestMapping("/test")
public String getSth(HttpServletRequest request, HttpServletResponse response) {
......
}
}
原理
- spring 会使用反射将这两个属性从上下文环境中注入到对应方法中(使用反射技术对相应的参数做到参数注入)
- 简单理解:读参数->搜索上下文中bean->若匹配上->注入
- 详细代码
第一段
//step1-invokeForRequest()
public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
//获取 方法参数
Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
if(this.logger.isTraceEnabled()) {
StringBuilder returnValue = new StringBuilder("Invoking [");
returnValue.append(this.getBeanType().getSimpleName()).append(".");
returnValue.append(this.getMethod().getName()).append("] method with arguments ");
returnValue.append(Arrays.asList(args));
this.logger.trace(returnValue.toString());
}
Object returnValue1 = this.doInvoke(args);
if(this.logger.isTraceEnabled()) {
this.logger.trace("Method [" + this.getMethod().getName() + "] returned [" + returnValue1 + "]");
}
return returnValue1;
}
第二段
/**
* Get the method argument values for the current request.
*/
private Object[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
MethodParameter[] parameters = getMethodParameters();
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
GenericTypeResolver.resolveParameterType(parameter, getBean().getClass());
args[i] = resolveProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
if (this.argumentResolvers.supportsParameter(parameter)) {
try {
args[i] = this.argumentResolvers.resolveArgument(
parameter, mavContainer, request, this.dataBinderFactory);
continue;
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug(getArgumentResolutionErrorMessage("Error resolving argument", i), ex);
}
throw ex;
}
}
if (args[i] == null) {
String msg = getArgumentResolutionErrorMessage("No suitable resolver for argument", i);
throw new IllegalStateException(msg);
}
}
return args;
}
第三段
/**
* Attempt to resolve a method parameter from the list of provided argument values.
*/
private Object resolveProvidedArgument(MethodParameter parameter, Object... providedArgs) {
if (providedArgs == null) {
return null;
}
for (Object providedArg : providedArgs) {
if (parameter.getParameterType().isInstance(providedArg)) {
return providedArg;
}
}
return null;
}
如果参数类型和提供的参数类型可以匹配,则直接返回。至此,我们分析完了从源码级别分析了,如何做的参数注入。
参考:https://www.jianshu.com/p/0ba4c65e493c
方法二
在非Controller层获得
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
HttpServletResponse response = ((ServletWebRequest)RequestContextHolder.getRequestAttributes()).getResponse();
ServletContext context = ContextLoader.getCurrentWebApplicationContext().getServletContext();
网友评论