如何在@MultipartForm注解的POJO中使用UUID类型表单参数
问题原因
你碰到的表现差异是因为Resteasy对两类参数的转换逻辑完全独立:
@PathParam、@QueryParam这类参数注解用的是ParamConverter体系,Resteasy默认内置了String转UUID的ParamConverter实现,所以可以直接转换。- Multipart表单的每个part是用
MessageBodyReader体系来反序列化,Resteasy默认没有提供text/plain类型到UUID的MessageBodyReader,所以会触发你碰到的报错。
解决方案
你不需要从零实现复杂的逻辑,两种方案可选:
方案1:注册全局UUID MessageBodyReader(推荐)
只需要实现一个极简的MessageBodyReader并注册到Resteasy上下文,所有text/plain类型的UUID参数都可以自动转换,不需要修改现有DTO代码:
import org.jboss.resteasy.spi.BadRequestException; import javax.ws.rs.Consumes; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyReader; import javax.ws.rs.ext.Provider; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.Scanner; import java.util.UUID; @Provider @Consumes(MediaType.TEXT_PLAIN) public class UuidMessageBodyReader implements MessageBodyReader<UUID> { @Override public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return UUID.class.isAssignableFrom(type); } @Override public UUID readFrom(Class<UUID> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { try (Scanner scanner = new Scanner(entityStream, StandardCharsets.UTF_8.name())) { String uuidContent = scanner.useDelimiter("\\A").next().trim(); return UUID.fromString(uuidContent); } catch (IllegalArgumentException e) { throw new BadRequestException("非法的UUID格式: " + e.getMessage(), e); } } }
注册完成后你原有DTO里的UUID字段不需要做任何修改即可正常使用。
方案2:DTO层做轻量转换(适合单场景使用)
如果只需要在这一个DTO里用到UUID转换,不想新增全局配置,可以直接把字段设为String类型,新增一个转换方法即可:
public class MultipartBodyRequestDto { // 其他属性... @NotNull @FormParam("id") @PartType(MediaType.TEXT_PLAIN) public String id; // 业务逻辑调用该方法获取UUID即可 public UUID getUuidId() { return UUID.fromString(id.trim()); } }
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

