当前位置: 首页 > news >正文

建一个购物网站多少钱凡科网站官网登录入口

建一个购物网站多少钱,凡科网站官网登录入口,沈阳做手机网站的公司,163企业邮箱设置文章目录 0. 前言i18n-spring-boot-starter1. 使用方式0.引入依赖1.配置项2.初始化国际化配置表3.如何使用 2. 核心源码实现一个拦截器I18nInterceptorI18nMessageResource 加载国际化配置 3.源码地址 0. 前言 写个了原生的SpringBoot国际化配置组件支持本地配置和数据库配置 背… 文章目录 0. 前言i18n-spring-boot-starter1. 使用方式0.引入依赖1.配置项2.初始化国际化配置表3.如何使用 2. 核心源码实现一个拦截器I18nInterceptorI18nMessageResource 加载国际化配置 3.源码地址 0. 前言 写个了原生的SpringBoot国际化配置组件支持本地配置和数据库配置 背景最近花时间把项目用到的国际化组件Starter 重构了一下使用更简单。基本上支持从本地配置读取和数据库配置读取支持web端和小程序等移动端的国际化需求。 i18n-spring-boot-starter 1. 使用方式 Spring Boot 国际化组件 0.引入依赖 代码在本地打包后 给需要国际化的工程引入 dependencygroupIdcom.bdkjzx.project/groupIdartifactIdi18n-spring-boot-starter/artifactIdversion0.0.1-SNAPSHOT/version /dependency1.配置项 #添加国际化 spring.ex.i18n.enabletrue # 如果未翻译是否将code 初始化入库 spring.ex.i18n.markfalse spring.ex.i18n.default-localezh-CN spring.ex.i18n.data-sourceprimary spring.ex.i18n.config-tableconfig_i18n_message2.初始化国际化配置表 CREATE TABLE config_i18n_message (code varchar(128) NOT NULL,zh-CN varchar(128) DEFAULT NULL,zh-TW varchar(128) DEFAULT NULL,en-US varchar(1024) DEFAULT NULL COMMENT 英文,PRIMARY KEY (code) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci ROW_FORMATDYNAMIC COMMENT国际化配置表 如果本地配置的话使用原生配置方式.缺点是需要手动更新并且每个服务都需要配置。建议使用数据库表配置 messages_zh_CN.properties , messages_en_US.properties 3.如何使用 I.n(操作成功)或者在返回的统一结果对象上,以下是个示例你需要加在你的项目的统一响应中 public class ApiResponseT {private int code;private String message;private T data;private ErrorDetails error;public ApiResponse() {}/*** message给消息进行国际化包装* param message*/public ApiResponse(int code, String message, T data, ErrorDetails error) {this.code code;this.message I.n(message);this.data data;this.error error;}// Getter and Setter methodspublic int getCode() {return code;}public void setCode(int code) {this.code code;}public String getMessage() {return message;}/*** 给消息进行国际化包装* param message*/public void setMessage(String message) {this.message I.n(message);}public T getData() {return data;}public void setData(T data) {this.data data;}public ErrorDetails getError() {return error;}public void setError(ErrorDetails error) {this.error error;} } 5.扩展请看入口 com.bdkjzx.project.i18n.config.I18nAutoConfig2. 核心源码 package com.bdkjzx.project.i18n.config;import com.bdkjzx.project.i18n.I18nHolder; import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties;ConfigurationProperties(prefix spring.ex.i18n) Setter Getter public class I18nProperties {/*** 是否启用国际化功能br* - 启用会创建和国际化相关的数据源、缓存等等br* - 不启用{link I18nHolder} 可以正常使用返回原值不会创建国际化相关的各种Beanbr** 默认不启用需要手动开启*/private Boolean enable false;/*** 国际化数据表所在的数据源入需指定则写入数据源名称。br* 此配置的作用是允许多个服务通过共享一个i18n配置表从而共用一套i18n翻译。br* 默认为空表示使用primary数据源。*/private String dataSource primary;/*** 默认地区语言*/private String defaultLocale zh_CN;/*** 查询i18n配置表的名称用于自定义修改表。br* 默认config_i18n_message*/private String configTable config_i18n_message;/*** i18n配置表的字段名。根据i18n配置表决定此配置br* 默认code*/private String configCodeColumn code;/*** i18n缓存更新时间小时数会提供手工刷新缓存的入口所以不必频繁刷新br* 默认值为-1表示长期有效。br*/private Integer cacheHours -1;/*** 当未找到i18n的code时是否将其记录到表中以便统一处理br* 默认关闭*/private Boolean mark false;/*** 用于记录无效code的线程池缓冲区大小*/private Integer markPoolSize 2000;/*** 是否在 {link com.bdkjzx.project.i18n.repository.I18nMessageResource} 未找到配置时再使用Spring默认方案* 从本地加载国际化资源。* 默认关闭*/private Boolean useLocale false;} package com.bdkjzx.project.i18n.config;import com.bdkjzx.project.i18n.I18nHolder; import com.bdkjzx.project.i18n.filter.I18nFilter;import com.bdkjzx.project.i18n.repository.*; import lombok.extern.slf4j.Slf4j; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.context.MessageSourceProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.caffeine.CaffeineCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import com.bdkjzx.project.i18n.interceptor.I18nInterceptor;import javax.sql.DataSource; import java.util.Locale; import java.util.concurrent.Executor;Configuration EnableConfigurationProperties({I18nProperties.class}) Slf4j public class I18nAutoConfig {Beanpublic I18nHolder getI18nUtil(Autowired(required false) I18nMessageResource messageSource,Autowired(required false) I18nLocaleHolder i18nLocaleHolder,Autowired I18nProperties i18NProperties) {// 不论是否启用都会配置保证这个工具类不会报错return i18NProperties.getEnable() ? new I18nHolder(messageSource, i18nLocaleHolder) : new I18nHolder();}ConditionalOnProperty(prefix spring.ex.i18n, name enable, havingValue true)Configurationstatic class I18nFilterConfig {Autowiredprivate I18nLocaleHolder i18nLocaleHolder;Beanpublic I18nFilter i18nFilter() {I18nFilter i18nFilter new I18nFilter();I18nInterceptor interceptor new I18nInterceptor();interceptor.setI18nLocaleHolder(i18nLocaleHolder);i18nFilter.setI18nInterceptor(interceptor);return i18nFilter;}}ConditionalOnProperty(prefix spring.ex.i18n, name enable, havingValue true)ConfigurationEnableCachingComponentScan(com.bdkjzx.project.i18n)static class I18nResourceConfig {/*** 采用默认的配置文件配置 messages开头的文件编码为utf8br* 如 messages_zh_CN.properties , messages_en_US.properties** return {link MessageSourceProperties}*/Beanpublic MessageSourceProperties messageSourceProperties() {return new MessageSourceProperties();}Beanpublic ResourceBundleMessageSource initResourceBundleMessageSource(MessageSourceProperties messageSourceProperties) {ResourceBundleMessageSource resourceBundleMessageSource new ResourceBundleMessageSource();resourceBundleMessageSource.setBasename(messageSourceProperties.getBasename());resourceBundleMessageSource.setDefaultEncoding(messageSourceProperties.getEncoding().name());return resourceBundleMessageSource;}BeanAutowiredpublic I18nMessageResource initMessageResource(ResourceBundleMessageSource resourceBundleMessageSource,I18nLocaleHolder i18NLocaleSettings) {I18nMessageResource i18nMessageResource new I18nMessageResource(i18NLocaleSettings.getDefaultLocale());i18nMessageResource.setParentMessageSource(resourceBundleMessageSource);return i18nMessageResource;}BeanAutowiredpublic I18nLocaleHolder getI18nLocaleSetting(I18nProperties i18nProperties) {Locale locale;try {locale new Locale.Builder().setLanguageTag(i18nProperties.getDefaultLocale().replace(_, -).toLowerCase()).build();} catch (Exception e) {log.error(String.format(解析默认语言时出现错误, setting %s, i18nProperties.getDefaultLocale()), e);throw new IllegalArgumentException(解析默认语言时出现错误请查看日志);}return new I18nLocaleHolder(locale);}Bean(name i18nJdbcTemplate)ConditionalOnMissingBean(name i18nJdbcTemplate)public JdbcTemplate getJdbcTemplate(Autowired(required false) Qualifier(i18nDataSource) DataSource i18nDataSource) {try {if (i18nDataSource null) {log.error(未配置国家化数据源,请使用Bean构造一个名为i18nDataSource的DataSource或者直接重新此方法);}return new JdbcTemplate(i18nDataSource);} catch (BeansException e) {log.error(无效的数据源{}, i18nDataSource, e);throw new IllegalArgumentException(创建数据源时出现错误请查看日志);}}AutowiredBean(name defaultI18nDataLoadService)public I18nConfigDbLoader getI18nDataLoadService(I18nProperties i18nProperties,Qualifier(i18nJdbcTemplate) JdbcTemplate jdbcTemplate) {return new SimpleI18NConfigDbLoaderImpl(i18nProperties.getConfigCodeColumn(),i18nProperties.getConfigTable(), jdbcTemplate);}AutowiredBean(name i18nCacheManager)public CacheManager getCacheManager(I18nProperties i18nProperties) {CaffeineCacheManager caffeineCacheManager new CaffeineCacheManager();if (i18nProperties.getCacheHours() 0) {// 缓存创建后经过固定时间小时更新caffeineCacheManager.setCacheSpecification(String.format(refreshAfterWrite%sH, i18nProperties.getCacheHours()));}return caffeineCacheManager;}/*** 线程池配置*/ConditionalOnProperty(prefix spring.ex.i18n, name mark, havingValue true)ConfigurationEnableAsyncstatic class I18nInvalidMarkerConfig {Bean(i18nExecutor)Autowiredpublic Executor getAsyncExecutor(I18nProperties i18NProperties) {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();executor.setCorePoolSize(0);executor.setMaxPoolSize(2);executor.setQueueCapacity(i18NProperties.getMarkPoolSize());executor.setThreadNamePrefix(i18n-executor-);executor.initialize();return executor;}Beanpublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return new SimpleAsyncUncaughtExceptionHandler();}}}}实现一个拦截器I18nInterceptor 作用是实现国际化i18n功能的拦截器。用于处理Web应用程序的国际化即根据用户的语言设置显示对应的国际化资源文件。 从请求的cookie或header中获取语言设置。将语言设置存储到i18nLocaleHolder中以便在后续的请求处理中使用。在请求处理完成后清除i18nLocaleHolder中的语言设置。 package com.bdkjzx.project.i18n.interceptor;import com.bdkjzx.project.i18n.repository.I18nLocaleHolder; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.springframework.lang.NonNull; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.*;import static org.slf4j.LoggerFactory.getLogger;/*** 国际化拦截器用于处理Web应用的国际化i18n。*/ Slf4j public class I18nInterceptor implements HandlerInterceptor {private I18nLocaleHolder i18nLocaleHolder;private final MapString, Locale localeMap new HashMap(8);private static final String NAME_OF_LANGUAGE_SETTING lang;/*** 在实际处理程序方法调用之前执行的预处理方法。* 从请求的cookie或header中获取语言设置并将其设置到i18nLocaleHolder中。* 如果语言设置为空或无效则返回true以允许请求继续进行。*/Overridepublic boolean preHandle(NonNull HttpServletRequest request, NonNull HttpServletResponse response, NonNull Object handler) throws Exception {String lang getLangFromCookies(request);if (StringUtils.isEmpty(lang)) {lang getLangFromHeader(request);}if (StringUtils.isEmpty(lang)) {return true;}try {i18nLocaleHolder.setThreadLocale(getLocaleByLang(lang));} catch (Exception e) {log.error(无效的语言设置{}, lang, e);}return true;}/*** 在完成请求处理后执行的方法。* 清除i18nLocaleHolder中的语言设置。*/Overridepublic void afterCompletion(NonNull HttpServletRequest request, NonNull HttpServletResponse response, NonNull Object handler, Exception ex) {try {i18nLocaleHolder.clear();} catch (Exception e) {log.error(清理语言设置时遇到错误, e);}}public I18nLocaleHolder getI18nLocaleHolder() {return i18nLocaleHolder;}public void setI18nLocaleHolder(I18nLocaleHolder i18nLocaleHolder) {this.i18nLocaleHolder i18nLocaleHolder;}/*** 根据语言设置获取Locale对象。** param lang 语言设置* return Locale对象*/private Locale getLocaleByLang(String lang) {return Optional.ofNullable(localeMap.get(lang)).orElseGet(() - {Locale locale new Locale.Builder().setLanguageTag(lang).build();localeMap.put(lang, locale);return locale;});}/*** 从cookie中获取国际化语言设置。** param request HttpServletRequest对象* return 国际化语言设置*/private static String getLangFromCookies(HttpServletRequest request) {String lang Optional.ofNullable(request.getCookies()).flatMap(cookies - Arrays.stream(cookies).filter(cookie - NAME_OF_LANGUAGE_SETTING.equals(cookie.getName())).findFirst()).map(Cookie::getValue).orElse();return lang;}/*** 从header中获取国际化语言设置。** param request HttpServletRequest对象* return 国际化语言设置*/private String getLangFromHeader(HttpServletRequest request) {String acceptLanguage request.getHeader(Accept-Language);return Optional.ofNullable(acceptLanguage).map(lang - lang.split(,)).filter(array - array.length 0).map(array - array[0]).orElse();}}I18nMessageResource 加载国际化配置 支持本地和数据库 package com.bdkjzx.project.i18n.repository;import com.bdkjzx.project.i18n.config.I18nProperties; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.annotation.Lazy; import org.springframework.context.support.AbstractMessageSource; import org.springframework.core.io.ResourceLoader; import org.springframework.lang.NonNull; import org.springframework.util.StringUtils;import javax.annotation.PostConstruct; import java.text.MessageFormat; import java.util.*; import java.util.function.BiFunction;Slf4j public class I18nMessageResource extends AbstractMessageSource implements ResourceLoaderAware {private final Locale defaultLocale;Autowiredprivate ListI18nConfigDbLoader i18NConfigDbLoaders;Autowiredprivate I18nProperties i18NProperties;LazyAutowired(required false)private I18nConfigDbLoader i18nConfigDbLoader;private final ListBiFunctionString, Locale, String getTextFunctionList new ArrayList();public I18nMessageResource(Locale defaultLocale) {this.defaultLocale defaultLocale;}PostConstructpublic void init() {if (this.i18NProperties.getEnable()) {getTextFunctionList.add(this::normalFinder);getTextFunctionList.add(this::languageFinder);getTextFunctionList.add(this::defaultLocaleFinder);if (i18NProperties.getUseLocale() getParentMessageSource() ! null) {getTextFunctionList.add(this::localFinder);getTextFunctionList.add(this::localDefaultFinder);}}}Overridepublic void setResourceLoader(NonNull ResourceLoader resourceLoader) {}Overrideprotected MessageFormat resolveCode(NonNull String code, NonNull Locale locale) {String msg getText(code, locale);return createMessageFormat(msg, locale);}Overrideprotected String resolveCodeWithoutArguments(NonNull String code, NonNull Locale locale) {return getText(code, locale);}/*** 这是加载国际化变量的核心方法先从自己控制的内存中取取不到了再到资源文件中取** param code 编码* param locale 本地化语言* return 查询对应语言的信息*/private String getText(String code, Locale locale) {String result getTextWithOutMark(code, locale);if (StringUtils.isEmpty(result)) {return result;}// 确实没有这项配置确定是否要记录logger.warn(未找到国际化配置 code);if (i18NProperties.getMark()) {i18nConfigDbLoader.markInvalidCode(code);}//如果最终还是取不到返回了NULL则外面会用默认值如果没有默认值最终会返回给页面变量名称,所以变量名称尽量有含义以作为遗漏配置的最后保障return code;}public String getTextWithOutMark(String code, Locale locale) {String result ;// 从 function list中依次使用各种策略查询for (BiFunctionString, Locale, String func : getTextFunctionList) {result func.apply(code, locale);if (!StringUtils.isEmpty(result)) {return result;}}return result;}/*** 从指定locale获取值** param code i18n code* param locale 语言* return 查询对应语言的信息*/private String findValueFromLocale(String code, Locale locale) {String resultValue;for (I18nConfigDbLoader i18NConfigDbLoader : i18NConfigDbLoaders) {// 在loadE6I18nDictByLocaleEntity中做过缓存了resultValue Optional.ofNullable(i18NConfigDbLoader.loadI18nDictByLocaleEntity()).flatMap(localeMap - Optional.ofNullable(localeMap.get(locale)).map(codeMap - codeMap.get(code))).orElse(null);if (!org.springframework.util.StringUtils.isEmpty(resultValue)) {return resultValue;}}return null;}// 查询字符的五种策略加入function list /*** 第一种情况通过期望的语言类型查找** param code 国际化代码* param locale 语言* return 没找到时返回null*/private String normalFinder(String code, Locale locale) {return findValueFromLocale(code, locale);}/*** 第二种情况如果期望是 语言-国家 没有找到那么尝试只找一下语言,比如zh-tw没找到那就尝试找一下zh** param code 国际化代码* param locale 语言* return 没找到时返回null*/private String languageFinder(String code, Locale locale) {if (locale.getLanguage() ! null) {return findValueFromLocale(code, Locale.forLanguageTag(locale.getLanguage()));}return null;}/*** 第三种情况如果没有找到 且不是默认语言包则取默认语言包** param code 国际化代码* param locale 语言* return 没找到时返回null*/private String defaultLocaleFinder(String code, Locale locale) {if (!Objects.equals(locale, defaultLocale)) {return findValueFromLocale(code, defaultLocale);}return null;}/*** 第四种情况通过以上三种方式都没找到那么尝试从本地配置文件加载期望的语言类型是否有** param code 国际化代码* param locale 语言* return 没找到时返回null*/private String localFinder(String code, Locale locale) {String value Objects.requireNonNull(getParentMessageSource()).getMessage(code, null, null, locale);if (logger.isDebugEnabled() !StringUtils.isEmpty(value)) {logger.debug(从配置文件 locale.toString() 找到变量 code value);}return value;}/*** 第五种情况如果没有找到则从本地配置文件加载默认的语言类型是否有** param code 国际化代码* param locale 语言* return 没找到时返回null*/private String localDefaultFinder(String code, Locale locale) {if (!Objects.equals(locale, defaultLocale)) {return this.localFinder(code, defaultLocale);}return null;}}pom 文件 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.bdkjzx.project/groupIdartifactIdi18n-spring-boot-starter/artifactIdversion0.0.1-SNAPSHOT/versionnamei18n-spring-boot-starter/namedescriptionSpring boot 国际化配置/descriptionpropertiesjava.version8/java.versionjava.version1.8/java.versionproject.build.sourceEncodingUTF-8/project.build.sourceEncoding!--版本支持到2.7.x--spring-boot.version2.0.3.RELEASE/spring-boot.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-cache/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependency/dependencies dependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion${spring-boot.version}/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdconfigurationsource8/sourcetarget8/target/configuration/plugin/plugins/build/project3.源码地址 https://github.com/wangshuai67/i18n-spring-boot-starter/ 大家好我是冰点今天的原生的SpringBoot国际化配置组件支持本地配置和数据库配置 内容分享就到这儿写的有点粗糙。如果你有疑问或见解可以在评论区留言。
http://www.dnsts.com.cn/news/63710.html

