我正在寻找创建自定义注释以从HttpServletRequest
读取标头集的方式
假设我有以下代码:
@RestController
public class ExampleController {
@PostMapping(path = "/path")
public void method(@RequestHeader("session-session_id") long sessionId,
@RequestHeader("session-user_id") long userId,
@RequestHeader("session-user_name") String userName) {
UserInfo userInfo = UserInfo.of(sessionId, userId, userName);
//service.handle(userInfo);
}
public static final class UserInfo {
private final long sessionId;
private final long userId;
private final String userName;
private UserInfo(long sessionId, long userId, String userName) {
this.sessionId = sessionId;
this.userId = userId;
this.userName = userName;
}
public static UserInfo of(long sessionId, long userId, String userName) {
return new UserInfo(sessionId, userId, userName);
}
}
}
如您所见,请求标头中包含用户信息。所有用户信息标题都将以“ session-”前缀开头。在实际系统上,我将有3个以上的字段。它们将用于许多请求。
因此,我必须将具有完整用户信息的对象转移到服务级别。为每个UserInfo
之类的请求创建此UserInfo.of(sessionId, userId, userName)
看起来很多余而且很丑陋。那就是问题所在。
我至少知道另外两种解决方法:
@PostMapping(path = "/path")
public void method(HttpServletRequest request) {
UserInfo userInfo = UserInfo.of(request);
}
public static UserInfo of(HttpServletRequest request) {
//request.getHeader("header name");
}
或
@PostMapping(path = "/path")
public void method(@RequestHeader Map<String, String> request) {
UserInfo userInfo = UserInfo.of(request);
}
public static UserInfo of(Map<String, String> request) {
//map.get("header name");
}
但事实并非如此。我正在寻找创建UserInfo
的方法,就像spring那样:
@PostMapping(path = "/path")
public void method(@UserInfo UserInfo request) {
UserInfo userInfo = UserInfo.of(request);
}
您能帮我解决一个问题吗?或至少提供指向文档的链接,其中描述了@RequestHeader
在Spring内部如何实现
答案 0 :(得分:1)
您需要定义自定义HandlerMethodArgumentResolver
:
public class UserInfoResolver implements HandlerMethodArgumentResolver {
private static final String sessionIdParam = "session-session_id";
private static final String userIdParam = "session-user_id";
private static final String userNameParam = "session-user_name";
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(UserInfo.class);
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
// There are no null-checks here for simplicity,
// so don't forget to add them in production code
return UserInfo(
Long.parseLong(webRequest.getHeader(sessionIdParam)),
Long.parseLong(webRequest.getHeader(userIdParam)),
webRequest.getHeader(userNameParam)
);
}
}
然后让Spring在您的Web配置类中意识到该参数解析器:
@Configuration
public class WebApiConfiguration extends WebMvcConfigurationSupport {
...
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new UserInfoResolver());
}
...
}
最后,您可以通过以下方式使用它:
@PostMapping(path = "/path")
public void method(UserInfo userInfo) {
//service.handle(userInfo);
}