设为首页 收藏本站
查看: 1026|回复: 0

[经验分享] springmvc+spring-security+mybatis +redis +solar框架抽取

[复制链接]

尚未签到

发表于 2017-3-1 10:39:29 | 显示全部楼层 |阅读模式
  参考文章:Spring MVC 3 深入总结;
  第二章 Spring MVC入门 —— 跟开涛学SpringMVC
  参考博客:http://www.cnblogs.com/liukemng/category/578644.html
  controller层配置文件介绍:
   DSC0000.png
  一.springmvc 配置;
  具体原理参考文章:  Spring MVC 3 深入总结
  web.xml配置文件如下:


DSC0001.gif DSC0002.gif


<!-- Spring MVC 控制器 -->
<servlet>
<servlet-name>SpringDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- spring mvc 配置文件的路径 -->
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<!-- 是启动顺序,让这个Servlet随Servletp容器一起启动 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Spring MVC 映射配置拦截器 -->
<servlet-mapping>
<servlet-name>SpringDispatcherServlet</servlet-name>  
<!-- 拦截/,例如:/user/add,弊端:对jpg,js,css静态文件的访问也被拦截,静态文件需另写拦截器,且放在该拦截器前面 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
web.xml中配置指定springmvc控制器,拦截/  其中<param-value>**.xml</param-value> 这里可以使用多种写法
1、不写,使用默认值:/WEB-INF/<servlet-name>-servlet.xml
2、<param-value>/WEB-INF/classes/spring/servlet-context.xml</param-value>
3、<param-value>classpath*:/spring/servlet-context.xml</param-value>
4、多个值用逗号分隔
  Spring MVC 映射配置拦截器 无法访问静态的文件,如jpg,js,css等,主要采用:激活Tomcat的defaultServlet来处理静态文件的方法;其中 Tomcat, Jetty, JBoss, and GlassFish  默认 Servlet的名字 -- "default"
  因此静态文件的拦截器,要写在DispatcherServlet的前面, 让 defaultServlet先拦截,这个就不会进入Spring了,性能最佳;
  在web.xml中加配置如下:





<!-- Spring MVC 控制器 -->
<servlet>
<servlet-name>SpringDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- spring mvc 配置文件的路径 -->
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<!-- 是启动顺序,让这个Servlet随Servletp容器一起启动 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Spring MVC 映射配置拦截器 -->
<servlet-mapping>
<servlet-name>SpringDispatcherServlet</servlet-name>  
<!-- 拦截/,例如:/user/add,弊端:对jpg,js,css静态文件的访问也被拦截,静态文件需另写拦截器,且放在该拦截器前面 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
web.xml配置静态文件:js,css等的拦截器  其中springmvc配置文件:servlet-context.xml主要内容如下:





<!-- 扫描控制层所在的包中的类上的注解 -->
<context:component-scan base-package="com.springmvc.controller.**" />
<!-- 默认的注解映射的支持 :会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean-->  
<mvc:annotation-driven />
<!-- 对静态资源文件的访问-->
<mvc:default-servlet-handler/>
<!-- 拦截器 -->
<mvc:interceptors>
<!-- 对应代码中拦截器类 -->
<bean class="com.springmvc.common.controller.AuthenticationInerceptor">
<!-- 对应代码中拦截器类 中属性-->
<property name="fileUri" value="${file_uri}"></property>
</bean>
</mvc:interceptors>
<!-- 视图解释类 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
<property name="order" value="2" />
</bean>
springmvc自身的配置文件  解释如下:
  1.<context:component-scan/> 扫描指定的包中的类上的注解,常用的注解有:
   @Controller 声明Action组件

@Service    声明Service组件    @Service("myMovieLister")

@Repository 声明Dao组件

@Component   泛指组件, 当不好归类时.

@RequestMapping("/menu")  请求映射

@Resource  用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName")

@Autowired 用于注入,(srping提供的) 默认按类型装配

@Transactional( rollbackFor={Exception.class}) 事务管理

@ResponseBody

@Scope("prototype")   设定bean的作用域
  2.<mvc:annotation-driven /> 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学都快速应用默认配置方案。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。并提供了:数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)
  3.<mvc:interceptors/>拦截器
  4.<mvc:default-servlet-handler/> 使用默认的Servlet来响应静态文件
  二.加入拦截器;
  在servlet-context.xml中加拦截器配置文件





