SpringBoot 支持多种ContentType请求

5,645 阅读1分钟

同时支持表单和Json方式提交

  1. 硬代码编写

这是一种比较挫的方式是直接在controller中直接硬代码编写,这是一种难以复用且丑陋的方式

  • 实现方式
    • 首先在RequestMapping中添加如下代码,支持JSON and form表单提交方式
@RequestMapping(value = "/corp/login", method = RequestMethod.POST,
  consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE,
  MediaType.APPLICATION_JSON_UTF8_VALUE},
  produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
  • 在Controller中 根据Content-type 方式获取相应的参数
String header = servletRequest.getHeader("Content-type");
        String formCharset = MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=utf-8";
        if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equals(header) || formCharset.equals(header)) {
            String clientInfo = servletRequest.getParameter("clientInfo");
            ClientInfo clientInfo1 = JSON.parseObject(clientInfo, ClientInfo.class);
            request = MemberLoginFromBotaoRequest
                    .builder()
                    .loginName(servletRequest.getParameter("loginName"))
                    .password(servletRequest.getParameter("password"))
                    .type(servletRequest.getParameter("type"))
                    //.brandId(Integer.valueOf(servletRequest.getParameter("brandId")))
                    .source(servletRequest.getParameter("source"))
                    .sellerId(Integer.valueOf(servletRequest.getParameter("sellerId")))
                    .terminalIp(servletRequest.getParameter("terminalIp"))
                    .name(servletRequest.getParameter("name"))
                    .clientInfo(clientInfo1)
                    .build();
        } else if (MediaType.APPLICATION_JSON_UTF8_VALUE.equals(header)
                || MediaType.APPLICATION_JSON_VALUE.equals(header)) {
            BufferedReader br = null;
            try {
                br = servletRequest.getReader();
                String str;
                StringBuilder wholeStr = new StringBuilder();
                while ((str = br.readLine()) != null) {
                    wholeStr.append(str);
                }
                request = JSON.parseObject(wholeStr.toString(), MemberLoginFromBotaoRequest.class);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
  1. 自定义消息转换器

关于springframework的消息转换器的姿势 请自行google or baidu 以下为具体实现代码 较简单 不做阐述了

/**
 * 自定义表单消息转换器
 * 解决android端 http请求中ContentType=application/x-www-form-urlencoded
 *
 * @author zhiqin.zhang
 */
public class CustomFormHttpMessageConverter extends AbstractHttpMessageConverter {

    private List supportedMediaTypes = Arrays.asList(
            MediaType.APPLICATION_FORM_URLENCODED);

    private Charset charset = Charset.forName("UTF-8");
    ;

    @Override
    public boolean canRead(Class clazz, MediaType mediaType) {
        if (mediaType == null || MediaType.ALL.equals(mediaType)) {
            return true;
        }
        for (MediaType supportedMediaType : getSupportedMediaTypes()) {
            if (supportedMediaType.includes(mediaType)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean canWrite(Class clazz, MediaType mediaType) {
        return false;
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return supportedMediaTypes;
    }

    /**
     * 解析表单请求
     *
     * @param clazz
     * @param inputMessage
     * @return
     * @throws IOException
     * @throws HttpMessageNotReadableException
     * @// FIXME: 2018/5/26
     */
    @Override
    protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        MediaType contentType = inputMessage.getHeaders().getContentType();
        Charset charset = (contentType.getCharset() != null ? contentType.getCharset() : this.charset);
        String body = StreamUtils.copyToString(inputMessage.getBody(), charset);
        if (StringUtils.isEmpty(body)) {
            return new ResponseEntity<>(new BaseViewModel("400", "参数错误"), HttpStatus.OK);
        }
        String[] pairs = StringUtils.tokenizeToStringArray(body, "&");
        MultiValueMap<String, String> result = new LinkedMultiValueMap<String, String>(pairs.length);
        for (String pair : pairs) {
            int idx = pair.indexOf('=');
            if (idx == -1) {
                result.add(URLDecoder.decode(pair, charset.name()), null);
            } else {
                String name = URLDecoder.decode(pair.substring(0, idx), charset.name());
                String value = URLDecoder.decode(pair.substring(idx + 1), charset.name());
                result.add(name, value);
            }
        }
        if (CollectionUtils.isEmpty(result)) {
            return null;
        }
        Map<String, String> stringStringMap = result.toSingleValueMap();
        try {
            return JSON.parseObject(JSON.toJSONString(stringStringMap), clazz);
        } catch (Exception e) {
            logger.error(String.format("CustomFormHttpMessageConverter 参数转化异常:{%s}", e));
        }
        return null;
    }

    @Override
    protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {

    }

    @Override
    protected boolean supports(Class clazz) {
        return false;
    }

}