基于 SnakeYAML 的 YAML 数据与 Java 对象转换实践

前言
在现代的 Web 开发中,数据交换格式的多样性要求我们能够灵活地处理各种格式的数据。除了常见的 JSON 和 XML,YAML 作为一种简洁且易于阅读的标记语言,也越来越受到开发者的关注。本文将通过一个完整的示例,展示如何在 Spring MVC 中使用 SnakeYAML 库实现 YAML 数据与 Java 对象之间的转换。

  1. 项目背景
    在之前的教程中,我们已经学习了如何创建自定义的 HTTPMessageConverter。这一次,我们将进一步扩展,实现一个能够处理 YAML 格式数据的 HTTPMessageConverter。通过这个转换器,我们可以轻松地将 YAML 格式的请求体转换为 Java 对象,同时也能将 Java 对象转换为 YAML 格式的响应体。

  2. 创建控制器
    首先,我们需要创建一个控制器来处理与 YAML 数据相关的请求。以下是一个简单的控制器示例:
    java复制
    @Controller
    public class ExampleController {
    @RequestMapping(
    value = “/newEmployee”,
    consumes = “text/yaml”,
    produces = MediaType.TEXT_PLAIN_VALUE,
    method = RequestMethod.POST)
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public String handleRequest(@RequestBody Employee employee) {
    System.out.printf(“In handleRequest method, employee: %s%n”, employee);
    String s = String.format("Employee saved: " + employee.getName());
    System.out.println(s);
    return s;
    }

    @RequestMapping(
    value = “/employee”,
    produces = “text/yaml”,
    method = RequestMethod.GET)
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    public Employee handleRequest2(@RequestParam String id) {
    // 创建一个测试员工对象
    return new Employee(id, “Tina”, “111-111-1111”);
    }
    }
    在上述代码中,handleRequest 方法用于处理 POST 请求,接收 YAML 格式的请求体并将其转换为 Employee 对象。handleRequest2 方法则用于处理 GET 请求,返回一个 Employee 对象,并将其转换为 YAML 格式的响应体。

  3. 创建 YAML 转换器
    接下来,我们需要创建一个自定义的 HTTPMessageConverter,用于处理 YAML 数据的读取和写入。以下是转换器的实现代码:
    java复制
    public class YamlHttpMessageConverter extends AbstractHttpMessageConverter {
    public YamlHttpMessageConverter() {
    super(new MediaType(“text”, “yaml”));
    }

    @Override
    protected boolean supports(Class<?> clazz) {
    return true;
    }

    @Override
    protected T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage)
    throws IOException, HttpMessageNotReadableException {
    Yaml yaml = new Yaml();
    T t = yaml.loadAs(inputMessage.getBody(), clazz);
    return t;
    }

    @Override
    protected void writeInternal(T t, HttpOutputMessage outputMessage)
    throws IOException, HttpMessageNotWritableException {
    Yaml yaml = new Yaml();
    OutputStreamWriter writer = new OutputStreamWriter(outputMessage.getBody());
    yaml.dump(t, writer);
    writer.close();
    }
    }
    在 readInternal 方法中,我们使用 SnakeYAML 的 loadAs 方法将 YAML 数据流转换为指定类型的 Java 对象。在 writeInternal 方法中,我们使用 dump 方法将 Java 对象转换为 YAML 格式的数据流。

  4. 注册转换器
    为了让 Spring MVC 使用我们自定义的 YamlHttpMessageConverter,我们需要在配置类中将其注册到消息转换器列表中。以下是配置类的代码:
    java复制
    @EnableWebMvc
    @ComponentScan(“com.logicbig.example”)
    public class AppConfig extends WebMvcConfigurerAdapter {
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(new YamlHttpMessageConverter<>());
    }
    }
    通过 extendMessageConverters 方法,我们将 YamlHttpMessageConverter 添加到 Spring MVC 的消息转换器列表中,使其能够被 Spring MVC 框架自动使用。

  5. 测试
    为了验证我们的实现是否正确,我们可以编写一些 JUnit 测试用例。以下是测试请求和响应的代码示例:
    测试请求
    java复制
    @RunWith(SpringJUnit4ClassRunner.class)
    @WebAppConfiguration
    @ContextConfiguration(classes = AppConfig.class)
    public class ControllerTest {
    @Autowired
    private WebApplicationContext wac;
    private MockMvc mockMvc;

    @Before
    public void setup() {
    DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac);
    this.mockMvc = builder.build();
    }

    @Test
    public void testConsumerController() throws Exception {
    MockHttpServletRequestBuilder builder =
    MockMvcRequestBuilders.post(“/newEmployee”)
    .contentType(“text/yaml”)
    .accept(MediaType.TEXT_PLAIN_VALUE)
    .content(getNewEmployeeInYaml());
    this.mockMvc.perform(builder)
    .andExpect(MockMvcResultMatchers.status().isOk())
    .andExpect(MockMvcResultMatchers.content().string(“Employee saved: Tina”))
    .andDo(MockMvcResultHandlers.print());
    }

    public String getNewEmployeeInYaml() {
    return “id: 1\nname: Tina\nphoneNumber: 111-111-1111\n”;
    }
    }
    在上述测试代码中,我们模拟了一个 POST 请求,发送 YAML 格式的请求体,并验证响应状态码和响应内容是否符合预期。
    测试响应
    java复制
    @Test
    public void testProducerController() throws Exception {
    MockHttpServletRequestBuilder builder =
    MockMvcRequestBuilders.get(“/employee”)
    .accept(“text/yaml”)
    .param(“id”, “1”);
    this.mockMvc.perform(builder)
    .andExpect(MockMvcResultMatchers.status().isOk())
    .andDo(MockMvcResultHandlers.print());
    }
    在测试响应的代码中,我们模拟了一个 GET 请求,接受 YAML 格式的响应体,并验证响应状态码是否为 200。

  6. 输出结果
    以下是测试运行后的输出结果:
    测试请求输出
    复制
    In handleRequest method, employee: Employee{id=‘1’, name=‘Tina’, phoneNumber=‘111-111-1111’}
    Employee saved: Tina
    MockHttpServletRequest:
    HTTP Method = POST
    Request URI = /newEmployee
    Parameters = {}
    Headers = {Content-Type=[text/yaml], Accept=[text/plain]}
    Handler:
    Type = com.logicbig.example.ExampleController
    Method = public java.lang.String com.logicbig.example.ExampleController.handleRequest(com.logicbig.example.Employee)
    Async:
    Async started = false
    Async result = null
    Resolved Exception:
    Type = null
    ModelAndView:
    View name = null
    View = null
    Model = null
    FlashMap:
    Attributes = null
    MockHttpServletResponse:
    Status = 200
    Error message = null
    Headers = {Content-Type=[text/plain;charset=ISO-8859-1], Content-Length=[20]}
    Content type = text/plain;charset=ISO-8859-1
    Body = Employee saved: Tina
    Forwarded URL = null
    Redirected URL = null
    Cookies = []
    测试响应输出
    复制
    MockHttpServletRequest:
    HTTP Method = GET
    Request URI = /employee
    Parameters = {id=[1]}
    Headers = {Accept=[text/yaml]}
    Handler:
    Type = com.logicbig.example.ExampleController
    Method = public com.logicbig.example.Employee com.logicbig.example.ExampleController.handleRequest2(java.lang.String)
    Async:
    Async started = false
    Async result = null
    Resolved Exception:
    Type = null
    ModelAndView:
    View name = null
    View = null
    Model = null
    FlashMap:
    Attributes = null
    MockHttpServletResponse:
    Status = 200
    Error message = null
    Headers = {Content-Type=[text/yaml]}
    Content type = text/yaml
    Body = !!com.logicbig.example.Employee {id: ‘1’, name: Tina, phoneNumber: 111-111-1111}
    Forwarded URL = null
    Redirected URL = null
    Cookies = []
    从输出结果可以看出,我们的 YAML 数据与 Java 对象之间的转换功能已经正常工作。

  7. 总结
    通过本文的介绍,我们学习了如何在 Spring MVC 中使用 SnakeYAML 库实现 YAML 数据与 Java 对象之间的转换。通过自定义的 YamlHttpMessageConverter,我们可以轻松地处理 YAML 格式的请求和响应。同时,通过编写 JUnit 测试用例,我们验证了实现的正确性。希望本文能够帮助你在项目中更好地处理 YAML 数据。

  8. 示例项目依赖
    以下是本项目所使用的依赖和相关技术:
    spring-webmvc 4.3.8.RELEASE: Spring Web MVC。
    spring-test 4.3.8.RELEASE: Spring TestContext Framework。
    javax.servlet-api 3.0.1: Java Servlet API。
    junit 4.12: JUnit 是一个用于 Java 的单元测试框架。
    snakeyaml

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值