package com.apobates.forum.thrones; import com.apobates.forum.thrones.controller.helper.StrategyCondition; import com.apobates.forum.attention.ImageStoreDomain; import com.apobates.forum.core.ImageIOMeta; import com.apobates.forum.member.storage.OnlineMemberStorage; import com.apobates.forum.member.storage.cookie.CookieMetaConfig; import com.apobates.forum.thrones.controller.helper.AuthenticationInterceptor; import com.apobates.forum.thrones.controller.helper.MemberInviteCodeInterceptorAdapter; import com.apobates.forum.thrones.controller.helper.OnlineDescriptorAspect; import com.apobates.forum.thrones.controller.helper.RegisteChannelInterceptor; import com.apobates.forum.thrones.controller.helper.StrategyInterceptorAdapter; import com.apobates.forum.thrones.rss.TopicRssView; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.http.MediaType; import org.springframework.validation.Validator; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.BeanNameViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; /** * 前端Spring MVC配置类 * * @author xiaofanku * @since 20200511 */ @Configuration @PropertySource(value = "classpath:global.properties", ignoreResourceNotFound = true, encoding = "UTF-8") @EnableWebMvc @EnableAspectJAutoProxy(proxyTargetClass=true) @ComponentScan(basePackages = {"com.apobates.forum.thrones.controller"}, useDefaultFilters = false, includeFilters = {@Filter(classes = {org.springframework.stereotype.Controller.class}),@Filter(classes = {org.springframework.stereotype.Component.class})}) @Import(value = {WebSocketConfig.class}) public class ThronesFrontConfig implements WebMvcConfigurer { @Value("${site.cookieSymbol}") private String cookieName; @Value("${site.cookieDomain}") private String cookieDomain; @Value("${site.cookiePath}") private String cookiePath; @Value("${site.domain}") private String siteDomain; @Value("${img.bucket.domain}") private String imageBucketDomain; @Value("${img.bucket.upload.direct}") private String imageBucketUploadDirect; @Value("${site.origin.admin}") private String adminDomain; //授权访问的拦截器 @Bean public AuthenticationInterceptor getAuthInter() { return new AuthenticationInterceptor(); } //注册通道检查拦截器 @Bean public RegisteChannelInterceptor getRegisInter() { return new RegisteChannelInterceptor(); } //策略检测拦截器,以Env(site.strategy)来控制开启,默认开启 @Bean @Conditional(StrategyCondition.class) public StrategyInterceptorAdapter getStrategyInter(){ return new StrategyInterceptorAdapter(); } //注册邀请码拦截器 @Bean public MemberInviteCodeInterceptorAdapter getInviteCodeInter(){ return new MemberInviteCodeInterceptorAdapter(); } //会员在线记录 aspectJ @Bean public OnlineDescriptorAspect getOnlineAspect() { //在线会员 return new OnlineDescriptorAspect(); } /** * 配置请求视图映射 * * @return */ @Bean public InternalResourceViewResolver resourceViewResolver() { InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); //请求视图文件的前缀地址 internalResourceViewResolver.setPrefix("/WEB-INF/layout/page/"); //请求视图文件的后缀 internalResourceViewResolver.setSuffix(".jsp"); internalResourceViewResolver.setViewClass(JstlView.class); return internalResourceViewResolver; } //静态资源映射 @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/static/").setCachePeriod(31536000); } //定义无Controller的path<->view直接映射 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("redirect:/home"); } //RSS @Bean(name = "topicRssView") public TopicRssView getRssView() { return new com.apobates.forum.thrones.rss.TopicRssView(); } //定义视图文件解析View resolvers @Override public void configureViewResolvers(ViewResolverRegistry registry) { BeanNameViewResolver beanResolver = new BeanNameViewResolver(); beanResolver.setOrder(1); registry.viewResolver(beanResolver); registry.viewResolver(resourceViewResolver()); registry.enableContentNegotiation(getRssView()); } //对静态资源文件的访问, 将无法mapping到Controller的path交给default servlet handler处理 @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } //注册媒体类型 @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.ignoreAcceptHeader(false) .favorPathExtension(true) .mediaType("json", MediaType.APPLICATION_JSON) .mediaType("xml", MediaType.APPLICATION_XML) .mediaType("rss", MediaType.APPLICATION_RSS_XML); } //拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { // 授权访问的拦截器 registry.addInterceptor(getAuthInter()).excludePathPatterns("/member/home/board/active/json", "/member/home/topic/publish/json", "/member/home/topic/reply/json").addPathPatterns("/member/home/**", "/message/**", "/topic/create", "/posts/create", "/posts/reply", "/search/"); // 注册通道检查拦截器 registry.addInterceptor(getRegisInter()).addPathPatterns("/member/register"); // 策略检测拦截器 registry.addInterceptor(getStrategyInter()).addPathPatterns("/board/**", "/posts/**", "/topic/**"); // 邀请码拦截器 registry.addInterceptor(getInviteCodeInter()).addPathPatterns("/member/register"); } //HV && BV @Override public Validator getValidator() { LocalValidatorFactoryBean lvfb = new org.springframework.validation.beanvalidation.LocalValidatorFactoryBean(); lvfb.setProviderClass(org.hibernate.validator.HibernateValidator.class); lvfb.setValidationMessageSource(messageSource()); return lvfb; } //To enable CORS for the whole application @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/member/home/topic/**").allowedMethods("GET").allowedOrigins(adminDomain); } @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); messageSource.setDefaultEncoding("UTF-8"); messageSource.setCacheSeconds(60); messageSource.setUseCodeAsDefaultMessage(false); return messageSource; } @Bean public static PropertySourcesPlaceholderConfigurer propertySourceConfigurer() { PropertySourcesPlaceholderConfigurer pp = new PropertySourcesPlaceholderConfigurer(); pp.setIgnoreUnresolvablePlaceholders(true); return pp; } /*apache fileupload @Bean(name = "multipartResolver") public MultipartResolver multipartResolver() { CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); commonsMultipartResolver.setDefaultEncoding("utf-8"); commonsMultipartResolver.setMaxUploadSize(maxBytes); commonsMultipartResolver.setResolveLazily(false); return commonsMultipartResolver; }*/ //Cookie @Bean(name = "cookieConfig") public CookieMetaConfig getCookieConfig() { CookieMetaConfig cnf = new com.apobates.forum.member.storage.cookie.CookieMetaConfig(cookieName, cookieDomain, cookiePath, siteDomain); return cnf; } @Bean(name = "onlineMemberStorage") public OnlineMemberStorage getMemberStorage(CookieMetaConfig cookieConfig) { return new com.apobates.forum.member.storage.cookie.HttpCookieProvider(cookieConfig); } @Bean(name="imageStoreDomain") public ImageStoreDomain getImageStore(){ return new com.apobates.forum.attention.ImageStoreDomain(){ @Override public String getDefaultDomain() { return imageBucketDomain; } @Override public String getLocalDomain() { return siteDomain; } }; } @Bean(name="imageIOMeta") public ImageIOMeta getImageIOMeta(){ return new com.apobates.forum.core.ImageIOMeta(){ @Override public String getImageBucketDomain() { return imageBucketDomain; } @Override public String getUploadImageDirectName() { return imageBucketUploadDirect; } }; } }