在SpringMVC的上下文中,如何使用提供同一类的不同JSON表示的Web服务?

vah*_*eza 6 java json spring-mvc spring-restcontroller

我有一个数据类,如下所示:

public class Person {
   private String name;
   private Long code;

   // corresponding getters and setters
}
Run Code Online (Sandbox Code Playgroud)

我想编写两个Web服务,提供两个不同的JSON表示形式的Person.例如,其中一个提供{"name":"foo"}但另一个提供{"name":"foo", "code":"123"}.

作为一个更复杂的场景,假设Person有一个引用属性,例如address.地址也有自己的属性,我希望我的两个Web服务都考虑这个属性,但每个属性都以自己的方式执行.

我的SpringMVC视图应该如何?

请注意,我是SpringMVC的新手.请在答案旁边给我一个示例代码.

更新1:几天后,所有答案都促使我解决控制器中的问题或通过注释数据类.但我希望在视图中执行此操作,而不再使用java代码.我可以在JSP文件或百万美元模板甚至.properties文件中执行此操作吗?

更新2:我找到了json-taglib.但不知何故,它被排除在新的升级之外.有没有类似的解决方案?

Mạn*_*yễn 5

你正在使用Spring-MVC杰克逊负责JSON序列化和反序列化.

在这种情况下,您可以使用@JsonInclude(Include.NON_NULL)在序列化期间忽略空字段.

public class Person {
   @JsonInclude(Include.NON_NULL)
   private String name;

   @JsonInclude(Include.NON_NULL)
   private Long code;

   // corresponding getters and setters
}
Run Code Online (Sandbox Code Playgroud)

如果您name或者codenull它会被从输出排除JSON

所以,如果你传递codenull,你的输出中JSON的样子{"name":"foo"}


Joh*_*anB 5

使用 Spring MVC 创建 JSon 时,“视图渲染器”默认为 Jackson。无需使用 JSP 或其他视图技术之类的东西。你想要做的是告诉杰克逊如何在给定的情况下渲染一个对象。有多种选择,但我建议使用投影。一个例子:

@RestController
@RequestMapping(value = "person")
public class PersonController {

    private final ProjectionFactory projectionFactory;

    public PersonController(ProjectionFactory projectionFactory) {
        this.projectionFactory = projectionFactory;
    }

    @GetMapping("...")
    public PersonBase getPerson(..., @RequestParam(value = "view", required = false, defaultValue = "base") String view) {
        ...

        if(view.equals("extended")) {
            return projectionFactory.createProjection(PersonExtended.class, person);
        } else {
            return projectionFactory.createProjection(PersonBase.class, person);
        }
    }
}



public interface PersonBase {
    String getName();
}

public interface PersonExtended extends PersonBase {
    Long getCode;
}
Run Code Online (Sandbox Code Playgroud)

您的应用程序的视图层是投影类(然后放在一个包中,如果您愿意,可以放在视图包中)。控制器可以选择要渲染的视图,或者您可以像示例中那样使结果动态化。

您关于如何呈现地址的问题可以通过这样的另一个投影来解决:

public interface PersonWithAddress extends PersonExtended {
    AddressProjection getAddress();
}

public interface AddressProjection {
    String getStreetName();
    String getZipcode();
    ...
}
Run Code Online (Sandbox Code Playgroud)