<!-- 拦截器 -->
<mvc:interceptors>
<!-- 对应代码中拦截器类 -->
<bean class="com.springmvc.common.controller.AuthenticationInerceptor">
<!-- 对应代码中拦截器类 中属性-->
<property name="fileUri" value="${file_uri}"></property>
</bean>
</mvc:interceptors>
springmvc配置文件中加拦截器配置  具体拦截器类内容见文件:com.springmvc.common.controller.AuthenticationInerceptor
  拦截器原理以及参考文章见:SpringMVC中使用Interceptor拦截器
  三.加入spring 业务层+加入mybatis

  1.在上下文配置文件applicationContext.xml中,加入spring封装业务层的配置文件;





<!--加spring 业务层配置:把spring-service.xml放在controller层  -->
<!--<import resource="spring/spring-service.xml" />  -->
<!--加spring 业务层配置:如果按业务分类有多个service层时把spring-service-s1.xml放在各种service层  -->
<import resource="classpath*:spring/spring-service-*.xml"/>
上下文配置文件中引入spring封装业务层的配置文件  2.spring封装业务层配置文件如下:





<!-- 基础服务层包 -->
<context:component-scan base-package="com.springmvc.service" />
<!-- 基础dao包 -->
<context:component-scan base-package="com.springmvc.dao" />
<!-- redis包 -->
<context:component-scan base-package="com.springmvc.redis" />
<!-- Spring应用上下文持有器 -->
<bean class="com.springmvc.common.util.SpringContextHolder"></bean>
<!-- 加载配置文件,该配置文件中 有线程池的配置信息:threadpool.coreSize和 threadpool.maxSize-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="2" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
<!-- 线程池的配置 -->
<bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="${threadpool.coreSize}" />
<property name="keepAliveSeconds" value="200" />
<property name="maxPoolSize" value="${threadpool.maxSize}" />
</bean>
<!-- 业务层的事务配置文件 -->
<import resource="classpath*:spring/spring-pms-transaction.xml"/>
<!-- 业务层的redis缓存配置文件 -->
<import resource="classpath*:spring/spring-pms-redis.xml"/>
<!-- 加载各服务层的配置文件 -->
<import resource="classpath*:spring/service-*.xml"/>
spring业务层配置文件  解释如下:
  <context:component-scan/>扫描该serivce层需要引用的所有:dao层,redis层
   这里没有扫描model层,是因为在mybatis的配置里,指定model层,和对应mapper.xml的位置;
  <bean class="com.springmvc.common.util.SpringContextHolder" /> spring上下文持有器,可以在该层取到:ApplicaitonContext,这样可以取得spring管理的bean;
  <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 读取.property配置文件,必须的,可以设置多个;
  <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">  多线程,线程池的配置
  具体的实现可参考:使用SPRING中的线程池ThreadPoolTaskExecutor实现JAVA并发
  <import resource="classpath*:spring/spring-pms-transaction.xml"/> 引入其他层的配置文件
  注意:classpath*:与classpath:的区别:classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找.
  具体的参考:web.xml 配置中classpath: 与classpath*:的区别
  3.加入mybatis,事务处理配置文件spring-transaction.xml如下:





<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans  
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
http://www.springframework.org/schema/context  
http://www.springframework.org/schema/context/spring-context-3.0.xsd  
http://www.springframework.org/schema/aop  
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx  
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/jdbc  
http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
<!-- 加载jdbc配置文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="${jdbc.initialPoolSize}" />
<property name="maxActive" value="${jdbc.maxPoolSize}" />
<property name="maxIdle" value="${jdbc.maxIdle}" />
<property name="maxWait" value="3000"/>
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<property name="validationQuery" value="${jdbc.validationQuery}" />
<property name="timeBetweenEvictionRunsMillis" value="${dbcp.timeBetweenEvictionRunsMillis}" />
<property name="numTestsPerEvictionRun" value="${dbcp.numTestsPerEvictionRun}" />
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="180"/>
<property name="minEvictableIdleTimeMillis" value="${dbcp.minEvictableIdleTimeMillis}" />
</bean>
<!-- MyBatis数据库标识提供者,可以在select/update/delete/insert加上databaseId的方式来标识不同的数据库,也可以直接使用属性<if test="_databaseId == 'mysql'">来判断不同的数据库 -->
<bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider">  
<property name="properties">
<props>  
<prop key="Oracle">oracle</prop>
<prop key="MySQL">mysql</prop>  
<prop key="Microsoft SQL Server">sqlserver</prop>  
<prop key="DB2">db2</prop>  
</props>
</property>  
</bean>
<!-- MyBatis配置 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
<property name="mapperLocations" value="classpath*:mybatis/**/*Mapper.xml" />
<property name="databaseIdProvider" ref="databaseIdProvider"/>
<property name="typeAliasesPackage" value="com.springmvc.entity"/>
<property name="plugins" >
<bean class="com.springmvc.common.mybatis.PaginationInterceptor">
<property name="properties">
<props>
<prop key="dialect">${jdbc.dialect}</prop>  
</props>
</property>
</bean>
</property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<aop:config>
<aop:pointcut id="serviceMethod"
expression="execution(* com.springmvc.*.service..*.*(..))" />
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
<!-- 也可以下面这样配置-->
<!--
<aop:pointcut id="baseServiceMethod"
expression="execution(* com.cdc.common.service..*.*(..))" />
<aop:pointcut id="serviceMethod"
expression="execution(* com.cdc.service..*.*(..))" />
<aop:advisor pointcut-ref="baseServiceMethod" advice-ref="txAdvice" />
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
-->
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="query*" read-only="true" />
<tx:method name="select*" read-only="true" />
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="process*" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
mybatis以及事务处理的配置文件
DSC0003.png



