在Spring Boot中,你可以以多种方式获取当前请求的HttpServletRequest和HttpServletResponse对象。以下是几种常见的写法示例:
1. 在方法参数中声明
最常见和推荐的方式是在控制器方法的参数中直接声明HttpServletRequest和HttpServletResponse对象。Spring Boot会自动将它们注入到方法中。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
public class MyController {
@GetMapping("/hello1")
public String hello1(HttpServletRequest request, HttpServletResponse response) {
// 使用 request 对象
String method = request.getMethod();
String uri = request.getRequestURI();
// 使用 response 对象
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
return "Hello 1, Spring Boot!";
}
}
2. 使用 @RequestMappingHandlerAdapter
你可以通过注入RequestMappingHandlerAdapter来手动获取HttpServletRequest和HttpServletResponse对象。这种方式比较灵活,但相对较少使用。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
public class MyController {
@Autowired
private RequestMappingHandlerAdapter handlerAdapter;
@GetMapping("/hello2")
public String hello2(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 通过 handlerAdapter 获取 request 和 response 对象
HttpServletRequest req = (HttpServletRequest) handlerAdapter.getWebBindingInitializer().getBindingContext().getModel().get("org.springframework.web.servlet.HandlerMapping.uriTemplateVariables");
// 使用 request 对象
String method = req.getMethod();
String uri = req.getRequestURI();
// 使用 response 对象
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
return "Hello 2, Spring Boot!";
}
}
3. 使用 ThreadLocal
另一种方式是使用ThreadLocal来存储当前的HttpServletRequest和HttpServletResponse对象,然后在需要时从ThreadLocal中获取。
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
public class MyController {
@GetMapping("/hello3")
public String hello3() {
// 从 RequestContextHolder 中获取 ServletRequestAttributes
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// 获取 HttpServletRequest 对象
HttpServletRequest request = attributes.getRequest();
// 获取 HttpServletResponse 对象
HttpServletResponse response = attributes.getResponse();
// 使用 request 对象
String method = request.getMethod();
String uri = request.getRequestURI();
// 使用 response 对象
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
return "Hello 3, Spring Boot!";
}
}
总结
以上是在Spring Boot中常见的几种方式获取当前请求的HttpServletRequest和HttpServletResponse对象。推荐使用第一种方式,即在方法参数中声明,因为它简单直观且符合Spring Boot的最佳实践。