相关文章:

  • 越秀学校网站建设国际本科
  • ui下载高清素材的网站有哪些网站嵌入地图
  • 甘肃找人做网站多少钱网站页面前端基本设计
  • 视频网站开发者工具北京建设网官方网站
  • 网站被很多公司抄袭做新房什么网站好
  • 电子商务网站网络安全设计方案网站网站娱乐建设
  • 建网站维护需要多少钱黄山市住房城乡建设厅网站
  • 郑州网站建设 app开发深圳平台设计
  • 提供邯郸网站建设app网站建设源码
  • 网站数据库如何导入数据库文件网络推广公司哪里好
  • 网站开发工程师优势有没有人通过网站建设卖东西的
  • 山东省建设监理协会网站打不开编程自己做网站
  • 建设银行东四十条支行支行网站竞价推广平台
  • 详谈电商网站建设四大流程原创文章代写
  • 网站建设有利点婚纱网站设计图
  • 网站平台策划书郑州厉害的seo顾问
  • 有源代码如何做网站漂亮的网站建设中静态页
  • 湖南省建设银行网站官网wordpress 浏览缓慢
  • 蓝牙音箱东莞网站建设设计一个网页大概多少钱
  • 公司网站建设服务费怎么做账什么叫网络服务商
  • 工程师招聘网站淄博网站建设 很乱
  • 民治做网站的公司推荐几个安全没封的网站
  • 做博客网站如何盈利泉州做网站的公司
  • 福田响应式网站建设服务上位机软件开发平台
  • 沈阳做网站的互联网公司如何做文化传播公司网站
  • 开个做网站的公司 知乎中国城镇建设网站
  • 建站公司经营行业网站推广怎么做
  • 永久免费做网站网站建设发生的费用会计科目
  • 公司网站怎么做才高大上中山建设信息网
  • 网站开发公司能不能去wordpress 系统安装教程