4.dao与mapper的指定在AbstractDAO类的构造函数中,通过命名空间来指定对应的mapper文件,从而取得里面的sql.具体的需要见代码






public AbstractDAO() {
@SuppressWarnings("rawtypes")
Class c = getClass();
Type type = c.getGenericSuperclass();
if (type instanceof ParameterizedType) {
Type[] parameterizedType = ((ParameterizedType) type)
.getActualTypeArguments();
this.entityClass = (Class<T>) parameterizedType[0];
nameSpace = entityClass.getCanonicalName();
}
}
abstractDao构造函数指定mapper  四.加入redis;
  对应包:jedis-2.0.0.jar,在service层调用redis,这个后续补充





<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.springmvc.redis" />
<!-- 加载配置文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="2" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
<!-- POOL配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxActive" value="${redis.maxActive}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxWait" value="${redis.maxWait}" />
<property name="testOnBorrow" value="false" />
</bean>
<!-- jedis shard信息配置 -->
<bean id="jedisShardInfo" class="redis.clients.jedis.JedisShardInfo">
<constructor-arg index="0" value="${redis.host}" /> <!-- host -->
<constructor-arg index="1" value="${redis.port}" /> <!-- port -->
<constructor-arg index="2" value="${redis.timeout}" /> <!-- timeout -->
</bean>
<!-- redis 连接池配置  -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
<property name="usePool" value="true"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
<property name="shardInfo" ref="jedisShardInfo"/>
</bean>
<!--  redis template -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="keySerializer">  
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>  
</property>
<property name="valueSerializer">  
<bean class="com.springmvc.common.redis.Object2StringRedisSerializer"></bean>  
</property>
<property name="hashKeySerializer">  
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean>  
</property>
<property name="hashValueSerializer">  
<bean class="com.springmvc.common.redis.Object2StringRedisSerializer"></bean>  
</property>
</bean>
</beans>
redis的配置文件  四.加入spring-security;
  参考文章:Spring安全权限管理(Spring Security的配置使用)
  原理:Spring Security 3 基于角色访问控制过程详解  
  主要引用jar包:spring-security-cas-3.1.4.RELEASE.jar;
  spring-security-config-3.1.4.RELEASE.jar;
  spring-security-core-3.1.4.RELEASE.jar;
  spring-security-crypto-3.1.4.RELEASE.jar;
  spring-security-taglibs-3.1.4.RELEASE.jar;
  spring-security-web-3.1.4.RELEASE.jar;
  1.在上下文文件:applicationContext.xml 中加入配置:





<!-- 扫描spring security相关类相关文件的路径 -->
<context:component-scan base-package="com.springmvc.security" />
<!-- 加spring security 配置文件 -->
<import resource="spring/spring-security.xml" />  
上下文配置文件中引入springsecurity的配置文件,并扫描spring-security类文件
  2.在web.xml中加入spring-security的过滤器和监听器:





<!-- spring security过滤器  cjjuan  -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Spring security配置HttpSessionEventPublisher防用户重复登录 cjjuan
- Publishes events for session creation and destruction through the application
- context. Optional unless concurrent session control is being used.
-->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
web.xml中引入监听器和过滤器  3.spring-security自身的配置文件:spring-security.xml的内容如下:





<?xml verssion="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http pattern="/css/**" security="none"/>
<http pattern="/js/**" security="none"/>
<http pattern="/images/**" security="none"/>
<http pattern="/login.jsp*" security="none"/>      
<http auto-config="true" access-denied-page="/noauth.jsp">
<intercept-url pattern="/**" access="ROLE_COMPANY" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" default-target-url="/test/list"/>
<custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="customFilter" />
</http>
<beans:bean id="customFilter"
class="com.springmvc.security.SecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager"/>
<beans:property name="accessDecisionManager" ref="accessDecisionManager" />  
<beans:property name="securityMetadataSource" ref="customSecurityMetadataSource" />  
</beans:bean>
<beans:bean id="customSecurityMetadataSource"
class="com.springmvc.security.SecurityMetadataSource">
</beans:bean>
<beans:bean id="accessDecisionManager" class="com.springmvc.security.RoleAccessDecisionManager">
</beans:bean>
<beans:bean id="userDetailServiceImpl" class="com.springmvc.security.UserDetailServiceImpl">
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref='userDetailServiceImpl'>
<password-encoder hash="md5"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
spring-security自身的配置文件  spring-security.xml 中提到的实体类和引用的jar包分别如下:


DSC0004.png     DSC0005.png   五。加入freemarker
  涉及到的引用包为:freemarker-2.3.15.jar; jstl.jar
  其中 freemarker 配置信息写在freemarker.xml中,然后将该文件import到servlet-context.xml(springMVC的配置文件)中,
  freemarker.xml 指定了freemarker对应html的存放路径:
DSC0006.png

  具体的见,自己写的文档:spring mvc中使用freemark的一点心得
  六.加入freemarker里的国际化
  参考文章:SpringMVC学习系列(8) 之 国际化  
  SpringMVC + FreeMarker 国际化使用方法
  1.配置xml文件





<!-- 基于Session的国际化实现 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
<!-- 国际化操作拦截器 如果采用基于(请求/Session/Cookie)则必需配置 -->
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
<!-- 国际化资源文件存放路径 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>/WEB-INF/message/messages</value>
</list>
</property>
<property name="cacheSeconds" value="0" />
</bean>
servlet-context里国际配置  注意事项:1.basenames里的 DSC0007.png
  如果资源文件名为 test_zh_CN.properties,则该处改为:/WEB-INF/message/test
  2.引入spring.ftl文件,该文件在:spring-webmvc-3.2.6.RELEASE.jar\org\springframework\web\servlet\view\freemarker\下
  复制到 DSC0008.png
  3.在html里import 该spring.ftl,如上图:testList.html中引用: DSC0009.png
  import的路径,是以freemark设置的默认路径为参照,因为该freemark路径是template,所以这里import路径如上图
  4.通过来java设置采用哪种语言  





//设置为英文格式化,到messages_en.properties 文件里去找
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("en"));
//设置为中文格式化,到messages_zh_CN.properties 文件里去找
request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("zh", "CN"));
// 根据properties文件的编码,取对应的中英文内容;
String msg=HttpUtil.getMessage(request, "tab.all");
java中设置中英文  另,在代码中根据资源文件的编码,取对应的中英文内容: HttpUtil.getMessage(request, "tab.all");
  七.封装自定义控件;
  见自己写的 用freemarker定义宏实现自定义公用控件
  调用的时候,只需要把控件的html 给 include 进去就可以了,具体的如下图:
DSC00010.png

  八.Spring事件监听器与异步机制
  参考:spring发布和接收定制的事件(spring事件传播)
  1.事件:TestTaskEvent 继承 ApplicationEvent,具体的见代码
  2.监听器:TestListener 实现接口 ApplicationListener<TestTaskEvent>,具体的见代码
  3.发布:SpringContextHolder 实现接口 ApplicationContextAware, ServletContextAware,具体的见代码,并确保有spring应用上下文持有器
   DSC00011.png
  调用代码:





    @Override
public void testEvent() {
// 发布事件
System.out.println("我要发布信息。。。。。。。。");
Map<String,Object> map=new HashMap<String,Object>();
map.put("a1", "a1");
TestTaskEvent event = new TestTaskEvent(map);
SpringContextHolder.getApplicationContext().publishEvent(event);
}
发布事件调用代码  测试结果:
DSC00012.png

  注意:很多文章里写的在配置文件xml中注入TestListener,这里使用了springMVC的自动扫描
  1.在配置文件中配置Event和Listener的扫描路径;





<!-- Spring Event异步机制 -->
<context:component-scan base-package="com.springmvc.event" />
<context:component-scan base-package="com.springmvc.listener" />
spring-service-s1.xml中的配置  2.发布,必须确保spring-service-s1.xml中有配置:
      <!-- Spring应用上下文持有器 -->
    <bean class="com.springmvc.common.util.SpringContextHolder"></bean>
  3.在TestListener 实现类上加:@Service
  九.定时器任务调度Quartz
  参考文档:SpringMVC整合Quartz实现定时任务和Spring自带Task定时任务  

框架Quart在Java中任务调度的使用
主要引用jar包:quartz-all-1.8.6.jar
  Quartz核心的概念:scheduler任务调度、Job任务、Trigger触发器、JobDetail任务细节
  scheduler任务调度:触发器工程,将所有定时任务都注入工厂;(在配置文件job-scheduler.xml中设置)
  Job任务:其实Job是接口,其中只有一个execute方法,我们开发者只要实现此接口,实现execute方法即可。把我们想做的事情,在execute中执行即可;
  (TestJob.java,配置文件job-scheduler.xml中也有指向该类)
  JobDetail:任务细节,Quartz执行Job时,需要新建个Job实例,但是不能直接操作Job类,所以通过JobDetail来获取Job的名称、描述信息
  (在配置文件job-scheduler.xml中设置)
  Trigger触发器:执行任务的规则;比如每天,每小时等。指定JobDetail和执行规则;(在配置文件job-scheduler.xml中设置)
  配置文件job-scheduler.xml如下文





<!-- 业务service里的包 -->
<import resource="classpath*:spring/spring-service-*.xml"/>
<!-- 定时任务包 -->
<context:component-scan base-package="com.springmvc.quartz.job.test.**" />
<!--job执行规则时间设置文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="2" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:cron.properties</value>
</list>
</property>
</bean>
<!-- scheduler任务调度(触发器工程,将所有定时任务都注入工厂) -->
<bean name="quartzScheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 设置数据源 -->
<!-- <property name="dataSource" ref="dataSource"/> -->
<!-- 设置事务管理器,如果设置了数据源则一定要事务管理器 -->
<!-- <property name="transactionManager" ref="transactionManager" /> -->
<!-- <property name="configLocation" value="classpath:quartz.properties" /> -->
<!-- 添加触发器 -->
<property name="triggers">
<list>
<!--将下面配置的所有定时任务注入(要执行的Trigger都要在这里注入)  -->
<ref bean="triggerTest" />
</list>
</property>
</bean>
<!--Trigger触发器(指定jobDetail和触发的时间规则)-->
<bean id="triggerTest" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="jobDetailTest" />
<property name="cronExpression" value="${quartz.test.minute}" />
</bean>
<!-- JobDetail(任务细节) -->
<bean id="jobDetailTest" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="jobTest"/>
</property>
<property name="targetMethod">
<value>execute</value>
</property>
<!-- 设置是否同步 false的话会等第一个job执行完才会执行后面的 -->
<property name="concurrent">  
<value>false</value>  
</property>
</bean>
<!-- Job(任务),指向具体的job类 -->
<bean id="jobTest" class="com.springmvc.quartz.job.test.TestJob">
</bean>
job-scheduler.xml  其中测试调用代码如下:选中该文件中的函数main,右键弹框--> Run As --> java application 进行测试





public class ServerMain {
public static void main(String[] args) {
RPCServer server = new RPCServer("spring/job-scheduler.xml");
server.start();
}
}
ServerMain  运行结果如下:
  17:10:00,002 INFO  [TestJob] springmvc-test:数据定时器,启动。。。。
17:10:00,002 INFO  [TestJob] springmvc-test:数据定时器:print users.开始。。。。
34009677
  34009721
  34009635
  34009633
  17:10:00,075 INFO  [TestJob] springmvc-test:数据定时器:print users.结束。。。。
17:10:00,075 INFO  [TestJob] springmvc-test:数据定时器,结束。。。。
  添加packing-build.xml文件,指定打包内容





<?xml version="1.0" encoding="UTF-8"?>
<!-- project元素 name project名字,default 默认执行的target -->
<project name="SpringMVC_Quartz" default="dir">
<!--发布到的路径 -->
<property name="publish.dir" value="D:/PM/SpringMVC_Quartz"/>
<target name="dir" description="folder">
<!-- 复制应用 -->
<copy todir="${publish.dir}/classes" includeEmptyDirs="false" overwrite="true">
<fileset dir="bin" excludes="mock/*.class"/>
</copy>
<!-- 复制execute -->
<copy todir="${publish.dir}/execute" includeEmptyDirs="true" overwrite="true">
<fileset dir="execute"/>
</copy>
<!-- 复制lib包,所有引用的jar包 -->
<copy todir="${publish.dir}/lib" overwrite="true">
<!-- lib -->
<fileset dir="../SpringMVC_Common/lib"/>
</copy>
<!--引用其他工程,需要把其他工程生成的包,复制到该工程的lib下 -->
<!--  复制SpringMVC_Common工程 -->
<copy todir="${publish.dir}/temp/SpringMVC_Common" overwrite="true">
<fileset dir="../SpringMVC_Common/bin"/>
</copy>
<jar  destfile ="${publish.dir}/lib/SpringMVC_Common.jar"  basedir ="${publish.dir}/temp/SpringMVC_Common" />
<!--  复制SpringMVC_DAO工程 -->
<copy todir="${publish.dir}/temp/SpringMVC_DAO" overwrite="true">
<fileset dir="../SpringMVC_DAO/bin"/>
</copy>
<jar  destfile ="${publish.dir}/lib/SpringMVC_DAO.jar"  basedir ="${publish.dir}/temp/SpringMVC_DAO" />
<!--  复制SpringMVC_Model工程 -->
<copy todir="${publish.dir}/temp/SpringMVC_Model" overwrite="true">
<fileset dir="../SpringMVC_Model/bin"/>
</copy>
<jar  destfile ="${publish.dir}/lib/SpringMVC_Model.jar"  basedir ="${publish.dir}/temp/SpringMVC_Model" />
<!-- 复制SpringMVC_Redis工程 -->
<copy todir="${publish.dir}/temp/SpringMVC_Redis" includeEmptyDirs="false" overwrite="true">
<fileset dir="../SpringMVC_Redis/bin" excludes="redis.properties"/>                                
</copy>
<copy file="../SpringMVC_Redis/bin/redis.properties" tofile="${publish.dir}/temp/SpringMVC_Redis/redis.properties" overwrite="true" />
<jar  destfile ="${publish.dir}/lib/SpringMVC_Redis.jar"  basedir ="${publish.dir}/temp/SpringMVC_Redis" />
<!-- 复制SpringMVC_Service工程 -->
<copy todir="${publish.dir}/temp/SpringMVC_Service" includeEmptyDirs="false" overwrite="true">
<fileset dir="../SpringMVC_Service/bin" excludes="config.properties,jdbc.properties"/>                                
</copy>
<copy file="../SpringMVC_Service/bin/config.properties" tofile="${publish.dir}/temp/SpringMVC_Service/config.properties" overwrite="true" />
<copy file="../SpringMVC_Service/bin/jdbc.properties" tofile="${publish.dir}/temp/SpringMVC_Service/jdbc.properties" overwrite="true" />
<jar  destfile ="${publish.dir}/lib/SpringMVC_Service.jar"  basedir ="${publish.dir}/temp/SpringMVC_Service" />
<delete dir="${publish.dir}/temp"/>
</target>
</project>
packing-build.xml  在execute文件夹下,加start.bat文件;修改该文件,指向测试用的 ServerMain文件
DSC00013.png

  用Ant发布:windows--> show view -->Ant,弹出小蚂蚁窗口。在Ant窗口中,右键--> add BuildFiles...选中该项目的packing-build.xml后,如下:
DSC00014.png

  选中该项目,右键 --->Run As  --->Ant Build,则将该工程发布到指定的路径下:
DSC00015.png

  十.日志文件
  参考文档:基础内容见:java日志文件log4j.properties配置详解  以及 Log4J日志配置详解
  其中日志文件的扩展类实现见:扩展log4j系列[一]为DailyRollingFileAppender加上maxBackupIndex属性  与我们系统中的扩展类 :DailyMaxRollingFileAppender相对应

   Log4j – 如何配置多个logger?  
  主要引用jar包:log4j-1.2.17.jar;

slf4j-api-1.7.5.jar ;
slf4j-log4j12-1.7.5.jar
DSC00016.png

  其中日志文件配置如下:





log4j.rootLogger=INFO,CONSOLE,FILE,useraction
#输出到控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c{1}] %m%n
#输出到file,也就是logger的输出
log4j.appender.FILE=org.apache.log4j.DailyMaxRollingFileAppender
log4j.appender.FILE.threshold=DEBUG
log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
log4j.appender.FILE.maxBackupIndex=10
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d - %-5p %C.%M(%F:%L) - %m%n
#日志文件后追加,以免覆盖原来的文件
log4j.appender.FILE.append=true
log4j.appender.FILE.file=${catalina.home}/logs/springmvc_test.log
log4j.appender.FILE.bufferedIO=false
#输出到useraction,用户操作日志,以loggerUserAction输出到另一个文件中
log4j.logger.useraction= DEBUG, useractionfile
log4j.additivity.useraction = false
log4j.appender.useractionfile=org.apache.log4j.DailyMaxRollingFileAppender
log4j.appender.useractionfile.threshold=DEBUG
log4j.appender.useractionfile.DatePattern='.'yyyy-MM-dd
log4j.appender.useractionfile.maxBackupIndex=10
log4j.appender.useractionfile.layout=org.apache.log4j.PatternLayout
log4j.appender.useractionfile.layout.ConversionPattern=%d - %-5p %C.%M(%F:%L) - %m%n
log4j.appender.useractionfile.append=true
log4j.appender.useractionfile.file=${catalina.home}/logs/springmvc_action.log
log4j.appender.useractionfile.bufferedIO=false
#com.springmvc架包下设置为debug
log4j.category.com.springmvc = DEBUG
log4j.category.java.sql = DEBUG
log4j.property  其中java代码调用:





//应用系统的日志
protected final Log logger = LogFactory.getLog(getClass());
//用户操作日志
protected final Log loggerUserAction = LogFactory.getLog("useraction");
logger.info("write to file springmvc_test.log");
loggerUserAction.info("write to file springmvc_userAction.log");
java调用写2个不同的日志文件  结果如下:
DSC00017.png

DSC00018.png

  十一.搜索引擎solar(solr4.9.1版本,对应jdk为1.7)
  1.solr的启动以及配置:
    cmd-->d:\platform\solr-4.9.1\example\下 启动 Jetty下的solr,命令:“java -jar start.jar”,启动后,在浏览器中输入http://localhost:8983/solr/则进入solr的管理页面
    如下图: DSC00019.png
    参考:Lucene/Solr搜索引擎开发笔记 - 第1章 Solr安装与部署(Jetty篇)
  2.在solr管理页面中,增,删,查数据:
  在linux系统上直接使用post命令就可以完成数据导入。
  在windows上我们必须要使用solr-4.9.1\example\exampledocs下的post.jar来完成数据导入(同时在这里也可以看到一些测试数据,如sd500.xml),先cd到exampledocs目录,然后输入"java -jar post.jar -h"来获取post.jar的使用帮助:
  先导入一个xml数据文件试试:"java -Dc=collection1 -jar post.jar sd500.xml" (这里的红色字体,与上图中的1对应)
  查询如上图1,2,3即可,在3中输入内容,删除见参考文档。   参考文档:全文检索引擎Solr系列——入门篇
3.在Tomcat中整合solr,整合后,如下图:
DSC00020.png
参考文档: Lucene/Solr搜索引擎开发笔记 - 第2章 Solr安装与部署(Tomcat篇)
  solr JBoss 使用配置  
  4.与java代码的整合 :java整合solr5.0之solrj的使用
  SolrCloud使用教程、原理介绍
  十二.RPC实现及其接口(Provider角色)
  引入.jar包:dubbo-2.5.3.jar;
  netty-3.2.7.Final.jar;
  zkclient-0.2.dev.jar;  javassist-3.17.1-GA.jar;
  zookeeper-3.4.4.jar; RPC工程布局如下:
   DSC00021.png
  在工程SpringMVC_RPC.API中放对外公开的接口:com.springmvc.rpc.api,以及接口返回字段的接收对象com.springmvc.rpc.model 以方便其他工程调用;如果其他工程想调用该RPC只需要引用该接口工程即可;
  在工程SpringMVC_RPC.Impl 用于接口的实现,这里包括service,dao,mapper.xml以及相关的配置文件;其中service层到mapper.xml的配置如有问题,
  参考:三.加入spring 业务层+加入mybatis;其中主要要注意的是spring-transaction.xml中mybatis的配置注意:
DSC00022.png

  其中dubbo应用RPC提供方的配置文件如下:





<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 定义提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="rpcApi" />
<!-- 指定zookeeper服务 -->
<dubbo:registry address="zookeeper://127.0.0.1:2088" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="2066" host="127.0.0.1" />
<!-- 定义声明需要暴露的服务接口:如代码中的接口 ITestApi,并指定接口实现TestApiImpl-->
<dubbo:service interface="com.springmvc.rpc.api.ITestApi" ref="testApi"/>
<bean id="testApi" class="com.springmvc.rpc.impl.TestApiImpl" />     
</beans>
applicationProvider.xml  RPC应用调用方的配置文件如下:





<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- check:为true表示启动时,验证 testApi接口是否存在 -->
<dubbo:reference id="testApi" interface="com.springmvc.rpc.api.ITestApi" check="false"/>
</beans>
dubbo-rpc.xml  注:dubbo-rpc.xml文件放在接口工程中,RPC本身的启动,不会读取该文件,主要是提供给调用方,也就是consumer使用,下文在portal中调用RPC接口;
  接口实现端单元测试:





@ContextConfiguration(locations = { "classpath:spring/spring-rpc.xml" })
public class TestApi extends AbstractJUnit4SpringContextTests{
@Autowired
ITestApi testApi;
@Test
public void getByUsername() throws ParseException {
RPCUsers rpcUser= testApi.getByUsername("34004198");
System.out.println("rpcUser="+JacksonMapper.toString(rpcUser));
}
}
单元测试  十三.web中调用RPC接口服务(Comsumer角色)
  在SpringMVC_Controller中调用RPC服务
  1.controller工程中引用接口工程:SpringMVC_RPC.API
  2.指定对应的zookeeper以及扫描相应接口端提供的dubbo-rpc.xml文件
  在spring的上下文配置文件中引用接口配置文件,在applicationContext.xml中加以下内容
DSC00023.png

   3.在dubbo-consumer-api.xml中配置调用RPC,比如dubbo_consumer的定义,指定的zookeeper,以及调用的接口testAPI等,具体见配置文件





<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- dubbo调用方 -->
<dubbo:application name="RPC_dubbo_Consumer"/>
<!-- zookeeper的指定 -->
<dubbo:registry address="zookeeper://192.168.1.156:2088" />
<!-- 扫描各API下的consumer 配置文件,如SpringMVC_RPC.API 下的dubbo-rpc.xml等  -->
<import resource="classpath*:spring/dubbo-*.xml"/>
</beans>
dubbo-consumer-api.xml  其中,<import resource="classpath*:spring/dubbo-*.xml"/> 能扫描到SpringMVC_RPC.API中的spring/dubbo-rpc.xml
  4.java代码的调用:





    @Autowired
@Qualifier("testApi")
ITestApi testApi;
/**
* 测试RPC及其接口
* @param request
* @param response
* @param map
* @return
*/
@RequestMapping(value = "/testApi")
@ResponseBody
public ModelAndView testApi(HttpServletRequest request, HttpServletResponse response, ModelMap map){
map.put("controllerUri", "http://127.0.0.1:8080/springmvc");
RPCUsers u= testApi.getByUsername("34004198");
map.put("searchText", "测试RPC及其接口:"+JacksonMapper.toString(u));
return new ModelAndView("/test/testList", map);
}
java调用代码  其中:ITestApi 和 RPCUsers都是 SpringMVC_RPC.API中的类
  结果如下:
