使用Dropwizard实现强大的参数

时间:2016-08-25 11:43:25

标签: java jersey jersey-2.0 dropwizard

我想以一种只接受特定请求字段的方式验证请求,并使用Dropwizard和Jersey为所有未接受的字段返回400.

有没有这样做?

编辑:

示例 - 假设请求包含以下JSON: { 名称:测试, 年龄:30岁, id:52 }

并且服务器在请求中不接受字段ID。

预期:服务器应返回400,表明请求中不允许使用字段ID。

1 个答案:

答案 0 :(得分:1)

第二次尝试在编辑问题后回答此问题。

您可以构建您的JSON bean并忽略未知值,例如ID with Jackson annotation' JsonIgnoreProperties'。

您有以下资源:

@Post
public Response hello(Person person) {
        return Response
                .status(Status.OK)
                .entity(String.format("Hello %s. We know that you are %s years old, but we do not know if you send more informations to us like id or sth. else.", person.getName(), person.getAge()))
                .build();
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {
    private final String name;
    private final int age;

    @JsonCreator
    public Person(@JsonProperty String name,@JsonProperty int age) {
        this.name= name;
        this.age= age;
    }

    @JsonProperty
    public String getName() {
        return name;
    }

    @JsonProperty
    public String getage() {
        return age;
    }
}

旧答案:

为什么不验证它们?下面是3个如何做到这一点的例子。

选项1:

@Path("smooth")
@GET
public Response smooth(
    @DefaultValue("2") @QueryParam("step") int step,
    @DefaultValue("true") @QueryParam("min-m") boolean hasMin,
    @DefaultValue("true") @QueryParam("max-m") boolean hasMax,
    @DefaultValue("true") @QueryParam("last-m") boolean hasLast,
    @DefaultValue("blue") @QueryParam("min-color") ColorParam minColor,
    @DefaultValue("green") @QueryParam("max-color") ColorParam maxColor,
    @DefaultValue("red") @QueryParam("last-color") ColorParam lastColor) {
    validateMaxColor(maxColor);
}

public void validateMaxColor(ColorParam  maxColorParam){
    if(!maxColorParam.isInRange()){
        throw new WebapplicationException("maxColorParam out of range");
    }
}

选项2:使用特定的参数类

@Path("smooth")
@GET
public Response smooth(
    @DefaultValue("2") @QueryParam("step") int step,
    @DefaultValue("true") @QueryParam("min-m") boolean hasMin,
    @DefaultValue("true") @QueryParam("max-m") boolean hasMax,
    @DefaultValue("true") @QueryParam("last-m") boolean hasLast,
    @DefaultValue("blue") @QueryParam("min-color") ColorParam minColor,
    @DefaultValue("green") @QueryParam("max-color") ColorParam maxColor,
    @DefaultValue("red") @QueryParam("last-color") ColorParam lastColor) {
    ....
}


public class ColorParam extends Color {

    public ColorParam(String color) {
        super(getRGB(color));
        if(getRGB(color).isGreen()){
            throw new ParseException("ohh nooooo ... green is not allowed here");
        }
    }

    private static int getRGB(String s) {
        if (s.charAt(0) == '#') {
            try {
                Color c = Color.decode("0x" + s.substring(1));
                return c.getRGB();
            } catch (NumberFormatException e) {
                throw new WebApplicationException(400);
            }
        } else {
            try {
                Field f = Color.class.getField(s);
                return ((Color)f.get(null)).getRGB();
            } catch (Exception e) {
                throw new WebApplicationException(400);
            }
        }
    }
}

使用String构造函数非常重要。

选项3:对于Dropwizard用户;使用AbstractParam并验证传入的字符串

请参阅Dropwizard documentation about Params

  

参数

     

资源类上带注释的方法可以接受参数   从传入请求的方面映射到。 * Param   注释确定数据映射的请求的哪个部分,   参数类型决定了数据的映射方式。

     

例如:

A @PathParam("user")-annotated String takes the raw value from the user variable in the matched URI template and passes it into the
     

方法作为String。       @QueryParam(" count") - 带注释的IntParam参数从请求的查询字符串中获取第一个计数值并将其作为   字符串到IntParam的构造函数。 IntParam(和所有其他   io.dropwizard.jersey.params。* classes)将字符串解析为   整数,如果值格式错误,则返回400 Bad Request。       @FormParam(" name") - 带注释的Set参数从发布的表单中获取所有名称值,并将它们作为集合传递给方法   字符串。       A * Param-annotated NonEmptyStringParam会将空字符串解释为缺少字符串,这在端点的情况下很有用   将空字符串和缺少字符串视为可互换的。

     

这里值得注意的是,你实际上可以封装庞大的数据   大多数验证逻辑使用专门的参数对象。   有关详细信息,请参阅AbstractParam。

您的资源应该是这样的:

@Path("long")
@GET
public Response long(
    @QueryParam("long") LongParam longValue) {
    //here your longValue is in wanted Range
    //doubles or floats will return a HTTP 400
}


/**
 * A parameter encapsulating long values. All non-decimal values will return a {@code 400 Bad
 * Request} response.
 */
public class LongParam extends AbstractParam<Long> {
    public LongParam(String input) {
        super(input);
    }

    @Override
    protected String errorMessage(Exception e) {
        return "Parameter is not a number.";
    }

    @Override
    protected Long parse(String input) {
        return Long.valueOf(input);
    }
}

使用此功能,您可以轻松验证传入的字符串并在无法解析字符串或无效范围时抛出异常(例如,如果您想要HexValue并且您的字符串是#ZZ8000,那么您可以检查该字符串不是允许包含任何&#39; Z&#39;)。