自定义HTTP消息转换器实战

自定义HTTP消息转换器实战

在上一篇教程中,我们学习了如何创建自定义的HTTP消息转换器。本篇教程,我们将更进一步,创建一个能够将包含YAML内容的请求体转换为用户定义的对象,反之亦然的HTTP消息转换器。我们将使用SnakeYAML,这是一个基于Java的YAML数据解析器。

创建控制器

首先,我们创建一个控制器ExampleController,它将处理YAML格式的请求和响应。

@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)
    @ResponseStatus(HttpStatus.OK)
    public Employee handleRequest2(@RequestParam String id) {
        // 创建一个测试员工
        return new Employee(id, "Tina", "111-111-1111");
    }
}

public class Employee {
    private String id;
    private String name;
    private String phoneNumber;
    // 省略其他字段和getter/setter方法
}

创建转换器

接下来,我们创建一个YamlHttpMessageConverter类,继承自AbstractHttpMessageConverter,用于处理YAML格式的转换。

public class YamlHttpMessageConverter<T> extends AbstractHttpMessageConverter<T> {
    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();
    }
}

注册转换器

然后,我们需要在Spring的配置类中注册这个转换器。

@EnableWebMvc
@ComponentScan("com.logicbig.example")
public class AppConfig extends WebMvcConfigurerAdapter {
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new YamlHttpMessageConverter<>());
    }
}

使用JUnit测试

最后,我们使用JUnit来测试我们的控制器。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = AppConfig.class)
public class ControllerTest {
    @Autowired
    private WebApplicationContext wac;
    private MockMvc mockMvc;

    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";
    }
}

输出示例

当测试通过时,你将看到如下输出:

In handleRequest method, employee: Employee{id='1', name='Tina', phoneNumber='111-111-1111}
Employee saved: Tina

项目依赖和技术

  • Spring Web MVC 4.3.8.RELEASE
  • Spring TestContext Framework 4.3.8.RELEASE
  • Java Servlet API 3.0.1
  • JUnit 4.12
  • SnakeYAML 1.18
  • JDK 1.8
  • Maven 3.3.9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

t0_54coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值