【问题标题】:JSON field mapping for Java modelJava 模型的 JSON 字段映射
【发布时间】:2015-09-05 18:19:10
【问题描述】:

发送的 JSON:

{
  "Banner": "ABC"
}

Java 模型:

...
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class BannerData implements java.io.Serializable {

    private static final long serialVersionUID = 5664846645733319592L;

    @JsonProperty(value = "Banner")
    private String banner;

    public String getBanner() {
        return banner;
    }

    public void setBanner(String banner) {
        this.banner = banner;
    }
}

控制器:

@RequestMapping(value = {"/GetBanner"}, method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<String> enrollCustomer(@RequestBody BannerData body, HttpServletRequest request) throws Exception {
...
}

/GetBanner 的请求返回:
客户端发送的请求在语法上不正确。

工作正常当 json 更改为(小写命名为 Java 字段名称):

{
  "banner": "ABC"
}

但是我需要 JSON 中的 大写 字段命名。
看起来@JsonProperty(value = "Banner") 不起作用。

映射是否正确?

【问题讨论】:

  • 我确信您没有使用 Jackson。几个 cmets 要求查看您的 Spring 设置,但您尚未发布。 @JsonProperty 现在适用于 3 个答案——您必须使用另一个序列化程序

标签: java json jackson deserialization


【解决方案1】:

也许你只是尝试:

@JsonProperty("Banner")

没有'值='。我在我的项目中使用了它,它实际上按预期工作。

更新

我刚刚创建了一些测试类来测试您的问题的行为。我做了什么:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonSerialize;


@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class BannerData implements java.io.Serializable {

 private static final long serialVersionUID = 5664846645733319592L;

 @JsonProperty("Banner")
 private String banner;

 public String getBanner() {
     return banner;
 }

 public void setBanner(String banner) {
     this.banner = banner;
 }
}

另一个读取json的类:

import org.codehaus.jackson.map.ObjectMapper;
import java.io.File;
import java.io.IOException;

public class BannerReader {
 private static final String JSON_PATH = "pathToYourJson";

 public BannerData readBanner() throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readValue(new File(JSON_PATH), BannerData.class);
 }
}

最后是入口点类:

import java.io.IOException;

public class BannerTest {

 public static void main(String[] args) throws IOException {
     BannerReader reader = new BannerReader();
     BannerData bannerData = reader.readBanner();
     System.out.println(bannerData.getBanner());
 }
}

打印:

ABC

使用的依赖:

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.9.13</version>
</dependency>

json 文件:

{
  "Banner": "ABC"
}

更新 2

虽然上面的代码对你不起作用,请尝试添加

@JsonProperty("Banner")

不仅是私有变量,还有getter/setter对,比如:

@JsonProperty("Banner")
private String banner;

@JsonProperty("Banner")
public String getBanner() {
  return banner;
}

@JsonProperty("Banner")
public void setBanner(String banner) {
  this.banner = banner;
}

【讨论】:

  • 我都试过了 - 有value=和没有。两者都不适合我。
  • @sergionni 看到我的第二次更新,希望最终会有所帮助:)
【解决方案2】:

我建议如下; (如果您使用的是 ObjectMapper)

获得 ObjectMapper 后,您可以使用 PascalCase 设置 PropertyNamingStrategy。 this is link for documentation

ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(
    PropertyNamingStrategy.PascalCaseStrategy);

如果您不使用 ObjectMapper- 然后使用 @JsonNaming 注释您的 BannerData 类,如下所示--

@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class) 
public class BannerData implements java.io.Serializable {

我发现@JsonNaming here in github

【讨论】:

    【解决方案3】:

    您是否尝试将您的 jackson 从 1.9.13 更新到 2.5.4(它有另一个工件组 id - com.fasterxml.jackson)

    此代码是否适合您?

    ObjectMapper mapper = new ObjectMapper();
    BannerData bannerData = mapper.readValue("{ \"Banner\": \"ABC\"}", BannerData.class);
    

    对我来说很好用(如果我用“banner”替换“Banner” - 得到错误的对象,“banner”字段为空。)

    这段代码也很有用:

    System.out.println(mapper.getDeserializationConfig().getPropertyNamingStrategy());
    

    属性命名策略可能有问题 - 如果您使用自定义策略。

    【讨论】:

    • 我没有尝试更新jackson。我明天将访问代码并通知您进度。感谢提示
    • 我不使用ObjectMapper mapper。模型通过@RequestBody注释作为参数传递给contoller方法。
    • 您不直接使用 objectmapper,但如果您在 spring 中使用 jackson provider 进行序列化 - 您会隐式使用它。你确定你使用的是杰克逊提供者,而不是别的吗?一些标准的嵌入式spring json序列化器?格森?你能和我们分享你的 spring 上下文描述符(beans.xml 或其他)吗?
    • 我的spring配置有限,没什么特别的
    • http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd spring config 中没有更多可能涉及此问题的具体内容
    【解决方案4】:

    在 getter 上试试

    @JsonProperty(value = "Banner")
    public String getBanner() {
    

    编辑:

    向我们展示您的 Spring 配置文件。你真的在使用杰克逊吗?见http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-jackson-and-client-program

     <!-- Configure to plugin JSON as request and response in method handler -->
     <beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
         <beans:property name="messageConverters">
             <beans:list>
                 <beans:ref bean="jsonMessageConverter"/>
             </beans:list>
         </beans:property>
     </beans:bean>
    
     <!-- Configure bean to convert JSON to POJO and vice versa -->
     <beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
     </beans:bean> 
    

    编辑 2

    由于您可能会或可能不会使用 Jackson...尝试一些其他注释 @XmlElement(name="Banner")

    也许来自 GSON @SerializedName("Banner")

    【讨论】:

    • 你确定你使用Jackson 进行序列化吗?它应该工作。见stackoverflow.com/questions/12583638/…
    • 您可以发布您对 Jackson 的配置吗?我已经使用了一百次JsonProperty。也许你错误地使用了 Moxy 或其他东西
    猜你喜欢
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多