DSC00024.png

  如果要修改start.bat黑屏的标题,在start.bat中 @echo off 下添加: title  组织架构_RPC_端口21880
  有时候发布成功,但是在windows下执行start.bat文件后,如果报错,黑屏会一闪而过,关闭掉。
  为了方便调试,可以在cmd里启动start.bat,这样黑屏就不会关闭。eg:packing-build.xml生成的文件在:D:\Amq\execute\start.bat
DSC00025.png

  十四。zookeeper+dubbo
  参考文档:Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
  1. 设置启动zookeeper:在zookeeper-3.4.4/conf/zoo.cfg中 配置 zookeeper的端口:clientPort=2088;启动zookeeper-3.4.4/bin/zkServer.cmd 成功启动zookeeper服务;
  2.dubbo-monitor 用于监控:dubbo-monitor-simple-2.5.3-assembly 简易监控中心安装  
  3.dubbo+zookeeper与提供者、消费者之间端口通信问题(No provider available for the service)
  4.com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method 错误处理  
  十五。CAS
  十六。Redis
  参考:redis系列文章
  在java中使用redis,则需要下载 jedis-2.0.0.jar,并加载到项目中。
  十七。mongodb
  参考:8天学通mongodb
  十八。activity工作流

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348718-1-1.html 上篇帖子: (十四)Maven聚合与继承 下篇帖子: Web 发展的十年
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表