【问题标题】:JSON object and Spring @RequestParamJSON 对象和 Spring @RequestParam
【发布时间】:2017-11-16 21:58:30
【问题描述】:

我正在我的网站前端操作以下 JSON 对象

<script>
window.campaign = {
    name: "test",
    budget: 20.00,
    type: 0,
    dynamic: false,
    geo_target: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],
    time_target: {
        monday: ["00","00","00","00",1],
        tuesday: ["00","00","00","00",1],
        wednesday: ["00","00","00","00",1],
        thursday: ["00","00","00","00",1],
        friday: ["00","00","00","00",1],
        saturday: ["00","00","00","00",1],
        sunday: ["00","00","00","00",1]
    },

    setName: function(val) {
        this.name = val;
    },

    //some more setters go here
}
</script>

然后我使用 AJAX 将它发送到我的 Spring 应用程序

$.ajax({ type: "POST", url: submit_url, data: JSON.stringify(window.campaign) })
.done(function() { alert( "success" ); })
.fail(function() { alert( "error" ); });

现在的问题是在我的@Controller 中相应地映射所有变量

....
@RequestParam(value = "name", required = false, defaultValue = "") String name,
@RequestParam(value = "budget", required = false, defaultValue = "0") BigDecimal budget,
@RequestParam(value = "type", required = false, defaultValue = "0") int type,
@RequestParam(value = "dynamic", required = false, defaultValue = "false") boolean dynamic,
@RequestParam(value = "geo_target", required = false, defaultValue = "") int[] geoTargeting,
....

这一切都很好,但我不知道如何映射time_target

我尝试创建一个新的Model 并使用@RequestBody 映射它

....
@RequestParam(value = "name", required = false, defaultValue = "") String name,
....
@RequestParam(value = "geo_target", required = false, defaultValue = "") int[] geoTargeting,    
@RequestBody TimeTarget timeTargeting
....

没有成功。我使用http://www.jsonschema2pojo.org 为我要发送的整个对象创建了一个Class,但没有成功(仅供参考,它创建了两个类,一个用于 timeTargeting,一个用于其他所有对象)。

我真的很绝望。请帮忙:)如果提供的代码不够,我可以更新更多。

【问题讨论】:

  • 1 个解决方案:@RequestParam(value = "time_target") String[] timeTargeting 这个工作适合你吗?
  • 这个控制器会变得很乱。您可以在一个 POST 参数中发送整个 JSON 字符串。然后在您的后端,您使用一个简单的 JSON 库来解析字符串并从中获取数据。
  • 我什至怀疑它是否有效。您发布的是 JSON 而不是请求参数 (afaik)。只需将 JSON 作为正文发送,创建一个对象并将所有参数映射到该对象(jackson 会为您执行此操作)。
  • M. Deinum 或@mumpitz 可以举个例子吗?我试过了,但真的被我在网上找到的不相关的例子弄糊涂了......
  • 您可以使用 Jackson 之类的转换器将字符串转换为 Java 对象

标签: java json ajax spring spring-mvc


【解决方案1】:

您应该在 Java 中围绕 JSON 结构创建一个包装器,并将其作为 @RequestBody 传递给控制器​​。这对我有用:

public class CampaignDTO {
    private String name;
    private BigDecimal budget;
    private Integer type;
    private Boolean dynamic;

    @JsonProperty("geo_target")
    private List<Integer> geoTarget;

    @JsonProperty("time_target")
    private TimeTarget timeTarget;

    public String getName() {
        return name;
    }

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

    public BigDecimal getBudget() {
        return budget;
    }

    public void setBudget(BigDecimal budget) {
        this.budget = budget;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Boolean getDynamic() {
        return dynamic;
    }

    public void setDynamic(Boolean dynamic) {
        this.dynamic = dynamic;
    }

    public List<Integer> getGeoTarget() {
        return geoTarget;
    }

    public void setGeoTarget(List<Integer> geoTarget) {
        this.geoTarget = geoTarget;
    }

    public TimeTarget getTimeTarget() {
        return timeTarget;
    }

    public void setTimeTarget(TimeTarget timeTarget) {
        this.timeTarget = timeTarget;
    }
}

CampainDTO 中包含的另一个 DTO:

public class TimeTarget {
    private List<String> monday;
    private List<String> tuesday;
    private List<String> wednesday;
    private List<String> thursday;
    private List<String> friday;
    private List<String> sunday;

    public List<String> getMonday() {
        return monday;
    }

    public void setMonday(List<String> monday) {
        this.monday = monday;
    }

    public List<String> getTuesday() {
        return tuesday;
    }

    public void setTuesday(List<String> tuesday) {
        this.tuesday = tuesday;
    }

    public List<String> getWednesday() {
        return wednesday;
    }

    public void setWednesday(List<String> wednesday) {
        this.wednesday = wednesday;
    }

    public List<String> getThursday() {
        return thursday;
    }

    public void setThursday(List<String> thursday) {
        this.thursday = thursday;
    }

    public List<String> getFriday() {
        return friday;
    }

    public void setFriday(List<String> friday) {
        this.friday = friday;
    }

    public List<String> getSunday() {
        return sunday;
    }

    public void setSunday(List<String> sunday) {
        this.sunday = sunday;
    }
}

最后一部分是你的控制器。请注意,它在这里作为回声工作 - 它完全返回您发布的内容。这就是我在这里添加@ResponseBody 的原因。

@Controller
public class CampainController {

    @RequestMapping(name = "/test", method = RequestMethod.POST)
    @ResponseBody
    public CampaignDTO test(@RequestBody CampaignDTO campaignDTO) {
        return campaignDTO;
    }
}

在您将请求发布到http://localhost:8080/test 后,它应该可以正常工作。

【讨论】:

  • 工作得很好。但是,我不得不稍微更改 ajax 调用以包含 Content-Type: "application/json"
  • 我来到这里是在寻找不同的方法来解决我刚刚在此处发布的question。这个解决方案看起来对我有用,但它没有。 save 方法接收的对象具有 Strings 变量,其中包含指向数据库中其他对象的 URL。我实现的任何控制器方法都无法转换这些 URL。此转换适用于扩展的默认存储库方法,但前端无法访问自定义保存存储库方法。
猜你喜欢
  • 1970-01-01
  • 2011-11-12
  • 1970-01-01
  • 2013-06-01
  • 2021-12-10
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多