Spring扩展点
Spring扩展点
1.IOC生成类全名
<!-- 自动扫描且只扫描@Controller --> <context:component-scan base-package="cn.com.demo.**.controller" name-generator="cn.com.demo.framework.spring.context.annotation.FullNameBeanNameGenerator" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
public class FullNameBeanNameGenerator extends AnnotationBeanNameGenerator{ @Override protected String buildDefaultBeanName(BeanDefinition definition) { return definition.getBeanClassName(); } }
2.转换生成映射的URL大小写
<!-- 通过 @Controller 和 @RequestMapping 从url定位到类的方法, 自定义CoC实现, 不要再配置annotation-driven --> <bean class="cn.com.demo.framework.web.springmvc.support.CocRequestMappingHandlerMapping"> <property name="basePackage" value="cn.com.demo" /> </bean>
public class CocRequestMappingHandlerMapping extends RequestMappingHandlerMapping{ /** Controller类的后缀 */ private static final String CONTROLLER_SUFFIX = "Controller"; /** 映射url路径的根 */ private String basePackage; //父类的属性 private boolean useSuffixPatternMatch = true; private boolean useTrailingSlashMatch = true; private final List<String> fileExtensions = new ArrayList<String>(); /** * Look for handler methods in a handler. * @param handler the bean name of a handler or a handler instance */ protected void detectHandlerMethods(final Object handler) { //Assert.notNull(this.basePackage, "must config basePackage!"); super.detectHandlerMethods(handler); } /** * 这个只改了createRequestMappingInfo的调用,增加了参数 * Uses method and type-level @{@link RequestMapping} annotations to create * the RequestMappingInfo. * * @return the created RequestMappingInfo, or {@code null} if the method * does not have a {@code @RequestMapping} annotation. * * @see #getCustomMethodCondition(Method) * @see #getCustomTypeCondition(Class) */ @Override protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { RequestMappingInfo info = null; RequestMapping methodAnnotation = AnnotationUtils.findAnnotation(method, RequestMapping.class); if (methodAnnotation != null) { RequestCondition<?> methodCondition = getCustomMethodCondition(method); info = createRequestMappingInfo(methodAnnotation, methodCondition, method, handlerType); RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class); if (typeAnnotation != null) { RequestCondition<?> typeCondition = getCustomTypeCondition(handlerType); info = createRequestMappingInfo(typeAnnotation, typeCondition, method, handlerType).combine(info); } } return info; } /** * 将父类同名方法加入controller的类型和方法参数 */ private RequestMappingInfo createRequestMappingInfo(RequestMapping annotation, RequestCondition<?> customCondition, Method method, Class<?> handlerType) { String[] patterns = resolveEmbeddedValuesInPatterns(annotation.value()); //@RequestMapping没有配置value, 加入coc部分 if( patterns.length==0 ){ StringBuilder p = new StringBuilder(); if (this.basePackage != null) { String packageName = ClassUtils.getPackageName(handlerType); if (packageName.startsWith(this.basePackage)) { String subPackage = packageName.substring(this.basePackage.length()).replace('.', '/'); if( subPackage.endsWith("/controller") ){ //去掉/backup/controller的 /controller subPackage = subPackage.substring(0,subPackage.indexOf("/controller")); } p.append(subPackage.toLowerCase()); p.append("/"); } } //类名去掉后缀小写 String className = handlerType.getSimpleName(); className = (className.endsWith(CONTROLLER_SUFFIX) ? className.substring(0, className.lastIndexOf(CONTROLLER_SUFFIX)) : className); p.append(className.toLowerCase()).append("/");//类名小写 p.append(method.getName().toLowerCase());//方法名小写 patterns = new String[]{p.toString()}; } return new RequestMappingInfo( new PatternsRequestCondition(patterns, getUrlPathHelper(), getPathMatcher(), this.useSuffixPatternMatch, this.useTrailingSlashMatch, this.fileExtensions), new RequestMethodsRequestCondition(annotation.method()), new ParamsRequestCondition(annotation.params()), new HeadersRequestCondition(annotation.headers()), new ConsumesRequestCondition(annotation.consumes(), annotation.headers()), new ProducesRequestCondition(annotation.produces(), annotation.headers(), getContentNegotiationManager()), customCondition); } //----------------------set get public void setBasePackage(String basePackage) { this.basePackage = basePackage; } public void setUseSuffixPatternMatch(boolean useSuffixPatternMatch) { this.useSuffixPatternMatch = useSuffixPatternMatch; } public void setUseTrailingSlashMatch(boolean useTrailingSlashMatch) { this.useTrailingSlashMatch = useTrailingSlashMatch; } }
3.参数自定义类型转换
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer"> <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="conversionService"> <bean class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="cn.com.demo.framework.spring.core.convert.converter.StringToDateConverter"/> </list> </property> </bean> </property> </bean> </property> <property name="customArgumentResolvers"> <list> <bean class="cn.com.demo.framework.web.springmvc.support.method.support.crud.CrudHandlerMethodArgumentResolver"/> </list> </property> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8" /> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="serializers"> <array> <bean class="cn.com.demo.canyin.common.springmvc.converter.json.LongToStringJsonSerializer" /> </array> </property> <property name="dateFormat"> <bean class="java.text.SimpleDateFormat"> <constructor-arg value="yyyy-MM-dd'T'HH:mm:ss.SSS" /> </bean> </property> </bean> </property> </bean> <bean class="org.springframework.http.converter.ResourceHttpMessageConverter" /> </list> </property> </bean>
public class StringToDateConverter implements Converter<String, Date>{ @Override public Date convert(String source) { if( source==null || source.length()==0 ) return null; int length = source.length(); switch (length) { case 5: return parse("HH:mm", source); case 10: return parse("yyyy-MM-dd", source); case 19: case 21: case 22: return parse("yyyy-MM-dd HH:mm:ss", source); case 23: return parse("yyyy-MM-dd'T'HH:mm:ss.SSS", source); case 28: try { return new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy", Locale.US).parse(source); } catch (ParseException e) { throw new RuntimeException("时间转换格式异常,datestr:" + source, e); } default: throw new RuntimeException("Unsupport Date Format: " + source); } } /** * 解析date */ private Date parse(String format, String date){ try { return new SimpleDateFormat(format).parse(date); } catch (ParseException e) { throw new RuntimeException(e); } } } public class CrudHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver{ @Override public boolean supportsParameter(MethodParameter parameter) { Class<?> paramType = parameter.getParameterType(); return QueryParam.class.isAssignableFrom(paramType); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { Class<?> paramType = parameter.getParameterType(); //查询参数 QueryParam p = parseQueryParam(parameter, webRequest); return p; } /** * <b>功能描述:</b>解析查询参数<br> */ @SuppressWarnings("serial") private QueryParam parseQueryParam(MethodParameter parameter, NativeWebRequest webRequest){ QueryParam p = new QueryParam(); //分页参数 p.setStart(getInteger(webRequest, "start")); p.setLimit(getInteger(webRequest, "limit")); String sort = webRequest.getParameter("sort"); if(StringUtils.isNotBlank(sort)){ SortExpression[] orderBy = JsonConverterUtils.getJc().fromJson(sort, SortExpression[].class); DefaultConvertName dcn = new DefaultConvertName(); orderBy[0].setProperty(dcn.convertToColumnName(orderBy[0].getProperty())); p.setSort(orderBy[0].toSqlString()); } return p; } /** * 获取整数参数 */ private Integer getInteger(NativeWebRequest webRequest, String name){ String p = webRequest.getParameter(name); if( p==null || p.length()==0 ) return null; return Integer.valueOf(p); } /** * 如果是get方法, 编码参数 */ private String encodeParameter(NativeWebRequest webRequest, String paramName){ HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); String p = webRequest.getParameter(paramName); if( "GET".equalsIgnoreCase(request.getMethod())){ return RequestUtil.encodeParameter(p); } return p; } } public class LongToStringJsonSerializer extends JsonSerializer<Long> { @Override public Class<Long> handledType() { return Long.class; } @Override public void serialize(Long value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(value.toString()); } }
4.自定义异常拦截器
<!-- mvc exception handler --> <bean id="handlerExceptionResolver" class="cn.com.demo.framework.enterprise.spring.web.ProjectHandlerExceptionResolver"></bean>
public class ProjectHandlerExceptionResolver implements HandlerExceptionResolver{ private final Logger logger = LoggerFactory.getLogger(getClass()); /** json 转换 */ @Resource private JsonConverter jsonConverter; @Resource private LogManageService logManageService; @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { return null; } /** * <b>功能描述:</b> * 是否ExtForm的StandardSubmit模式<br> * 前台需要额外传入X-Requested-With的参数来说明本次提交为StandardSubmit */ private boolean isExtFormStandardSubmit(HttpServletRequest request){ return request.getParameter("X-Requested-With")!=null; } }
相关推荐
yupi0 2020-10-10
spring 2020-08-18
编程点滴 2020-07-29
幸运小侯子 2020-07-05
itjavashuai 2020-07-04
qingjiuquan 2020-06-29
shushan 2020-06-25
小鱿鱼 2020-06-22
咻pur慢 2020-06-18
melonjj 2020-06-17
qingjiuquan 2020-06-13
neweastsun 2020-06-05
小鱿鱼 2020-06-05
mxcsdn 2020-05-31
吾日五省我身 2020-05-27
牧场SZShepherd 2020-05-27
sweetgirl0 2020-05-14