Jax RS-具有空值的PATCH方法行为

我有一个REST Web应用程序Java EE8应用程序。

假设我有这个:

PATCH
{
    "mobile": "+3494441122" // update only mobile
}

我想创建一个资源更新方法,该方法仅更新请求的属性,因此我使用PATCH方法。

JSON请求示例:

// chat-page.component.ts
// ...
@Output
onChat = new EventEmitter<string>();

/* Triggered when a user submit a message */
onSubmit(message: string) { onChat.emit(message) }

// ...

仅修改移动字段,而保留其他字段不变。

问题

如何使用PATCH方法处理 null 值?

我应该考虑将该字段转为空白还是忽略它?

我担心第一种情况,因为我不知道是否有任何方法可以识别差异,因为如果我不通过该字段或指定空值,那么Person的property字段将为 null 值。

有任何提示吗?

qwer21212009 回答:Jax RS-具有空值的PATCH方法行为

这不是最好的解决方案,但它应该可以帮助您。

import java.util.Iterator;

import org.json.JSONObject;

public class Test{
    public static void main(String[] args) {

        /** We will pass the Body of the request through a series of conditions listed below.
        1. Check if the key exists,2. Check if the value is not null,3. Check if the value is not "null"
        **/

        JSONObject requestBody = new JSONObject("{\"mobile\":\"+3494441122\",\"email\":\"email\",\"name\":\"null\",\"surname\":null}");

        JSONObject updateObject = new JSONObject();

        Iterator<String> ittr = requestBody.keys();
        while(ittr.hasNext()) {

            String key = ittr.next();
            if(requestBody.has(key)) {
                if(!requestBody.isNull(key)) {
                    String value = requestBody.get(key).toString();
                    if(!value.equalsIgnoreCase("null")) {
                        //If these cases are matched,only then allow the value to be updated.
                        updateObject.put(key,value);
                    }
                }

            }

        }
        System.out.println(updateObject);

    }
}

输出

{"mobile":"+3494441122","email":"email"}

您也可以使用GSON库来这样做,这是一种更好的方法,但与以前的方法不同,它会接受“空”值。

主类

import org.json.JSONObject;

public class Test{
    public static void main(String[] args) {

        JSONObject requestBody = new JSONObject("{\"mobile\":\"+3494441122\",\"surname\":null}");

        PersonRequest personRequest = new PersonRequest().fromJson(requestBody.toString() );
        System.out.println(personRequest.toJson());

    }
}

POJO类

import org.json.JSONObject;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class PersonRequest {
    String email;
    String name;
    String surname;
    String mobile;
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSurname() {
        return surname;
    }
    public void setSurname(String surname) {
        this.surname = surname;
    }
    public String getMobile() {
        return mobile;
    }
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public JSONObject toJson() {
        return new JSONObject(new Gson().toJson(this));
    }

    public  PersonRequest fromJson(String json) {
        Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .create(); 

        return gson.fromJson(json,this.getClass());
    }
}

输出:

{"name":"null","mobile":"+3494441122","email":"email"}

区别只是现在名称具有空字符串。

,

我将继续发布基于Java 8的Optional的解决方案。首先,应该解决的问题是在HTTP PATCH情况下将JSON undefined值映射到Java:Java中的null不足,因为它可能对应于null或{{ 1}} JSON值。在PATCH的情况下,我们希望以不同的方式处理这两个JSON值:undefined实际上设置为Java nullnull将该值保持不变。

我在WildFly 15上进行了测试,因此我想它可能会在WildFly服务器以及其他使用RestEasy(例如Quarkus)的服务器上运行-但我尚未测试!我浏览了JAX-RS 2.1规范,但没有发现对undefined的明确提及以及应如何处理,因此请注意,这可能是仅限RestEasy的解决方案!更糟糕的是,它可能与处理JSON的确切工具有关,因此可以工作,例如杰克逊,但不使用JSON-B。

还有一个关于正确样式和按预期使用Optional的问题;请参阅问题注释中的链接。尽管我必须承认这不是我通常构造通用Java Bean的方式,但我相信这种解决方案对于这种特殊情况已经足够了。我过去尝试过的另一种解决方案是在每个普通变量(例如Optional)旁边保留一个boolean变量。我认为此解决方案和其他解决方案最终比此处概述的解决方案更加麻烦。

DTO:

nameIsSet

然后发送以下对象:

class PersonPatchRequest {
     Optional<String> email;
     Optional<String> name;
     Optional<String> surname;
     Optional<String> mobile;

     .. getter and setter for the Optional,e.g.:


    public Optional<String> getName() {
        return name;
    }

    public void setName(Optional<String> name) {
        this.name = name;
    }
}

例如为:

{
    "name": "Bob","surname": null
}

将使用Java生成以下数据:

curl -X PATCH http://...  -H "Accepts: application/json" -H "Content-Type: application/json"    \
     -d "{\"name\":\"Bob\",\"surname\":null}"

PersonPatchRequest { email: null,name: Optional["Bob"] surname: Optional.empty mobile: null } 值是客户端发送的真实Optional.emptynull值是null

本文链接:https://www.f2er.com/3104082.html

大家都在问