У меня есть определенный пользователем HttpMessageConverter с именем User2JsonConverter
, который может преобразовать класс User
в Http-сообщение и наоборот:
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
.Также в этом методе я печатаю некоторые сообщения журнала, чтобы указать, что является содержимым тела запроса.
И затем я регистрирую этот преобразователь в списке преобразователя:
@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
из User2JsonConverter
:
@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();
}
}
Я использую MockMvc для проверки следующим образом:
@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
, параметр метода content
.Что случилось?