【问题标题】:Spring Java Rest Handle invalid type at deserializationSpring Java Rest Handle 在反序列化时处理无效类型
【发布时间】:2019-12-27 19:33:56
【问题描述】:

我正在开发用于注册用户的 java REST API。我正在尝试检查发送到 POST 的用户是否所有字段都有效,以便可以将其保存到数据库,但如果其中一个字段的类型无效,我无法找到处理错误的方法。

我的模型 User.java

public class User{

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@Column
private String description;
@Column
private String date_joined;
@Column
private double age;
//setters and getters
}

用户资源方式:

@POST
@Consumes("application/json")
@Produces("application/json")
public Response postUser(User User)
{  
    //validate User fields and save to db
    // if valid return following, else send Bad Request
    return Response.status(Response.Status.CREATED).entity(User).build();
}

我正在使用 ajax 通过以下方式发送数据:

{
"date_joined":"27/12/19",
"description":"Currently looking for job",
"age":30
}

这个例子很好用,但我想验证发送的数据是无效类型,例如:

{
"date_joined":"27/12/19",
"description":"Currently looking for job",
"age": "thirty"
}

这会产生以下错误

org.codehaus.jackson.map.JsonMappingException: Can not construct instance of double from String value 'thirty': not a valid Double value

有没有办法捕捉这些错误?因此,稍后我可以向用户发送一条消息,说明他们发送了无效数据

【问题讨论】:

  • 搜索ExceptionHandler@ControllerAdvice,也可能搜索@Valid。如果这与 Spring 相关,请添加 spring/spring-boot 标签
  • 我会在客户端用javascript做这个验证以节省服务器的工作量
  • 阅读这个link,它会对你有所帮助。

标签: java json rest jackson


【解决方案1】:

如果遇到 JsonMappingException,是否可以捕获异常并返回错误消息?

try {
   return Response.status(Response.Status.CREATED).entity(User).build();
} catch (JsonMappingException e) {
   // Return a 4xx statuscode to indicate a client error and some json containing e.getMessage()
}

如果有用请告诉我!谢谢!

:)

【讨论】:

    【解决方案2】:

    是的。有一种方法。我们可以编写自己的自定义反序列化器。

    我为电子邮件验证编写了反序列化器/验证器。

    import org.apache.commons.lang.StringUtils;
    
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.ObjectCodec;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.JsonDeserializer;
    import com.fasterxml.jackson.databind.JsonNode;
    
    public class EmailValidator2 extends JsonDeserializer<String> {
    
        @Override
        public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
                throws IOException, JsonProcessingException {
    
            System.out.println("Intercepting deserlization to validate email....");
    
            ObjectCodec objectCodec = jsonParser.getCodec();
    
            JsonNode jsonNode = objectCodec.readTree(jsonParser);
    
            String value = jsonNode.asText();
    
    
    
            if (StringUtils.isNotBlank(value) && (!org.apache.commons.validator.routines.EmailValidator.getInstance().isValid(value))) {
                throw new RuntimeException("Email address is invalid");
            }
    
            return jsonNode.asText();
        }
    }
    
    
    
    
    
    import org.springframework.stereotype.Service;    
    import com.fasterxml.jackson.databind.module.SimpleModule;
    @Service
    public class CustomSerializerAndDeserializerRegistry extends SimpleModule {
    
        public CustomSerializerAndDeserializerRegistry() {
            this.addDeserializer(String.class, new EmailValidator2());
    
        }
    
    }
    
    
    public class User{
    
        private String email;
    
        public String getEmail() {
            return email;
        }
    
        @JsonDeserialize(using = EmailValidator2.class)
        @ExceptionHandler
        public void setEmail(String email) {
            this.email = email;
        }
    }
    

    如果需要,我可以提供更多帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多