我有一个名为User2JsonConverter
的用户定义的HttpMessageConverter,它可以将User
类转换为Http Message,反之亦然:
public class User2JsonConverter extends AbstractHttpMessageConverter<User> {
public static final MediaType USER_MEDIATYPE=new MediaType("application","user-defined-json-type");
private static Logger logger= Logger.getLogger(User2JsonConverter.class);
public User2JsonConverter(){
super(Charset.forName("UTF-8"),USER_MEDIATYPE);
}
@Override
protected boolean supports(Class<?> clazz) {
return User.class.isAssignableFrom(clazz);;
}
@Override
protected User readInternal(Class<? extends User> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException {
byte[] bytes=new byte[inputMessage.getBody().available()];
logger.info("The return value of #read is " + inputMessage.getBody().read(bytes));
String content=new String(bytes,Charset.forName("UTF-8"));
logger.info("The content is "+content);
String[] userProfiles=content.split(",");
if(userProfiles.length!=3) {
logger.fatal("invalid message");
throw new HttpMessageNotReadableException("invalid message");
}
User user=new User();
user.setId(userProfiles[0]);
user.setUsername(userProfiles[1]);
user.setPassword(userProfiles[2]);
return user;
}
@Override
protected void writeInternal(User user, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
//.....
}
}
方法readInternal
可以分析格式为'User
bean。同样,在这种方法中,我打印一些日志消息以指示请求正文的内容。
然后我将该转换器注册到对流器列表中
@Configuration
@EnableWebMvc //Serve as <mvc:annotation-driven/>
@ComponentScan
@ImportResource({"classpath:spring/springmvc-config.xml"})
public class SpringWebContextConfig extends WebMvcConfigurerAdapter {
private static Logger logger=Logger.getLogger(SpringWebContextConfig.class);
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
converters.add(0,new User2JsonConverter());
}
//......
}
控制器deserializeUser
中的方法TestController
用作测试,使用注解@RequestBody
调用readInternal
的{{1}}:
User2JsonConverter
我使用MockMvc进行测试,如下所示:
@Controller
@RequestMapping("/test")
public class TestController {
@RequestMapping(
value = "/getUserJson",
consumes = "application/user-defined-json-type" ,
method = RequestMethod.POST)
@ResponseBody
public String deserializeUser(@RequestBody User user){
return user.toJson();
}
}
但是它无法显示我的期望。它报告已解决的异常:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CombContextConfig.class)
@WebAppConfiguration
public class TestControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
private Logger logger= Logger.getLogger(TestControllerTest.class);
@Before
public void setMockMvc() {
mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void testDeserializeUser() throws Exception {
String content="id-testSerializeUser," +
"username-testSerializeUser," +
"password-testSerializeUser";
mockMvc.perform(
post("/test/getUserJson")
.content(content)
.contentType(User2JsonConverter.USER_MEDIATYPE)
)
.andDo(MockMvcResultHandlers.print());
}
}
日志消息显示:
Resolved Exception:
Type = org.springframework.http.converter.HttpMessageNotReadableException
它表示请求正文的内容仅包含一个字符04:12:50 [main] INFO IN [com.azure.mall.converter.User2JsonConverter]
=> The return value of #read is 1
04:12:50 [main] INFO IN [com.azure.mall.converter.User2JsonConverter]
=> The content is i
04:12:50 [main] FATAL IN [com.azure.mall.converter.User2JsonConverter]
=> invalid message
,它是方法'i'
的参数content
的第一个字符。发生了什么?