如何在请求正文中将Serializable对象的Map作为JSON传递

时间:2019-05-20 12:37:13

标签: java json rest spring-boot postman

模型类如下所示:MailFilterCondition具有EmailCondition的映射,其中Filter是一个类,而MailAttributes和Operator是枚举:

public class EmailCondition implements Serializable {
private static final long serialVersionUID = -5429392022485346125L;
private Filter.MailAttributes key;
private Filter.Operator op;
private String value;

public Filter.MailAttributes getKey() {
    return key;
}

public void setKey(Filter.MailAttributes key) {
    this.key = key;
}

public Operator getOp() {
    return op;
}

public void setOp(Operator op) {
    this.op = op;
}

public String getValue() {
    return value;
}

public void setValue(String value) {
    this.value = value;
}

@Override
public String toString() {
    return "EmailCondition [key=" + key + ", op=" + op + ", value=" + value + "]";
}
}

public class MailFilterCondition implements Serializable {
private static final long serialVersionUID = -2691329267596354267L;
private int automationId;
private Map<String, EmailCondition> emailConditionMap;
private String filterString;

public int getAutomationId() {
    return automationId;
}

public void setAutomationId(int automationId) {
    this.automationId = automationId;
}

public Map<String, EmailCondition> getEmailConditions() {
    return emailConditionMap;
}

public void setEmailConditions(Map<String, EmailCondition> emailConditionMap) {
    this.emailConditionMap = emailConditionMap;
}

public String getFilterString() {
    return filterString;
}

public void setFilterString(String filterString) {
    this.filterString = filterString;
}

@Override
public String toString() {
    return "MailFilterCondition [automationId=" + automationId + ", emailConditions=" + emailConditionMap
            + ", filterString=" + filterString + "]";
}
}

控制器:

@PostMapping(value = "/email")
public void createAutomationFilter(@RequestParam(value="automation_id") int automationId, @RequestBody MailFilterCondition filterData) {

    System.out.println(filterData);
}

请求正文:

{
"automationId": 123,
"filterString": "(c1_and_c2)_or_(c1_and_c3)",
"emailConditionMap": 
{
    "c1":{
        "key": "from",
        "op": "contains",
        "value": "jhon"
    },

    "c2":{
        "key": "from1",
        "op": "starts",
        "value": "ron"
    },

    "c3":{
        "key": "from",
        "op": "contains",
        "value": "payment"
    }
}
}

过滤器枚举:

public class Filter {
public enum Operator {
    contains("contains"), starts("starts"), ends("ends"), gt("gt"), gteq("gteq"), lt("lt"), lteq("lteq"), eq("eq"),
    inlist("inlist"), pattern("pattern");
    private final String operator;

    private Operator(String opt) {
        this.operator = opt;
    }

    public String getValue() {
        return this.operator;
    }
}

public enum MailAttributes {
    from("from"), to("to"), subject("subject"), body("body"), received_time("received_time");
    private final String attribute;

    private MailAttributes(String attribute) {
        this.attribute = attribute;
    }

    public String getValue() {
        return this.attribute;
    }
}

public enum LogicOperator {
    AND("_and_"), OR("_or_");
    private final String operator;

    private LogicOperator(String opt) {
        this.operator = opt;
    }

    public String getValue() {
        return this.operator;
    }
}
}

输出:

MailFilterCondition [automationId=123, emailConditions=null, filterString=(c1_and_c2)_or_(c1_and_c3)]

虽然在json中传递键值对,但map属性的值为null。我尝试了所有方法,但每次emailConditions都输出null。

3 个答案:

答案 0 :(得分:0)

您在课程中是否有适当的吸气剂/吸气剂? 我不确定Filter类是什么,但是将这两个字段更改为String可以正常工作。所以问题可能在那里。

答案 1 :(得分:0)

您需要使用Jackson编组。在发送到请求主体之前,它将自动转换对象。 杰克逊使用吸气剂和吸气剂,所以您的对象必须有它们。

答案 2 :(得分:0)

@PostMapping(value = "/email")
public void createAutomationFilter(@RequestParam(value="automation_id") int automationId, @RequestBody MailFilterCondition filterData) {

    System.out.println(filterData);
}

createAutomationFilter方法中,您正在传递@RequestParam(value="automation_id") int automationId作为参数,这是不正确的,因为您在Postman中的请求正文中发送了所有参数。因此,您必须将所有参数映射到一个Model类(即MailFilterCondition)中,并使用 @RequestBody注解。请参阅以下控制器。

控制器:

import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/mail")
public class TestController {

    @PostMapping(value = "/create", produces = { "application/json" })
    public void createAutomationFilter(@RequestBody final MailFilterCondition emailConditionMap,
            final HttpServletRequest request) {
      System.out.println(emailConditionMap);

    }
}

在此模型MailFilterCondition中,您对emailConditionMap的设置和获取不正确。

public Map<String, EmailCondition> getEmailConditions() {
    return emailConditionMap;
}

public void setEmailConditions(Map<String, EmailCondition> emailConditionMap) {
    this.emailConditionMap = emailConditionMap;
}

