/** * Create a new {@code Message.Builder} instance for the given class. * <p>This method uses a ConcurrentReferenceHashMap for caching method lookups. */ private Message.Builder getMessageBuilder(Class<? extends Message> clazz) { try { Method method = methodCache.get(clazz); if (method == null) { method = clazz.getMethod("newBuilder"); methodCache.put(clazz, method); } return (Message.Builder) method.invoke(clazz); } catch (Exception ex) { throw new HttpMessageConversionException( "Invalid Protobuf Message type: no invocable newBuilder() method on " + clazz, ex); } }
@Test public void readWithNoDefaultConstructor() throws Exception { String body = "{\"property1\":\"foo\",\"property2\":\"bar\"}"; MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8")); inputMessage.getHeaders().setContentType(new MediaType("application", "json")); try { converter.read(BeanWithNoDefaultConstructor.class, inputMessage); } catch (HttpMessageConversionException ex) { assertTrue(ex.getMessage(), ex.getMessage().startsWith("Type definition error:")); return; } fail(); }
/** * Return a {@link JAXBContext} for the given class. * @param clazz the class to return the context for * @return the {@code JAXBContext} * @throws HttpMessageConversionException in case of JAXB errors */ protected final JAXBContext getJaxbContext(Class<?> clazz) { Assert.notNull(clazz, "Class must not be null"); JAXBContext jaxbContext = this.jaxbContexts.get(clazz); if (jaxbContext == null) { try { jaxbContext = JAXBContext.newInstance(clazz); this.jaxbContexts.putIfAbsent(clazz, jaxbContext); } catch (JAXBException ex) { throw new HttpMessageConversionException( "Could not instantiate JAXBContext for class [" + clazz + "]: " + ex.getMessage(), ex); } } return jaxbContext; }
/** * 参数格式异常处理 * * @param cause 异常 * @return 响应结果 */ @ExceptionHandler(HttpMessageConversionException.class) @ResponseBody public RespData handleHttpMessageConversionException(HttpMessageConversionException cause, HttpServletRequest request) { // 输出错误信息 log.info("== 参数绑定异常 =="); log.info(cause.getMessage(), cause); // 构造返回值 RespData resp = new RespData(); resp.setCode(BaseCode.E9997); resp.setMessage(msa.getMessage(localeResolve.resolveLocale(request), BaseCode.E9997)); return resp; }
@Override public void print(Message message, OutputStream output, MediaType contentType, Charset charset) throws IOException, HttpMessageConversionException { if (contentType.isCompatibleWith(APPLICATION_JSON)) { OutputStreamWriter writer = new OutputStreamWriter(output, charset); this.printer.appendTo(message, writer); writer.flush(); } else { throw new HttpMessageConversionException( "protobuf-java-util does not support printing " + contentType); } } }
@Override public void merge(InputStream input, Charset charset, MediaType contentType, ExtensionRegistry extensionRegistry, Message.Builder builder) throws IOException, HttpMessageConversionException { if (contentType.isCompatibleWith(APPLICATION_JSON)) { InputStreamReader reader = new InputStreamReader(input, charset); this.parser.merge(reader, builder); } else { throw new HttpMessageConversionException( "protobuf-java-util does not support parsing " + contentType); } }
/** * Create a new {@link Marshaller} for the given class. * @param clazz the class to create the marshaller for * @return the {@code Marshaller} * @throws HttpMessageConversionException in case of JAXB errors */ protected final Marshaller createMarshaller(Class<?> clazz) { try { JAXBContext jaxbContext = getJaxbContext(clazz); Marshaller marshaller = jaxbContext.createMarshaller(); customizeMarshaller(marshaller); return marshaller; } catch (JAXBException ex) { throw new HttpMessageConversionException( "Could not create Marshaller for class [" + clazz + "]: " + ex.getMessage(), ex); } }
/** * Create a new {@code Message.Builder} instance for the given class. * <p>This method uses a ConcurrentReferenceHashMap for caching method lookups. */ private Message.Builder getMessageBuilder(Class<? extends Message> clazz) { try { Method method = methodCache.get(clazz); if (method == null) { method = clazz.getMethod("newBuilder"); methodCache.put(clazz, method); } return (Message.Builder) method.invoke(clazz); } catch (Exception ex) { throw new HttpMessageConversionException( "Invalid Protobuf Message type: no invocable newBuilder() method on " + clazz, ex); } }
/** * Create a new {@link Unmarshaller} for the given class. * @param clazz the class to create the unmarshaller for * @return the {@code Unmarshaller} * @throws HttpMessageConversionException in case of JAXB errors */ protected final Unmarshaller createUnmarshaller(Class<?> clazz) { try { JAXBContext jaxbContext = getJaxbContext(clazz); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); customizeUnmarshaller(unmarshaller); return unmarshaller; } catch (JAXBException ex) { throw new HttpMessageConversionException( "Could not create Unmarshaller for class [" + clazz + "]: " + ex.getMessage(), ex); } }
/** * Return a {@link JAXBContext} for the given class. * @param clazz the class to return the context for * @return the {@code JAXBContext} * @throws HttpMessageConversionException in case of JAXB errors */ protected final JAXBContext getJaxbContext(Class<?> clazz) { Assert.notNull(clazz, "Class must not be null"); JAXBContext jaxbContext = this.jaxbContexts.get(clazz); if (jaxbContext == null) { try { jaxbContext = JAXBContext.newInstance(clazz); this.jaxbContexts.putIfAbsent(clazz, jaxbContext); } catch (JAXBException ex) { throw new HttpMessageConversionException( "Could not instantiate JAXBContext for class [" + clazz + "]: " + ex.getMessage(), ex); } } return jaxbContext; }
@Override protected Object readFromSource(Class<?> clazz, HttpHeaders headers, Source source) throws Exception { try { source = processSource(source); Unmarshaller unmarshaller = createUnmarshaller(clazz); if (clazz.isAnnotationPresent(XmlRootElement.class)) { return unmarshaller.unmarshal(source); } else { JAXBElement<?> jaxbElement = unmarshaller.unmarshal(source, clazz); return jaxbElement.getValue(); } } catch (NullPointerException ex) { if (!isSupportDtd()) { throw new IllegalStateException("NPE while unmarshalling. " + "This can happen due to the presence of DTD declarations which are disabled.", ex); } throw ex; } catch (UnmarshalException ex) { throw ex; } catch (JAXBException ex) { throw new HttpMessageConversionException("Invalid JAXB setup: " + ex.getMessage(), ex); } }
@Override protected void writeToResult(Object o, HttpHeaders headers, Result result) throws Exception { try { Class<?> clazz = ClassUtils.getUserClass(o); Marshaller marshaller = createMarshaller(clazz); setCharset(headers.getContentType(), marshaller); marshaller.marshal(o, result); } catch (MarshalException ex) { throw ex; } catch (JAXBException ex) { throw new HttpMessageConversionException("Invalid JAXB setup: " + ex.getMessage(), ex); } }
@Override public void print(Message message, OutputStream output, MediaType contentType, Charset charset) throws IOException, HttpMessageConversionException { if (contentType.isCompatibleWith(APPLICATION_JSON)) { OutputStreamWriter writer = new OutputStreamWriter(output, charset); this.printer.appendTo(message, writer); writer.flush(); } else { throw new HttpMessageConversionException( "protobuf-java-util does not support printing " + contentType); } } }
@Override public void merge(InputStream input, Charset charset, MediaType contentType, ExtensionRegistry extensionRegistry, Message.Builder builder) throws IOException, HttpMessageConversionException { if (contentType.isCompatibleWith(APPLICATION_JSON)) { InputStreamReader reader = new InputStreamReader(input, charset); this.parser.merge(reader, builder); } else { throw new HttpMessageConversionException( "protobuf-java-util does not support parsing " + contentType); } }
/** * Create a new {@link Unmarshaller} for the given class. * @param clazz the class to create the unmarshaller for * @return the {@code Unmarshaller} * @throws HttpMessageConversionException in case of JAXB errors */ protected final Unmarshaller createUnmarshaller(Class<?> clazz) { try { JAXBContext jaxbContext = getJaxbContext(clazz); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); customizeUnmarshaller(unmarshaller); return unmarshaller; } catch (JAXBException ex) { throw new HttpMessageConversionException( "Could not create Unmarshaller for class [" + clazz + "]: " + ex.getMessage(), ex); } }
/** * Create a new {@link Marshaller} for the given class. * @param clazz the class to create the marshaller for * @return the {@code Marshaller} * @throws HttpMessageConversionException in case of JAXB errors */ protected final Marshaller createMarshaller(Class<?> clazz) { try { JAXBContext jaxbContext = getJaxbContext(clazz); Marshaller marshaller = jaxbContext.createMarshaller(); customizeMarshaller(marshaller); return marshaller; } catch (JAXBException ex) { throw new HttpMessageConversionException( "Could not create Marshaller for class [" + clazz + "]: " + ex.getMessage(), ex); } }
throw new HttpMessageConversionException("Invalid JAXB setup: " + ex.getMessage(), ex);
@Override protected final E readFromSource(Class<? extends E> clazz, HttpHeaders headers, Source source) throws IOException { try { JAXBElement<? extends I> jaxbElement = createUnmarshaller().unmarshal(source, internalClass); return convertToExternal(jaxbElement.getValue()); } catch (UnmarshalException ex) { throw new HttpMessageNotReadableException("Could not unmarshal to [" + clazz + "]: " + ex.getMessage(), ex); } catch (JAXBException ex) { throw new HttpMessageConversionException("Could not instantiate JAXBContext: " + ex.getMessage(), ex); } }
@Override protected Object readFromSource(Class<?> clazz, HttpHeaders headers, Source source) throws Exception { try { source = processSource(source); Unmarshaller unmarshaller = createUnmarshaller(clazz); if (clazz.isAnnotationPresent(XmlRootElement.class)) { return unmarshaller.unmarshal(source); } else { JAXBElement<?> jaxbElement = unmarshaller.unmarshal(source, clazz); return jaxbElement.getValue(); } } catch (NullPointerException ex) { if (!isSupportDtd()) { throw new IllegalStateException("NPE while unmarshalling. " + "This can happen due to the presence of DTD declarations which are disabled.", ex); } throw ex; } catch (UnmarshalException ex) { throw ex; } catch (JAXBException ex) { throw new HttpMessageConversionException("Invalid JAXB setup: " + ex.getMessage(), ex); } }
@Override public void merge(InputStream input, Charset charset, MediaType contentType, ExtensionRegistry extensionRegistry, Message.Builder builder) throws IOException, HttpMessageConversionException { if (contentType.isCompatibleWith(APPLICATION_JSON)) { this.jsonFormatter.merge(input, charset, extensionRegistry, builder); } else if (contentType.isCompatibleWith(APPLICATION_XML)) { this.xmlFormatter.merge(input, charset, extensionRegistry, builder); } else { throw new HttpMessageConversionException( "protobuf-java-format does not support parsing " + contentType); } }