下面列出了org.springframework.beans.factory.config.BeanExpressionContext#org.springframework.beans.TypeMismatchException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
@Nullable
protected Object convertFromInternal(Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
Assert.notNull(this.unmarshaller, "Property 'unmarshaller' is required");
try {
Source source = getSource(message.getPayload());
Object result = this.unmarshaller.unmarshal(source);
if (!targetClass.isInstance(result)) {
throw new TypeMismatchException(result, targetClass);
}
return result;
}
catch (Exception ex) {
throw new MessageConversionException(message, "Could not unmarshal XML: " + ex.getMessage(), ex);
}
}
@Override
@SuppressWarnings("unchecked")
public Object convertIfNecessary(Object value, Class requiredType) {
if (value instanceof String && Float.class.isAssignableFrom(requiredType)) {
try {
return new Float(this.numberFormat.parse((String) value).floatValue());
}
catch (ParseException ex) {
throw new TypeMismatchException(value, requiredType, ex);
}
}
else if (value instanceof String && int.class.isAssignableFrom(requiredType)) {
return new Integer(5);
}
else {
return value;
}
}
@Test
public void testContextWithInvalidValueType() throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] {INVALID_VALUE_TYPE_CONTEXT}, false);
try {
context.refresh();
fail("Should have thrown BeanCreationException");
}
catch (BeanCreationException ex) {
assertTrue(ex.contains(TypeMismatchException.class));
assertTrue(ex.toString().contains("someMessageSource"));
assertTrue(ex.toString().contains("useCodeAsDefaultMessage"));
checkExceptionFromInvalidValueType(ex);
checkExceptionFromInvalidValueType(new ExceptionInInitializerError(ex));
assertFalse(context.isActive());
}
}
/**
* TypeMismatchException中获取到参数错误类型
*
* @param e
*/
private ModelAndView getParamErrors(TypeMismatchException e) {
Throwable t = e.getCause();
if (t instanceof ConversionFailedException) {
ConversionFailedException x = (ConversionFailedException) t;
TypeDescriptor type = x.getTargetType();
Annotation[] annotations = type != null ? type.getAnnotations() : new Annotation[0];
Map<String, String> errors = new HashMap<String, String>();
for (Annotation a : annotations) {
if (a instanceof RequestParam) {
errors.put(((RequestParam) a).value(), "parameter type error!");
}
}
if (errors.size() > 0) {
return paramError(errors, ErrorCode.TYPE_MIS_MATCH);
}
}
JsonObjectBase jsonObject = JsonObjectUtils.buildGlobalError("parameter type error!", ErrorCode.TYPE_MIS_MATCH);
return JsonObjectUtils.JsonObjectError2ModelView((JsonObjectError) jsonObject);
}
@Test(expected = TypeMismatchException.class)
public void testCustomConversionService() throws Exception {
loadBeanDefinitions("mvc-config-custom-conversion-service.xml");
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
mapping.setDefaultHandler(handlerMethod);
// default web binding initializer behavior test
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
request.setRequestURI("/accounts/12345");
request.addParameter("date", "2009-10-31");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = mapping.getHandler(request);
assertEquals(1, chain.getInterceptors().length);
assertTrue(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor);
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[0];
interceptor.preHandle(request, response, handler);
assertSame(appContext.getBean("conversionService"), request.getAttribute(ConversionService.class.getName()));
RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class);
assertNotNull(adapter);
adapter.handle(request, response, handlerMethod);
}
@Test
public void readWithTypeMismatchException() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(new byte[0]);
Marshaller marshaller = mock(Marshaller.class);
Unmarshaller unmarshaller = mock(Unmarshaller.class);
given(unmarshaller.unmarshal(isA(StreamSource.class))).willReturn(Integer.valueOf(3));
MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(marshaller, unmarshaller);
try {
converter.read(String.class, inputMessage);
fail("Should have thrown HttpMessageNotReadableException");
}
catch (HttpMessageNotReadableException ex) {
assertTrue(ex.getCause() instanceof TypeMismatchException);
}
}
@Override
protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex,
HttpHeaders headers,
HttpStatus status,
WebRequest request)
{
ErrorDetail errorDetail = new ErrorDetail();
errorDetail.setTimestamp(new Date().getTime());
errorDetail.setStatus(HttpStatus.BAD_REQUEST.value());
errorDetail.setTitle(ex.getPropertyName() + " Parameter Type Mismatch");
errorDetail.setDetail(ex.getMessage());
errorDetail.setDeveloperMessage(request.getDescription(true));
return new ResponseEntity<>(errorDetail,
headers,
HttpStatus.NOT_FOUND);
}
@Test(expected = TypeMismatchException.class)
public void testCustomConversionService() throws Exception {
loadBeanDefinitions("mvc-config-custom-conversion-service.xml");
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
mapping.setDefaultHandler(handlerMethod);
// default web binding initializer behavior test
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
request.setRequestURI("/accounts/12345");
request.addParameter("date", "2009-10-31");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = mapping.getHandler(request);
assertEquals(1, chain.getInterceptors().length);
assertTrue(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor);
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[0];
interceptor.preHandle(request, response, handler);
assertSame(appContext.getBean("conversionService"), request.getAttribute(ConversionService.class.getName()));
RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class);
assertNotNull(adapter);
adapter.handle(request, response, handlerMethod);
}
@Test(expected = TypeMismatchException.class)
public void testCustomConversionService() throws Exception {
loadBeanDefinitions("mvc-config-custom-conversion-service.xml", 14);
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
assertNotNull(mapping);
mapping.setDefaultHandler(handlerMethod);
// default web binding initializer behavior test
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
request.setRequestURI("/accounts/12345");
request.addParameter("date", "2009-10-31");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = mapping.getHandler(request);
assertEquals(1, chain.getInterceptors().length);
assertTrue(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor);
ConversionServiceExposingInterceptor interceptor = (ConversionServiceExposingInterceptor) chain.getInterceptors()[0];
interceptor.preHandle(request, response, handler);
assertSame(appContext.getBean("conversionService"), request.getAttribute(ConversionService.class.getName()));
RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class);
assertNotNull(adapter);
adapter.handle(request, response, handlerMethod);
}
/**
* parameter exception:TypeMismatchException
*/
@ResponseBody
@ExceptionHandler(value = TypeMismatchException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public BaseResponse typeMismatchExceptionHandler(TypeMismatchException ex) {
log.warn("catch typeMismatchException", ex);
RetCode retCode = new RetCode(ConstantCode.PARAM_EXCEPTION.getCode(), ex.getMessage());
BaseResponse bre = new BaseResponse(retCode);
log.warn("typeMismatchException return:{}", JsonTools.toJSONString(bre));
return bre;
}
/**
* 添加全局异常处理流程
*
* @param e
* @return
* @throws Exception
*/
@ResponseBody
@ExceptionHandler(Exception.class)
public ResponseDTO exceptionHandler(Exception e) {
log.error("error:", e);
// http 请求方式错误
if (e instanceof HttpRequestMethodNotSupportedException) {
return ResponseDTO.wrap(ResponseCodeConst.REQUEST_METHOD_ERROR);
}
// 参数类型错误
if (e instanceof TypeMismatchException) {
return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM);
}
// json 格式错误
if (e instanceof HttpMessageNotReadableException) {
return ResponseDTO.wrap(ResponseCodeConst.JSON_FORMAT_ERROR);
}
// 参数校验未通过
if (e instanceof MethodArgumentNotValidException) {
List<FieldError> fieldErrors = ((MethodArgumentNotValidException) e).getBindingResult().getFieldErrors();
List<String> msgList = fieldErrors.stream().map(FieldError :: getDefaultMessage).collect(Collectors.toList());
return ResponseDTO.wrap(ResponseCodeConst.ERROR_PARAM, String.join(",", msgList));
}
if (e instanceof SmartBusinessException) {
return ResponseDTO.wrap(ResponseCodeConst.SYSTEM_ERROR);
}
return ResponseDTO.wrap(ResponseCodeConst.SYSTEM_ERROR);
}
/**
* {@link TypeMismatchException}をハンドリングします。
* @param e {@link TypeMismatchException}
* @return {@link ErrorMessage}
* HTTPステータス 400 でレスポンスを返却します。
*/
@ExceptionHandler(TypeMismatchException.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@Override
public ErrorMessage handle(TypeMismatchException e) {
if (L.isDebugEnabled()) {
L.debug(R.getString("D-SPRINGMVC-REST-HANDLER#0008"), e);
}
ErrorMessage error = createClientErrorMessage(HttpStatus.BAD_REQUEST);
warn(error, e);
return error;
}
@Test // SPR-12903
public void nestedException() throws Exception {
Exception cause = new StatusCodeAndReasonMessageException();
TypeMismatchException ex = new TypeMismatchException("value", ITestBean.class, cause);
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertResolved(mav, 410, "gone.reason");
}
@Test
public void testMappingNullValue() throws Exception {
BeanPropertyRowMapper<Person> mapper = new BeanPropertyRowMapper<>(Person.class);
Mock mock = new Mock(MockType.TWO);
assertThatExceptionOfType(TypeMismatchException.class).isThrownBy(() ->
mock.getJdbcTemplate().query("select name, null as age, birth_date, balance from people", mapper));
}
@Override
protected Object readFromSource(Class<?> clazz, HttpHeaders headers, Source source) throws Exception {
Assert.notNull(this.unmarshaller, "Property 'unmarshaller' is required");
Object result = this.unmarshaller.unmarshal(source);
if (!clazz.isInstance(result)) {
throw new TypeMismatchException(result, clazz);
}
return result;
}
@Test
public void shouldConvertTypeMismatchExceptionToTYPE_CONVERSION_ERROR() throws Exception {
MvcResult result = this.mockMvc.perform(get("/clientFacingErrorTestDummy/validateRequiredInteger")
.param("someInt", "notaninteger")
).andReturn();
verifyErrorResponse(result, projectApiErrors, projectApiErrors.getTypeConversionApiError(), TypeMismatchException.class);
}
/**
* Verifies that a dependency on a {@link FactoryBean} can <strong>not</strong>
* be autowired <em>by name</em>, as & is an illegal character in
* Java method names. In other words, you can't name a method
* {@code set&FactoryBean(...)}.
*/
@Test(expected = TypeMismatchException.class)
public void testAutowireBeanWithFactoryBeanByName() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
lbf.registerBeanDefinition("factoryBean", bd);
LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
assertNotNull("The FactoryBean should have been registered.", factoryBean);
lbf.autowire(FactoryBeanDependentBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
}
@Test
public void nestedException() throws Exception {
Exception cause = new StatusCodeAndReasonMessageException();
TypeMismatchException ex = new TypeMismatchException("value", ITestBean.class, cause);
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertNotNull("No ModelAndView returned", mav);
assertTrue("No Empty ModelAndView returned", mav.isEmpty());
assertEquals("Invalid status code", 410, response.getStatus());
}
/**
* 400错误
*
* @param ex
* @return
*/
@ExceptionHandler({TypeMismatchException.class})
@ResponseBody
public Result requestTypeMismatch(TypeMismatchException ex) {
log.error("异常类 TypeMismatchException {},", ex.getMessage());
return Result.createWithErrorMessage("参数异常", ErrorConstants.PARAM_INCORRECT);
}
/**
* parameter exception:TypeMismatchException
*/
@ResponseBody
@ExceptionHandler(value = TypeMismatchException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public BaseRspVo typeMismatchExceptionHandler(TypeMismatchException ex) {
log.warn("catch typeMismatchException", ex);
CodeMessageEnums cme = CodeMessageEnums.PARAM_EXCEPTION;
cme.setMessage(ex.getMessage());
BaseRspVo bre = new BaseRspVo(cme);
log.warn("typeMismatchException return:{}", JsonUtils.toJSONString(bre));
return bre;
}
@Override
protected Object convertFromInternal(Message<?> message, Class<?> targetClass, Object conversionHint) {
Assert.notNull(this.unmarshaller, "Property 'unmarshaller' is required");
try {
Source source = getSource(message.getPayload());
Object result = this.unmarshaller.unmarshal(source);
if (!targetClass.isInstance(result)) {
throw new TypeMismatchException(result, targetClass);
}
return result;
}
catch (Exception ex) {
throw new MessageConversionException(message, "Could not unmarshal XML: " + ex.getMessage(), ex);
}
}
@ExceptionHandler({
MissingServletRequestParameterException.class,
ServletRequestBindingException.class,
TypeMismatchException.class,
HttpMessageNotReadableException.class,
MethodArgumentNotValidException.class,
MissingServletRequestPartException.class,
BindException.class,
ConstraintViolationException.class
})
public final Object handleSpringBadRequestException(Exception e, HandlerMethod handlerMethod) {
return logAndHandleException(e, BAD_REQUEST, handlerMethod);
}
@Override
@Nullable
public <T> T convertIfNecessary(@Nullable Object value, @Nullable Class<T> requiredType,
@Nullable MethodParameter methodParam) throws TypeMismatchException {
return getTypeConverter().convertIfNecessary(value, requiredType, methodParam);
}
private Map<Class, RestExceptionHandler> getDefaultHandlers() {
Map<Class, RestExceptionHandler> map = new HashMap<>();
map.put( NoSuchRequestHandlingMethodException.class, new NoSuchRequestHandlingMethodExceptionHandler() );
map.put( HttpRequestMethodNotSupportedException.class, new HttpRequestMethodNotSupportedExceptionHandler() );
map.put( HttpMediaTypeNotSupportedException.class, new HttpMediaTypeNotSupportedExceptionHandler() );
map.put( MethodArgumentNotValidException.class, new MethodArgumentNotValidExceptionHandler() );
if (ClassUtils.isPresent("javax.validation.ConstraintViolationException", getClass().getClassLoader())) {
map.put( ConstraintViolationException.class, new ConstraintViolationExceptionHandler() );
}
addHandlerTo( map, HttpMediaTypeNotAcceptableException.class, NOT_ACCEPTABLE );
addHandlerTo( map, MissingServletRequestParameterException.class, BAD_REQUEST );
addHandlerTo( map, ServletRequestBindingException.class, BAD_REQUEST );
addHandlerTo( map, ConversionNotSupportedException.class, INTERNAL_SERVER_ERROR );
addHandlerTo( map, TypeMismatchException.class, BAD_REQUEST );
addHandlerTo( map, HttpMessageNotReadableException.class, UNPROCESSABLE_ENTITY );
addHandlerTo( map, HttpMessageNotWritableException.class, INTERNAL_SERVER_ERROR );
addHandlerTo( map, MissingServletRequestPartException.class, BAD_REQUEST );
addHandlerTo(map, Exception.class, INTERNAL_SERVER_ERROR);
// this class didn't exist before Spring 4.0
try {
Class clazz = Class.forName("org.springframework.web.servlet.NoHandlerFoundException");
addHandlerTo(map, clazz, NOT_FOUND);
} catch (ClassNotFoundException ex) {
// ignore
}
return map;
}
/**
* Look up the JNDI object and store it.
*/
@Override
public void afterPropertiesSet() throws IllegalArgumentException, NamingException {
super.afterPropertiesSet();
if (this.proxyInterfaces != null || !this.lookupOnStartup || !this.cache || this.exposeAccessContext) {
// We need to create a proxy for this...
if (this.defaultObject != null) {
throw new IllegalArgumentException(
"'defaultObject' is not supported in combination with 'proxyInterface'");
}
// We need a proxy and a JndiObjectTargetSource.
this.jndiObject = JndiObjectProxyFactory.createJndiObjectProxy(this);
}
else {
if (this.defaultObject != null && getExpectedType() != null &&
!getExpectedType().isInstance(this.defaultObject)) {
TypeConverter converter = (this.beanFactory != null ?
this.beanFactory.getTypeConverter() : new SimpleTypeConverter());
try {
this.defaultObject = converter.convertIfNecessary(this.defaultObject, getExpectedType());
}
catch (TypeMismatchException ex) {
throw new IllegalArgumentException("Default object [" + this.defaultObject + "] of type [" +
this.defaultObject.getClass().getName() + "] is not of expected type [" +
getExpectedType().getName() + "] and cannot be converted either", ex);
}
}
// Locate specified JNDI object.
this.jndiObject = lookupWithFallback();
}
}
@Test // SPR-12903
public void nestedException() throws Exception {
Exception cause = new StatusCodeAndReasonMessageException();
TypeMismatchException ex = new TypeMismatchException("value", ITestBean.class, cause);
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertResolved(mav, 410, "gone.reason");
}
@Test
public void handleTypeMismatch() {
TypeMismatchException ex = new TypeMismatchException("foo", String.class);
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
assertNotNull("No ModelAndView returned", mav);
assertTrue("No Empty ModelAndView returned", mav.isEmpty());
assertEquals("Invalid status code", 400, response.getStatus());
}
/**
* Verifies that a dependency on a {@link FactoryBean} can <strong>not</strong>
* be autowired <em>by name</em>, as & is an illegal character in
* Java method names. In other words, you can't name a method
* {@code set&FactoryBean(...)}.
*/
@Test(expected = TypeMismatchException.class)
public void testAutowireBeanWithFactoryBeanByName() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
lbf.registerBeanDefinition("factoryBean", bd);
LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
assertNotNull("The FactoryBean should have been registered.", factoryBean);
lbf.autowire(FactoryBeanDependentBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
}
@Test
public void extractPropertyName_returns_null_for_base_TypeMismatchException() {
// given
TypeMismatchException exMock = mock(TypeMismatchException.class);
// when
String result = listener.extractPropertyName(exMock);
// then
assertThat(result).isNull();
}
/**
* Verifies that a dependency on a {@link FactoryBean} can <strong>not</strong>
* be autowired <em>by name</em>, as & is an illegal character in
* Java method names. In other words, you can't name a method
* {@code set&FactoryBean(...)}.
*/
@Test(expected = TypeMismatchException.class)
public void testAutowireBeanWithFactoryBeanByName() {
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
RootBeanDefinition bd = new RootBeanDefinition(LazyInitFactory.class);
lbf.registerBeanDefinition("factoryBean", bd);
LazyInitFactory factoryBean = (LazyInitFactory) lbf.getBean("&factoryBean");
assertNotNull("The FactoryBean should have been registered.", factoryBean);
lbf.autowire(FactoryBeanDependentBean.class, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, true);
}