java – 使用Dropwizard实现强params

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

反正有没有这样做?

编辑:

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

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

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

最佳答案 第二次尝试在编辑问题后回答此问题.

您可以构建您的JSON bean并忽略未知值,例如带有Jackson注释’JsonIgnoreProperties’的ID.

您有以下资源:

@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

Parameters

The annotated methods on a resource class can accept parameters which
are mapped to from aspects of the incoming request. The *Param
annotations determine which part of the request the data is mapped,
and the parameter type determines how the data is mapped.

For example:

06004

method as a String.
A @QueryParam(“count”)-annotated IntParam parameter takes the first count value from the request’s query string and passes it as a
String to IntParam‘s constructor. IntParam (and all other
io.dropwizard.jersey.params.* classes) parses the string as an
Integer, returning a 400 Bad Request if the value is malformed.
A @FormParam(“name”)-annotated Set parameter takes all the name values from a posted form and passes them to the method as a set
of strings.
A *Param–annotated NonEmptyStringParam will interpret empty strings as absent strings, which is useful in cases where the endpoint
treats empty strings and absent strings as interchangeable.

What’s noteworthy here is that you can actually encapsulate the vast
majority of your validation logic using specialized parameter objects.
See AbstractParam for details.

您的资源应该是这样的:

@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,那么您可以检查不允许包含十六进制字符串任何’Z’).

点赞