转载博客:http://www.cnblogs.com/jennybackup/p/5286554.html
controller层配置文件介绍:
一.springmvc 配置;
具体原理参考文章: Spring MVC 3 深入总结
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>
其中<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>
其中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>
解释如下:
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>
具体拦截器类内容见文件: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"/>
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"/>
解释如下:
<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如下:
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(); } }
四.加入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>
四.加入spring-security;
参考文章:Spring安全权限管理(Spring Security的配置使用)
主要引用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" />
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>
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.xml 中提到的实体类和引用的jar包分别如下:
五。加入freemarker
涉及到的引用包为:freemarker-2.3.15.jar; jstl.jar
其中 freemarker 配置信息写在freemarker.xml中,然后将该文件import到servlet-context.xml(springMVC的配置文件)中,
freemarker.xml 指定了freemarker对应html的存放路径:
具体的见,自己写的文档:spring mvc中使用freemark的一点心得
六.加入freemarker里的国际化
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>
注意事项:1.basenames里的
如果资源文件名为 test_zh_CN.properties,则该处改为:/WEB-INF/message/test
2.引入spring.ftl文件,该文件在:spring-webmvc-3.2.6.RELEASE.jar\org\springframework\web\servlet\view\freemarker\下
复制到
3.在html里import 该spring.ftl,如上图:testList.html中引用:
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");
另,在代码中根据资源文件的编码,取对应的中英文内容: HttpUtil.getMessage(request, "tab.all");
七.封装自定义控件;
见自己写的 用freemarker定义宏实现自定义公用控件
调用的时候,只需要把控件的html 给 include 进去就可以了,具体的如下图:
八.Spring事件监听器与异步机制
参考:spring发布和接收定制的事件(spring事件传播)
1.事件:TestTaskEvent 继承 ApplicationEvent,具体的见代码
2.监听器:TestListener 实现接口 ApplicationListener<TestTaskEvent>,具体的见代码
3.发布:SpringContextHolder 实现接口 ApplicationContextAware, ServletContextAware,具体的见代码,并确保有spring应用上下文持有器
调用代码:
@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); }
测试结果:
注意:很多文章里写的在配置文件xml中注入TestListener,这里使用了springMVC的自动扫描
1.在配置文件中配置Event和Listener的扫描路径;
<!-- Spring Event异步机制 --> <context:component-scan base-package="com.springmvc.event" /> <context:component-scan base-package="com.springmvc.listener" />
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>
其中测试调用代码如下:选中该文件中的函数main,右键弹框--> Run As --> java application 进行测试
public class ServerMain { public static void main(String[] args) { RPCServer server = new RPCServer("spring/job-scheduler.xml"); server.start(); } }
运行结果如下:
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>
在execute文件夹下,加start.bat文件;修改该文件,指向测试用的 ServerMain文件
用Ant发布:windows--> show view -->Ant,弹出小蚂蚁窗口。在Ant窗口中,右键--> add BuildFiles...选中该项目的packing-build.xml后,如下:
选中该项目,右键 --->Run As --->Ant Build,则将该工程发布到指定的路径下:
十.日志文件
参考文档:基础内容见:java日志文件log4j.properties配置详解 以及 Log4J日志配置详解
其中日志文件的扩展类实现见:扩展log4j系列[一]为DailyRollingFileAppender加上maxBackupIndex属性 与我们系统中的扩展类 :DailyMaxRollingFileAppender相对应
主要引用jar包:log4j-1.2.17.jar;
slf4j-api-1.7.5.jar ;
slf4j-log4j12-1.7.5.jar
其中日志文件配置如下:
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
其中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");
结果如下:
十一.手机客户端接口开发
十二.CAS
十三.搜索引擎
十四。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服务;
十五.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工程布局如下:
在工程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的配置注意:
其中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>
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文件放在接口工程中,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中加以下内容
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>
其中,<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); }
其中:ITestApi 和 RPCUsers都是 SpringMVC_RPC.API中的类
结果如下: