HttpInputMessage дает только один символ из тела запроса - PullRequest
0 голосов
/ 15 декабря 2018

У меня есть определенный пользователем 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.Что случилось?

...