使用(Spring用于映射与字段设置程序名称完全相同的字段)来更新您的setter和getter。

   public Map<String, EmailCondition> getEmailConditionMap() {
    return emailConditionMap;
     }

   public void setEmailConditionMap(Map<String, EmailCondition> 
     emailConditionMap) {
    this.emailConditionMap = emailConditionMap;
    }

型号:MailFilterCondition

import java.io.Serializable;
import java.util.Map;

public class MailFilterCondition implements Serializable {
    private static final long serialVersionUID = -2691329267596354267L;
    private int automationId;
    private Map<String, EmailCondition> emailConditionMap;
    private String filterString;

    public int getAutomationId() {
        return automationId;
    }

    public void setAutomationId(int automationId) {
        this.automationId = automationId;
    }

    public Map<String, EmailCondition> getEmailConditionMap() {
        return emailConditionMap;
    }

    public void setEmailConditionMap(Map<String, EmailCondition> emailConditionMap) {
        this.emailConditionMap = emailConditionMap;
    }

    public String getFilterString() {
        return filterString;
    }

    public void setFilterString(String filterString) {
        this.filterString = filterString;
    }

    @Override
    public String toString() {
        return "MailFilterCondition [automationId=" + automationId + ", emailConditions=" + emailConditionMap
                + ", filterString=" + filterString + "]";
    }
}

在模型EmailCondition中,我将String作为参数传递给

public void setKey(String key) {
    this.key = Filter.MailAttributes.valueOf(key);
}

public void setOp(String op) {
    this.op = Filter.Operator.valueOf(op);
}

正如您在请求正文中看到的那样,您正在将keyop的值传递为String, 这些值不是任何自定义java类。在运行时,Spring无法确定您传递的类型

public void setKey(Filter.MailAttributes key) {
    this.key = key;
}

public void setOp(Operator op) {
    this.op = op;
}

据我所知,您还可以使用@InitBinder批注来绑定这些字段。

型号:EmailCondition

import java.io.Serializable;

import com.spring.web.controller.Filter.MailAttributes;
import com.spring.web.controller.Filter.Operator;

public class EmailCondition implements Serializable {

    private static final long serialVersionUID = -5429392022485346125L;
    private Filter.MailAttributes key;
    private Filter.Operator op;
    private String value;

    public void setKey(String key) {
        this.key = Filter.MailAttributes.valueOf(key);
    }

    public void setOp(String op) {
        this.op = Filter.Operator.valueOf(op);
    }

    public void setValue(String value) {
        this.value = value;
    }

    public MailAttributes getKey() {
        return key;
    }

    public Operator getOp() {
        return op;
    }

    public String getValue() {
        return value;
    }

    @Override
    public String toString() {
        return "EmailCondition [key=" + key + ", op=" + op + ", value=" + value + "]";
    }
}

型号:Filter

public class Filter {

    public enum Operator {
        contains("contains"), starts("starts"), ends("ends"), gt("gt"), gteq("gteq"), lt("lt"), lteq("lteq"), eq(
                "eq"), inlist("inlist"), pattern("pattern");
        private final String operator;

        private Operator(String opt) {
            this.operator = opt;
        }

        public String getValue() {
            return this.operator;
        }
    }

    public enum MailAttributes {

        from("from"), to("to"), subject("subject"), body("body"), received_time("received_time");
        private final String attribute;

        private MailAttributes(String attribute) {
            this.attribute = attribute;
        }

        public String getValue() {
            return this.attribute;
        }
    }

    public enum LogicOperator {
        AND("_and_"), OR("_or_");
        private final String operator;

        private LogicOperator(String opt) {
            this.operator = opt;
        }

        public String getValue() {
            return this.operator;
        }
    }
}

您可以发送ajax请求,如下所示:

var payLoad = {

                "automationId": 123,
                "filterString": "(c1_and_c2)_or_(c1_and_c3)",
                "emailConditionMap": 
                {
                    "c1":{
                        "key": "from",
                        "op": "contains",
                        "value": "jhon"
                    },

                    "c2":{
                        "key": "to",
                        "op": "starts",
                        "value": "ron"
                    },

                    "c3":{
                        "key": "subject",
                        "op": "ends",
                        "value": "payment"
                    }
                }

           };

    $.ajax({
        url: appContextJs+"/mail/create",
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(payLoad),
        success: callbackfunction
    });

appContextJs:作为您的基本URL,例如:http://localhost:8080/webapp

请不要忘记在邮递员中将contentType设置为application/json

邮递员控制台输出:

{
    "automationId": 123,
    "emailConditionMap": {
        "c1": {
            "key": "from",
            "op": "contains",
            "value": "jhon"
        },
        "c2": {
            "key": "to",
            "op": "starts",
            "value": "ron"
        },
        "c3": {
            "key": "subject",
            "op": "ends",
            "value": "payment"
        }
    },
    "filterString": "(c1_and_c2)_or_(c1_and_c3)"
}

Eclipse控制台输出:

MailFilterCondition [automationId=123, emailConditions={c1=EmailCondition [key=from, op=contains, value=jhon], c2=EmailCondition [key=to, op=starts, value=ron], c3=EmailCondition [key=subject, op=ends, value=payment]}, filterString=(c1_and_c2)_or_(c1_and_c3)]