【问题标题】:Using Spring MVC projections with JSON and Jackson使用带有 JSON 和 Jackson 的 Spring MVC 投影
【发布时间】:2015-03-29 21:46:45
【问题描述】:

在新版本的 Spring Data (Fowler) 中,可以将接口传递给 Spring MVC 控制器动作,然后 Spring Data 会自动创建一个代理实现并将值绑定到这个代理对象。

An example is given 在博文中描述了 Spring Data Fowler 中的一些新功能:

interface Form {
    @NotBlank String getName();
    @NotBlank String getText();
}

@Controller
@RequestMapping(value = "/guestbook")
class GuestbookController {
    @RequestMapping(method = RequestMethod.GET)
    String guestbook(Form form, Model model) { ... }

    @RequestMapping(method = RequestMethod.POST)
    String guestbook(@Valid Form form, Errors errors, Model model) { ... }
}

我的问题是,在使用 Jackson 反序列化 JSON 时是否也可以这样做?例如,像这样:

interface Form {
    @NotBlank String getName();
    @NotBlank String getText();
}

@Controller
@RequestMapping(value = "/guestbook")
class GuestbookController {
    @RequestMapping(method = RequestMethod.POST)
    String guestbook(@Valid @RequestBody Form form) { ... }
}

但是,这会产生以下异常:

无法构造 Form 的实例,问题:抽象类型也 需要映射到具体类型,具有自定义反序列化器,或者是 用额外的类型信息实例化

我明白问题出在哪里,但有没有不需要我创建实现我的接口的类或编写大量代码的解决方案?一个是simpler than this approach。因为否则我还不如使用 DTO 方法,但我发现如果我可以像示例中那样简单地使用接口,它会非常酷。

我可以通过上述方法很好地使用 DTO 类(或避免使用 JSON),但使用博客文章示例中的接口会很简洁。但是在反序列化 JSON 时,Jackson 库是否可以做到这一点?

【问题讨论】:

    标签: java spring spring-mvc jackson


    【解决方案1】:

    您可以使用Jackson Mr Bean module,这正是您想要的。

    要使用它,只需下载特定的依赖并将其作为模块设置到底层ObjectMapper 实例:

    import java.io.IOException;
    import java.util.List;
    
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.module.mrbean.MrBeanModule;
    
    public class AbstractPojosExample {
    
        public interface Person {
    
            String getName();
    
            int getAge();
    
            Address getAddress();
    
            default String asString() {
                return String.format("%s, %d, %s", this.getName(), this.getAge(), this.getAddress().asString());
            }
        }
    
        public interface Address {
    
            String getStreet();
    
            String getCity();
    
            default String asString() {
                return String.format("%s, %s", this.getStreet(), this.getCity());
            }
        }
    
        private void run() throws IOException {
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new MrBeanModule());
    
            String json = "[ { \"name\": \"John\", \"age\": 23, "
                + "\"address\": { \"street\": \"1001 5th Ave\", \"city\": \"New York\" } }, "
                + "{ \"name\": \"Jean Jacques\", \"age\": 26 , "
                + "\"address\": { \"street\": \"1001 Champs Elysees Blvd\", \"city\": \"Paris\" } }, "
                + "{ \"name\": \"Oscar Ruben\", \"age\": 54, "
                + "\"address\": { \"street\": \"1001 9th July Ave\", \"city\": \"Buenos Aires\" } } ]";
            System.out.println(json);
    
            List<Person> people = mapper.readValue(json, new TypeReference<List<Person>>() {});
    
            people.stream().map(Person::asString).forEach(System.out::println);
        }
    
        public static void main(String[] args) throws IOException {
            AbstractPojosExample example = new AbstractPojosExample();
            example.run();
        }
    }
    

    对于给定的 json:

    [
      {
        "name": "John",
        "age": 23,
        "address": {
          "street": "1001 5th Ave",
          "city": "New York"
        }
      },
      {
        "name": "Jean Jacques",
        "age": 26,
        "address": {
          "street": "1001 Champs Elysees Blvd",
          "city": "Paris"
        }
      },
      {
        "name": "Oscar Ruben",
        "age": 54,
        "address": {
          "street": "1001 9th July Ave",
          "city": "Buenos Aires"
        }
      }
    ]
    

    上面的小程序产生以下输出:

    John, 23, 1001 5th Ave, New York
    Jean Jacques, 26, 1001 Champs Elysees Blvd, Paris
    Oscar Ruben, 54, 1001 9th July Ave, Buenos Aires
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-28
      • 2016-01-15
      • 2011-03-09
      • 1970-01-01
      • 2011-08-26
      • 2021-02-18
      • 2011-05-21
      相关资源
      最近更新 更多