我想实现一个自定义的MethodArgumentResolver,以便从请求标头和正文中组合我自己的消息。
我已经做了一些工作,将请求作为字节数组读取,获取由请求标头'type'的值指定的相应解析器,将字节数组解析为特定对象,然后返回。 / p>
这是我的解析器,我已经正确配置了它。
public class DeviceManagerRequestBodyResolver extends AbstractMessageReaderArgumentResolver {
protected DeviceManagerRequestBodyResolver(List<HttpMessageReader<?>> readers) {
super(readers);
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(DMRequestBody.class);
}
@Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext, ServerWebExchange exchange) {
ServerHttpRequest request = exchange.getRequest();
String type = request.getHeaders().getFirst("type");
if (StringUtils.isEmpty(type)) {
return Mono.error(new IllegalArgumentException("Type is null."));
}
DMRequestBody annotation =
parameter.getParameterAnnotation(DMRequestBody.class);
Assert.state(annotation != null, "No DMRequestBody annotation.");
// Here I'm using the value of header 'type' to get the corresponding parser to parse the request body as the specofied object.
// All parsers have been loaded into the ParserSupplier at the bootstrap phase.
return Mono.just(ParserSupplier.getParser(Integer.valueOf(type)).parse(request));
}
}
ParserSupplier.getParser(Integer.valueOf(type))
现在将解析为该解析器:
public class AuthorizationRequestBodyParser implements DmRequestBodyParser<AuthorizationMessage> {
@Override
public Mono<AuthorizationMessage> parse(ServerHttpRequest request) {
return readBody(request).flatMap(this::parse0);
}
@SuppressWarnings("unchecked")
private Mono<byte[]> readBody(ServerHttpRequest request) {
DecoderHttpMessageReader<byte[]> httpMessageReader = new DecoderHttpMessageReader(new ByteArrayDecoder());
ResolvableType resolvableType = ResolvableType.forClass(byte[].class);
return httpMessageReader.readMono(resolvableType, request, Collections.emptyMap());
}
private Mono<AuthorizationMessage> parse0(byte[] bytes) {
try {
JsonNode jsonNode = new ObjectMapper().readTree(bytes);
AuthorizationMessage parsed = new AuthorizationMessage();
parsed.setToken(jsonNode.get("token").asText());
parsed.setUuid(jsonNode.get("uuid").asText());
return Mono.just(parsed);
} catch (IOException e) {
e.printStackTrace();
}
return Mono.empty();
}
}
问题是,一切正常,但AuthorizationRequestBodyParser#parse(ServerHttpRequest request)
不能正常工作,它导致了以下异常:
java.lang.IllegalStateException: argument type mismatch
Controller [com.baidu.iot.devicecloud.devicemanager.controller.PostController]
Method [public reactor.core.publisher.Mono<com.baidu.iot.devicecloud.devicemanager.resolver.bean.AuthorizationMessage> com.baidu.iot.devicecloud.devicemanager.controller.PostController.auth(com.baidu.iot.devicecloud.devicemanager.resolver.bean.AuthorizationMessage)] with argument values:
[0] [type=reactor.core.publisher.MonoFlatMap] [value=MonoFlatMap]
我不知道如何用Publisher的东西返回正确的类型。有人可以指出我吗?感谢任何回应。