简体   繁体   English

将值注入Jackson转换器/解串器

[英]Inject value into Jackson converter/deserializer

I'm porting a legacy API to Java from a Ruby app that takes full advantage of not being statically typed. 我正在从Ruby应用程序将旧版API移植到Java,该应用程序充分利用了无需静态输入的优势。

In one such situation, the API accepts from the JSON body a user_id that is either a numeric user ID or the string "me" , (which should be converted to the ID of the user making the request before being saved to the database). 在这种情况下,API从JSON主体接受user_id ,它可以是数字用户ID或字符串"me" (在保存到数据库之前,应将其转换为发出请求的用户的ID)。 The method looks like this: 该方法如下所示:

@PUT
@Path("{key}")
@UnitOfWork
public Response getMyObjByKey(@PathParam("key") String key, MyObj myObj) {
    myObjDAO.save(myObj);
}

I have a converter that I want to look something like this: 我有一个转换器,我想看起来像这样:

public class UserIdConverter extends StdConverter<String, Integer> {

    @Inject
    @AuthUser
    protected AuthenticatedUser user;

    public Integer convert(String strUserId) {
        // if strUserId is "me"
        return user.getId();
    }
}

Of course, this doesn't work because of...something to do with the lifecycle that causes user to be null . 当然,由于...与导致usernull的生命周期有关,因此这是行不通的。

My question is: Is there a way for me to access the user object in the converter? 我的问题是:有没有办法让我访问转换器中的用户对象?

To my knowledge its not possible to access the User during the deserialization. 据我所知,在反序列化期间无法访问User Try a custom deserializer and place an indicating int as the id if the String "me" is received. 如果收到String “ me”,请尝试使用自定义反序列化器,并将指示int用作id。 Something like: 就像是:

public class MyObjDeserializer extends JsonDeserializer<MyObj>{

    @Override
    public MyObj deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {

        ObjectCodec oc = jp.getCodec();
        JsonNode node = oc.readTree(jp);

        MyObj myobj = new MyObj();
        myobj.setName(node.get("name").textValue());
        // set other attributes...

        String idString = node.get("id").textValue();
        int id = -1;
        if(!idString.equals("me")) { 
           // another option: use idString.matches("-?\\d+") to check if its a number - https://stackoverflow.com/a/15801999/7015661
            id = Integer.parseInt(idString);
        }

        myobj.setId(id);

        return myobj;
    }

}

Then in your MyObj class place @JsonDeserialize(using = MyObjDeserializer.class) to use your own deserializer. 然后在MyObj类中放置@JsonDeserialize(using = MyObjDeserializer.class)以使用您自己的反序列化器。

Now if the id is "-1", you can get the user's own id in the resource method as follows: 现在,如果id为“ -1”,则可以在resource方法中获取用户自己的id,如下所示:

@PUT
@Path("{key}")
@UnitOfWork
public Response getMyObjByKey(@PathParam("key") String key, MyObj myObj, @Auth Optional<User> user) {

    if(myObj.getId() == -1){
        if(!user.isPresent) // something went very wrong
             throw new RuntimeException("User not authenticated");

       myObj.setId(user.get().getId()); // set the id to its correct value
    }

    myObjDAO.save(myObj);
}

Hope this works :) 希望这有效:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM