ssm项目环境搭建详解

     在ssm项目搭建时,需要我们结合项目选择需要的依赖,如何高效优雅的实现项目需求,是每个程序员孜孜以求的,本文的是根据自己的项目需求进行一个小结,可能并不优雅,高手勿喷。。。

maven配置

ssm项目环境+shiro+redis+Email的maven配置:(可根据自己项目需求自行选择需要的jar包)

<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.7</maven.compiler.source>
		<maven.compiler.target>1.7</maven.compiler.target>
		<!-- spring版本号 -->
		<spring.version>4.3.2.RELEASE</spring.version>
		<!-- mybatis版本号 -->
		<mybatis.version>3.4.1</mybatis.version>
		<!-- mybatis/spring版本号 -->
		<mybatis.spring.version>1.3.1</mybatis.spring.version>
		<!-- log4j日志文件管理包版本 -->
		<log4j.version>1.2.17</log4j.version>
		<!-- shiro权限管理版本 -->
		<shiro.version>1.2.3</shiro.version>
	</properties>

	<dependencies>
		<!--单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<!-- 表示开发的时候引入,发布的时候不会加载此包 -->
			<scope>test</scope>
		</dependency>
		<!-- spring依赖管理 start -->
		<!-- spring-context 是使用spring的最基本的环境支持依赖,会传递依赖core、beans、expression、aop等基本组件,以及commons-logging、aopalliance -->

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- spring核心包 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- spring-webmvc 是spring处理前端mvc表现层的组件,也即是springMVC,传递依赖了web等web操作有关的组件 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- spring-orm 是spring处理对象关系映射的组件,传递依赖了jdbc、tx等数据库操作有关的组件 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!--spring 的事务管理功能  -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- spring-aspects 增加了spring对面向切面编程的支持,传递依赖了aspectjweaver -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- spring-context-support 提供了对其他第三方库的内置支持,如quartz等 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!-- spring依赖管理 end -->

		<!-- mybatis依赖管理 start -->
		<!-- mybatis核心包 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>
		<!-- mybatis和spring整合 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>${mybatis.spring.version}</version>
		</dependency>
		<!-- mybatis 分页插件 -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>5.1.2</version>
		</dependency>
		<!-- mybatis依赖管理 end -->
		<!-- 导入Mysql数据库链接jar包 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.6</version>
		</dependency>
		<!--这是整合 druid源 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.10</version>
		</dependency>
		<!-- c3p0依赖 -->
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5</version>
		</dependency>

		<!-- redis java客户端jar包 -->
		<!-- jedis依赖 -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.9.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
			<version>1.6.2.RELEASE</version>
		</dependency>
		<!-- 日志文件管理包 -->
		<!-- log start -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
		</dependency>
		<dependency>
	      <groupId>org.slf4j</groupId>
	      <artifactId>slf4j-api</artifactId>
	      <version>1.7.5</version>
	    </dependency>
	    <dependency>
	      <groupId>org.slf4j</groupId>
	      <artifactId>slf4j-log4j12</artifactId>
	      <version>1.7.12</version>
	    </dependency>
		<!-- log end -->
		

		<!--前后端分离解决跨域的jar包 -->
		<dependency>
			<groupId>com.thetransactioncompany</groupId>
			<artifactId>cors-filter</artifactId>
			<version>2.6</version>
		</dependency>

		<!-- json解析 -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
			<version>2.7.5</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-annotations</artifactId>
			<version>2.7.5</version>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.7.5</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-asl</artifactId>
			<version>1.9.4</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-core-asl</artifactId>
			<version>1.9.4</version>
		</dependency>
		
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>
		
		<dependency>
			<groupId>commons-httpclient</groupId>
			<artifactId>commons-httpclient</artifactId>
			<version>3.1</version>
		</dependency>
		<!-- 文件上传 start -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3.1</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.5</version>
		</dependency>
		<dependency>
			<groupId>com.jcraft</groupId>
				<artifactId>jsch</artifactId>
			<version>0.1.49</version>
		</dependency>
		<!-- 文件上传 end -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-email</artifactId>
			<version>1.4</version>
		</dependency>

		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.7</version>
		</dependency>
		<!--提供对http服务器的访问功能  -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpcore</artifactId>
			<version>4.4.4</version>
		</dependency>
		<!-- servlet依赖 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
			<scope>provided</scope>
		</dependency>

		<!-- jsp依赖 -->
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.2</version>
			<scope>provided</scope>
		</dependency>
		<!-- jstl依赖 -->
		<dependency>
			<groupId>org.glassfish.web</groupId>
			<artifactId>jstl-impl</artifactId>
			<version>1.2</version>
			<exclusions>
				<exclusion>
					<groupId>javax.servlet</groupId>
					<artifactId>servlet-api</artifactId>
				</exclusion>
				<exclusion>
					<groupId>javax.servlet.jsp</groupId>
					<artifactId>jsp-api</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

		<!-- shiro依赖包 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-cas</artifactId>
			<version>${shiro.version}</version>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-web</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-ehcache</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-quartz</artifactId>
			<version>${shiro.version}</version>
		</dependency>
		<!-- shiro end -->
		
		<!-- Email-api -->
		<dependency>
		    <groupId>javax.mail</groupId>
		   	 <artifactId>javax.mail-api</artifactId>
		    <version>1.5.0</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<!-- 指定JDK编译版本 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>			
		</plugins>
	</build>

web.xml

<!-- Spring容器监听器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- 告知配置文件的位置 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            classpath:applicationContext.xml,
            classpath:springmvc.xml,
            classpath:applicationContext-redis.xml,
            classpath:spring-shiro.xml
        </param-value>
  </context-param>

  <!-- 解决乱码 -->
	<filter>
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- shiro权限管理 过滤器 -->
	<filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
       	<dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
	</filter-mapping>
	<!-- SSO 过滤器(同一认证中心) -->
	<filter>
		<filter-name>SSOClientFilter</filter-name>
		<filter-class>com.lbis.rfq.web.filter.SSOClientFilter</filter-class>
		<init-param> 
			<!-- 配置不需要被登录过滤器拦截的链接,只支持配后缀、前缀 及全路径,多个配置用逗号分隔 -->
	        <param-name>excludedPaths</param-name>
	        <param-value>/delegation/dc</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>SSOClientFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- springmvc 核心dispatcherServlet -->
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
	<!--springMVC的拦截规则:
	  /拦截所有,但会放行jsp,但是会拦截css,js,png等静态资源
	  /* 是真的拦截所有,包括jsp,css,js等也进行拦截
	  *.action 只对action进行拦截
	    -->
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

进行配置时需要注意配置的先后顺序, 尤其是对filter的配置

配置文件

log4j.properties【日志文件】

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
## MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
## Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

pro.properties【jdbc,Linux,redis,Email】

# 可以定义子系统的路径如:统一认证中心的主机位置


# jdbc配置
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
jdbc.username=用户名
jdbc.password=密码

# 邮箱
# smtp邮件的传输协议
email-server-host=smtp.qq.com
# 主机端口
email-server-port=25
# 邮箱账号
email-server-username=邮箱账号
# 邮箱密码(秘钥)
email-server-password=秘钥
# //发送者邮箱地址
[email protected]


# 账号
linux.username=root
# 密码
linux.password=root
# ip路径
linux.ip=ip路径
# 虚拟机端口号
linux.id=22
# nginx端口
linux.nginx.port=8089
# 上传根目录
linux.nginx.uploadPath=/home/accessory
# 文件上传访问路径	
linux.nginx.downPath=/accessory/

#访问地址 
redis.host=ip路径
#访问端口 
redis.port=6379
#注意,如果没有password,此处不设置值,但这一项要保留 
redis.password=

#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制。 
redis.maxIdle=300
#连接池的最大数据库连接数。设为0表示无限制 
redis.maxActive=600
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。  
redis.maxWait=1000
#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;  
redis.testOnBorrow=true

applicationContext.xml【spring的配置文件】 

<?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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

 	<!-- 配置扫描spring注解(@Component、@Controller、@Service、@Repository)时扫描的包,同时也开启了spring注解支持 -->
     <!-- 这个地方只需要扫描service包即可,因为controller包由springMVC配置扫描,mapper包由上面的mybatis配置扫描 -->
    <context:component-scan base-package="com.#####"/>

    <!--1:引入数据源配置文件-->
	<context:property-placeholder location="classpath:pro.properties" ignore-unresolvable="true" />

    <!--2:配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--sqlSessionFactory工厂-->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 给模型起别名 -->
        <property name="typeAliasesPackage" value="com.######.model"/>
        <!-- 扫描sql配置文件:mapping需要的xml文件 -->
        <property name="mapperLocations" value="classpath:com/#####/mapper/*.xml"/>
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <!--可以不用配置,使用默认的就可以 -->
                        <value></value>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

    <!--动态创建mapper代理   mapper接口自动扫描、自动代理 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="mapper接口所在的包"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
    </bean>

    <!--配置事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置注解事务-->
    <tx:annotation-driven transaction-manager="transactionManager"  proxy-target-class="true" />

	<!-- 开启Aop扫描 -->
	<aop:aspectj-autoproxy/>
</beans>

springmvc.xml【springMVC的配置】

<?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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

 	<!-- 配置扫描spring注解时扫描的包,同时也开启了spring注解支持 -->
    <context:component-scan base-package="web层" />
	 <!-- 静态资源处理-->
    <mvc:default-servlet-handler/>
    <!-- 文件上传解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="104857600" />
        <property name="defaultEncoding" value="UTF-8" />
        <property name="maxInMemorySize" value="40960" />
    </bean>	
	
    <!-- 配置mvc注解解析器-->
    <mvc:annotation-driven conversion-service="myDateConverter" />
    <!-- 自定义转换器-->
    <bean id="myDateConverter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="自定义日期转换类路径"/>
            </set>
        </property>
    </bean>
  
  <import resource="classpath:spring-shiro.xml"/>
    
</beans>

applicationContext-redis.xml【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:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
			http://www.springframework.org/schema/beans 
			http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/context 
			http://www.springframework.org/schema/context/spring-context.xsd
			http://www.springframework.org/schema/mvc 
			http://www.springframework.org/schema/mvc/spring-mvc.xsd">
			
<!-- 扫描redis的工具类-->
    <context:component-scan base-package="com.####.util"/>
	
	<!-- 
	注意事项:
  		如果在多个spring配置文件中引入<context:property-placeholder .../>标签,最后需要加上ignore-unresolvable="true",否则会报错。
	 -->
	<!-- 连接池基本参数配置,类似数据库连接池 -->
	<context:property-placeholder location="classpath:pro.properties" ignore-unresolvable="true" />
    
    <!-- redis连接池 -->  
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${redis.maxActive}" />
        <property name="maxIdle" value="${redis.maxIdle}" />
        <property name="testOnBorrow" value="${redis.testOnBorrow}" />
    </bean>

    <!-- 连接池配置,类似数据库连接池 -->
    <bean id="jedisConnectionFactory"
        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis.host}"></property>
        <property name="port" value="${redis.port}"></property>
        <!-- <property name="password" value="${redis.pass}"></property> -->
        <property name="poolConfig" ref="poolConfig"></property>
    </bean>

    <!--redis操作模版,使用该对象可以操作redis  -->  
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >    
        <property name="connectionFactory" ref="jedisConnectionFactory" />    
        <!--如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!!  -->    
        <property name="keySerializer" >    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />    
        </property>    
        <property name="valueSerializer" >    
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" />    
        </property>    
        <property name="hashKeySerializer">    
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>    
        </property>    
        <property name="hashValueSerializer">    
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>    
        </property>    
        <!--开启事务  -->  
        <property name="enableTransactionSupport" value="true"></property>  
    </bean >   
<!--redis的监听器 -->
     <bean id="redisMessageListener" class="com.###.web.listener.RedisMessageListener"></bean>
	 <!-- 注入自定义的监听器 -->
    <bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter" >
        <constructor-arg ref="redisMessageListener"></constructor-arg>
    </bean>

    <bean class="org.springframework.data.redis.listener.RedisMessageListenerContainer" id="redisContainer">
	     <!-- 配置Redis数据库连接池 -->
	    <property name="connectionFactory" ref="jedisConnectionFactory"></property>
	    <property name="messageListeners">
	        <map>
	            <entry key-ref="messageListener">
	            	<list>
	                    <bean class="org.springframework.data.redis.listener.ChannelTopic">
	                        <constructor-arg value="__keyevent@0__:expired"></constructor-arg>
	                    </bean>
	                </list>
	            </entry>
	        </map>
	    </property>
    </bean>
</beans>

​

spring-shiro.xml【shiro的配置】

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
			http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
   <!--加载配置文件-->
	<context:property-placeholder location="classpath:pro.properties" ignore-unresolvable="true" />
	
	<!--配置自定义的realm-->
	<bean id="myRealm" class="自定义的Realm">
		<!--密码需要加密:加密器-->
		<!-- <property name="credentialsMatcher" ref="credentialsMatcher" /> -->
	</bean>

	<!-- 配置安全管理器SecurityManager -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="myRealm"/>
		<!--给shiro添加缓存机制-->
		<!-- <property name="cacheManager" ref="cacheManager"></property> -->
	</bean>

	<!-- 定义ShiroFilter -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- shiro的核心安全接口 -->
		<property name="securityManager" ref="securityManager"/>
		<property name="loginUrl" value="/login"/>
		 <!-- 登陆成功后要跳转的连接 -->
<!--         <property name="successUrl" value="/success" /> --> 
        <!-- 没有权限要跳转的链接 -->
		<property name="unauthorizedUrl" value="/nopermission.jsp"/>
		<!-- 默认的连接拦截配置 -->
		<property name="filterChainDefinitions">
			<value>
				<!-- 匿名访问 -->
				/delegation/dc=anon				
				<!-- 退出 -->
				/logOut=logout
				<!-- 认证 -->
				/**=authc
			</value>
		</property>
	</bean>
    
	<!-- 开启aop,对类代理 -->
	<aop:config proxy-target-class="true"></aop:config>
	<!-- 开启shiro注解支持 -->
	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" /> 
	</bean>

	<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常页名作为值 -->
	<!--shiro权限异常处理-->
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<!-- 异常处理器,当系统抛出该异常之后跳转的页面。 -->
				<prop key="org.apache.shiro.authz.UnauthorizedException">redirect:/nopermission.jsp</prop>
			</props>
		</property>
	</bean>

	<!-- 缓存管理器开始 -->
	<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
		<property name="cacheManager" ref="ehCacheManager"/>
	</bean>
	<bean id="ehCacheManager" class ="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="classpath:shiro-ehcache.xml" />
		<property name="shared" value="true"></property>
	</bean>

	<!--加密器-->
	<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
		<!--加密算法-->
		<property name="hashAlgorithmName" value="md5" />
		<!--散列次数-->
		<property name="hashIterations" value="3" />
	</bean>
</beans>

 shiro-ehcache.xml【shiro的缓存】

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
	<defaultCache
			maxElementsInMemory="1000"
			eternal="false"
			timeToIdleSeconds="120"
			timeToLiveSeconds="120"
			memoryStoreEvictionPolicy="LRU">
	</defaultCache>
</ehcache>

工具类

加载配置信息

/**
 * 统一加载配置信息
 * @author 曰业而安
 *
 */
public class PropertiesUtil {
    public static final String FILE_PATH = "pro.properties";
    
	private static Properties ssoProperties = new Properties();
	
	//统一认证中心地址:http://www.sso.com:8888,在sso.properties配置
	public static String SERVER_URL_PREFIX = getValue("server-url-prefix");
 	
// 	# 邮箱
// 	# smtp邮件的传输协议 smtp.qq.com
 	public static String EMAIL_SERVER_HOST = getValue("email-server-host");
// 	# 主机端口// 	=25
 	public static String EMAIL_SERVER_PORT = getValue("email-server-port");
// 	# 邮箱账号
 	public static String EMAIL_SERVER_USERNAME = getValue("email-server-username");
// 	# 邮箱密码(秘钥)
 	public static String EMAIL_SERVER_PASSWORD = getValue("email-server-password");
// 	# //发送者邮箱地址
 	public static String EMAIL_FROM_ADDRESS = getValue("email-from-address");	
 	
//	# 账号
	public static String LINUX_USERNAME = getValue("linux.username");
//	# 密码
	public static String LINUX_PASSWORD = getValue("linux.password");
//	# ip路径
	public static String LINUX_IP = getValue("linux.ip");
//	# 虚拟机端口号
	public static String LINUX_ID = getValue("linux.id");
//	# nginx端口
	public static String LINUX_NGINX_PORT = getValue("linux.nginx.port");
//	# nginx 上传根目录
	public static String LINUX_NGINX_UPLOADPATH = getValue("linux.nginx.uploadPath");
//	# nginx 文件上传访问路径	
	public static String LINUX_NGINX_DOWNPATH = getValue("linux.nginx.downPath");
		
	public static String getValue(String key){
		try {
			ssoProperties.load(PropertiesUtil.class.getClassLoader().getResourceAsStream(FILE_PATH));
		} catch (IOException e) {
			e.printStackTrace();
		}
		String property = ssoProperties.getProperty(key);
		System.out.println(property);
		return property;
	}	
}

redis的工具类

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
/** 
 *  
 * @author 曰业而安
 * 基于spring和redis的redisTemplate工具类 
 * 针对所有的hash 都是以h开头的方法 
 * 针对所有的Set 都是以s开头的方法                    不含通用方法 
 * 针对所有的List 都是以l开头的方法 
 */  
@Component("redisUtil") //交给Spring管理(在需要缓存的地方自动注入即可使用)
public class RedisUtil {  
  
    @Autowired//(自动注入redisTemplet)
    private RedisTemplate<String, Object> redisTemplate;  
      
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {  
        this.redisTemplate = redisTemplate;  
    }  
    //=============================common============================  
    /** 
     * 指定缓存失效时间 
     * @param key 键 
     * @param time 时间(秒) 
     * @return 
     */  
    public boolean expire(String key,long time){  
        try {  
            if(time>0){  
                redisTemplate.expire(key, time, TimeUnit.SECONDS);  
            }  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 根据key 获取过期时间 
     * @param key 键 不能为null 
     * @return 时间(秒) 返回0代表为永久有效 
     */  
    public long getExpire(String key){  
        return redisTemplate.getExpire(key,TimeUnit.SECONDS);  
    }  
      
    /** 
     * 判断key是否存在 
     * @param key 键 
     * @return true 存在 false不存在 
     */  
    public boolean hasKey(String key){  
        try {  
            return redisTemplate.hasKey(key);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 删除缓存 
     * @param key 可以传一个值 或多个 
     */  
    @SuppressWarnings("unchecked")  
    public void del(String ... key){  
        if(key!=null&&key.length>0){  
            if(key.length==1){  
                redisTemplate.delete(key[0]);  
            }else{  
                redisTemplate.delete(CollectionUtils.arrayToList(key));  
            }  
        }  
    }  
      
    //============================String=============================  
    /** 
     * 普通缓存获取 
     * @param key 键 
     * @return 值 
     */  
    public Object get(String key){  
        return key==null?null:redisTemplate.opsForValue().get(key);  
    }  
      
    /** 
     * 普通缓存放入 
     * @param key 键 
     * @param value 值 
     * @return true成功 false失败 
     */  
    public boolean set(String key,Object value) {  
         try {  
            redisTemplate.opsForValue().set(key, value);  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
          
    }  
      
    /** 
     * 普通缓存放入并设置时间 
     * @param key 键 
     * @param value 值 
     * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 
     * @return true成功 false 失败 
     */  
    public boolean set(String key,Object value,long time){  
        try {  
            if(time>0){  
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);  
            }else{  
                set(key, value);  
            }  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 递增 
     * @param key 键 
     * @param by 要增加几(大于0) 
     * @return 
     */  
    public long incr(String key, long delta){    
        if(delta<0){  
            throw new RuntimeException("递增因子必须大于0");  
        }  
        return redisTemplate.opsForValue().increment(key, delta);  
    }  
      
    /** 
     * 递减 
     * @param key 键 
     * @param by 要减少几(小于0) 
     * @return 
     */  
    public long decr(String key, long delta){    
        if(delta<0){  
            throw new RuntimeException("递减因子必须大于0");  
        }  
        return redisTemplate.opsForValue().increment(key, -delta);    
    }    
      
    //================================Map=================================  
    /** 
     * HashGet 
     * @param key 键 不能为null 
     * @param item 项 不能为null 
     * @return 值 
     */  
    public Object hget(String key,String item){  
        return redisTemplate.opsForHash().get(key, item);  
    }  
      
    /** 
     * 获取hashKey对应的所有键值 
     * @param key 键 
     * @return 对应的多个键值 
     */  
    public Map<Object,Object> hmget(String key){  
        return redisTemplate.opsForHash().entries(key);  
    }  
      
    /** 
     * HashSet 
     * @param key 键 
     * @param map 对应多个键值 
     * @return true 成功 false 失败 
     */  
    public boolean hmset(String key, Map<String,Object> map){    
        try {  
            redisTemplate.opsForHash().putAll(key, map);  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * HashSet 并设置时间 
     * @param key 键 
     * @param map 对应多个键值 
     * @param time 时间(秒) 
     * @return true成功 false失败 
     */  
    public boolean hmset(String key, Map<String,Object> map, long time){    
        try {  
            redisTemplate.opsForHash().putAll(key, map);  
            if(time>0){  
                expire(key, time);  
            }  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 向一张hash表中放入数据,如果不存在将创建 
     * @param key 键 
     * @param item 项 
     * @param value 值 
     * @return true 成功 false失败 
     */  
    public boolean hset(String key,String item,Object value) {  
         try {  
            redisTemplate.opsForHash().put(key, item, value);  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 向一张hash表中放入数据,如果不存在将创建 
     * @param key 键 
     * @param item 项 
     * @param value 值 
     * @param time 时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间 
     * @return true 成功 false失败 
     */  
    public boolean hset(String key,String item,Object value,long time) {  
         try {  
            redisTemplate.opsForHash().put(key, item, value);  
            if(time>0){  
                expire(key, time);  
            }  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 删除hash表中的值 
     * @param key 键 不能为null 
     * @param item 项 可以使多个 不能为null 
     */  
    public void hdel(String key, Object... item){    
        redisTemplate.opsForHash().delete(key,item);  
    }   
      
    /** 
     * 判断hash表中是否有该项的值 
     * @param key 键 不能为null 
     * @param item 项 不能为null 
     * @return true 存在 false不存在 
     */  
    public boolean hHasKey(String key, String item){  
        return redisTemplate.opsForHash().hasKey(key, item);  
    }   
      
    /** 
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回 
     * @param key 键 
     * @param item 项 
     * @param by 要增加几(大于0) 
     * @return 
     */  
    public double hincr(String key, String item,double by){    
        return redisTemplate.opsForHash().increment(key, item, by);  
    }  
      
    /** 
     * hash递减 
     * @param key 键 
     * @param item 项 
     * @param by 要减少记(小于0) 
     * @return 
     */  
    public double hdecr(String key, String item,double by){    
        return redisTemplate.opsForHash().increment(key, item,-by);    
    }    
      
    //============================set=============================  
    /** 
     * 根据key获取Set中的所有值 
     * @param key 键 
     * @return 
     */  
    public Set<Object> sGet(String key){  
        try {  
            return redisTemplate.opsForSet().members(key);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
      
    /** 
     * 根据value从一个set中查询,是否存在 
     * @param key 键 
     * @param value 值 
     * @return true 存在 false不存在 
     */  
    public boolean sHasKey(String key,Object value){  
        try {  
            return redisTemplate.opsForSet().isMember(key, value);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 将数据放入set缓存 
     * @param key 键 
     * @param values 值 可以是多个 
     * @return 成功个数 
     */  
    public long sSet(String key, Object...values) {  
        try {  
            return redisTemplate.opsForSet().add(key, values);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return 0;  
        }  
    }  
      
    /** 
     * 将set数据放入缓存 
     * @param key 键 
     * @param time 时间(秒) 
     * @param values 值 可以是多个 
     * @return 成功个数 
     */  
    public long sSetAndTime(String key,long time,Object...values) {  
        try {  
            Long count = redisTemplate.opsForSet().add(key, values);  
            if(time>0) expire(key, time);  
            return count;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return 0;  
        }  
    }  
      
    /** 
     * 获取set缓存的长度 
     * @param key 键 
     * @return 
     */  
    public long sGetSetSize(String key){  
        try {  
            return redisTemplate.opsForSet().size(key);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return 0;  
        }  
    }  
      
    /** 
     * 移除值为value的 
     * @param key 键 
     * @param values 值 可以是多个 
     * @return 移除的个数 
     */  
    public long setRemove(String key, Object ...values) {  
        try {  
            Long count = redisTemplate.opsForSet().remove(key, values);  
            return count;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return 0;  
        }  
    }  
    
    //===============================list=================================  
      
    /** 
     * 获取list缓存的内容 
     * @param key 键 
     * @param start 开始 
     * @param end 结束  0 到 -1代表所有值 
     * @return 
     */  
    public List<Object> lGet(String key,long start, long end){  
        try {  
            return redisTemplate.opsForList().range(key, start, end);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
      
    /** 
     * 获取list缓存的长度 
     * @param key 键 
     * @return 
     */  
    public long lGetListSize(String key){  
        try {  
            return redisTemplate.opsForList().size(key);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return 0;  
        }  
    }  
      
    /** 
     * 通过索引 获取list中的值 
     * @param key 键 
     * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 
     * @return 
     */  
    public Object lGetIndex(String key,long index){  
        try {  
            return redisTemplate.opsForList().index(key, index);  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
    }  
      
    /** 
     * 将list放入缓存 
     * @param key 键 
     * @param value 值 
     * @param time 时间(秒) 
     * @return 
     */  
    public boolean lSet(String key, Object value) {  
        try {  
            redisTemplate.opsForList().rightPush(key, value);  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 将list放入缓存 
     * @param key 键 
     * @param value 值 
     * @param time 时间(秒) 
     * @return 
     */  
    public boolean lSet(String key, Object value, long time) {  
        try {  
            redisTemplate.opsForList().rightPush(key, value);  
            if (time > 0) expire(key, time);  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 将list放入缓存 
     * @param key 键 
     * @param value 值 
     * @param time 时间(秒) 
     * @return 
     */  
    public boolean lSet(String key, List<Object> value) {  
        try {  
            redisTemplate.opsForList().rightPushAll(key, value);  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 将list放入缓存 
     * @param key 键 
     * @param value 值 
     * @param time 时间(秒) 
     * @return 
     */  
    public boolean lSet(String key, List<Object> value, long time) {  
        try {  
            redisTemplate.opsForList().rightPushAll(key, value);  
            if (time > 0) expire(key, time);  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * 根据索引修改list中的某条数据 
     * @param key 键 
     * @param index 索引 
     * @param value 值 
     * @return 
     */  
    public boolean lUpdateIndex(String key, long index,Object value) {  
        try {  
            redisTemplate.opsForList().set(key, index, value);  
            return true;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return false;  
        }  
    }   
      
    /** 
     * 移除N个值为value  
     * @param key 键 
     * @param count 移除多少个 
     * @param value 值 
     * @return 移除的个数 
     */  
    public long lRemove(String key,long count,Object value) {  
        try {  
            Long remove = redisTemplate.opsForList().remove(key, count, value);  
            return remove;  
        } catch (Exception e) {  
            e.printStackTrace();  
            return 0;  
        }  
    }  
      
}

发邮件的核心类

import java.util.Date;
import java.util.Properties;

import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 * 邮件发送核心类
 * @author 曰业而安
 */
public class SimpleMailSender {
	
	/**
	 * 发送html格式的邮件
	 * @param mailInfo//待发送邮件信息
	 * @return
	 */
	public boolean sendHtmlMail(MailSenderInfo mailInfo) {
		//1.判断是否需要身份验证
		MyAuthenticator authenticator = null;//验证类
		Properties pro = mailInfo.getProperties();//主机和端口
		//2.验证类实例化 如果需要身份验证 则创建一个密码的验证器
		authenticator = new MyAuthenticator(mailInfo.getUsername(),mailInfo.getPassword());
		//3.根据邮件的会话属性 和密码验证器构造一个发送邮件的session
		Session sendMailSession = Session.getDefaultInstance(pro,authenticator);
		
		
		try {
			//4.通过session会话创建邮件信息
			Message mailMessage = new MimeMessage(sendMailSession);
			//5.创建邮件发送者的地址
			Address from = new InternetAddress(mailInfo.getFromAddress());
			//6.设置邮件的发送者  并且把发送者地址设置到邮件当中
			mailMessage.setFrom(from);
			//7.设置接收者的地址
			Address to = new InternetAddress(mailInfo.getToAddress());
			//8.RecipientType.TO 表示接受者的类型    to:接收者的地址
			mailMessage.setRecipient(Message.RecipientType.TO, to);
			//9.设置邮件的主题
			mailMessage.setSubject(mailInfo.getSubject());
			//10.设置发送时间   实时获取时间
			mailMessage.setSentDate(new Date());
			//11.创建一个容器类
			Multipart mailPart = new MimeMultipart();
			//12.创建一个包含html容器的bodyPart
			BodyPart html = new MimeBodyPart();
			html.setContent(mailInfo.getContent(),"text/html;charset=utf-8");//html格式 防止出现乱码现象
			mailPart.addBodyPart(html);
			mailMessage.setContent(mailPart);//设置内容
			
			//发送邮件
			MailcapCommandMap mc = (MailcapCommandMap)CommandMap.getDefaultCommandMap();
			mc.addMailcap("text/html;;x-java-content-handler=com.sun.mail.handlers.text_html");
			mc.addMailcap("text/xml;;x-java-content-handler=com.sun.mail.handlers.text_xml");
			mc.addMailcap("text/plain;;x-java-content-handler=com.sun.mail.handlers.text_plain");
			mc.addMailcap("multipart/*;;x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
			mc.addMailcap("message/rfc822;;x-java-content-handler=com.sun.mail.handlers.message.rfc822");
			CommandMap.setDefaultCommandMap(mc);
			
			Transport.send(mailMessage);//发送邮件
			System.out.println("恭喜您,邮件发送成功!!!");
			return true;
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("不好意思,邮件发送失败,可能是你太丑了");
		}
		return false;
		
	}
}
/**
 * 邮箱用户验证类
 * @author 曰业而安
 */
public class MyAuthenticator extends Authenticator{
	String username=null;//账号
	String password=null;//密码
	
	public MyAuthenticator() {//默认的构造函数
		
	}
	public MyAuthenticator(String username,String password) {
		this.username=username;
		this.password=password;
	}
	//验证用户名以及密码
	protected PasswordAuthentication getPasswordAuthentication() {
		return new PasswordAuthentication(username,password);
	}
}

对发邮件功能不了解的可以参考博客:https://blog.csdn.net/duan196_118/article/details/103729207

上传图片到nginx服务器的工具类

/**
 * @Description: sftp连接工具类
 */
public class SftpUtil {
	private transient Logger log = LoggerFactory.getLogger(this.getClass());

	private ChannelSftp sftp;

	private Session session;
	/** FTP 登录用户名 */
	private String username;
	/** FTP 登录密码 */
	private String password;
	/** 私钥 */
	private String privateKey;
	/** FTP 服务器地址IP地址 */
	private String host;
	/** FTP 端口 */
	private int port;

	/**
	 * 构造基于密码认证的sftp对象
	 * 
	 * @param userName
	 * @param password
	 * @param host
	 * @param port
	 */
	public SftpUtil(String username, String password, String host, int port) {
		this.username = username;
		this.password = password;
		this.host = host;
		this.port = port;
	}

	/**
	 * 构造基于秘钥认证的sftp对象
	 * 
	 * @param userName
	 * @param host
	 * @param port
	 * @param privateKey
	 */
	public SftpUtil(String username, String host, int port, String privateKey) {
		this.username = username;
		this.host = host;
		this.port = port;
		this.privateKey = privateKey;
	}

	public SftpUtil() {
		
	}

	/**
	 * 连接sftp服务器
	 *
	 * @throws Exception
	 */
	public void login() {
		try {
			JSch jsch = new JSch();
			if (privateKey != null) {
				jsch.addIdentity(privateKey);// 设置私钥
				log.info("sftp connect,path of private key file:{}", privateKey);
			}
			log.info("sftp connect by host:{} username:{}", host, username);

			session = jsch.getSession(username, host, port);
			log.info("Session is build");
			if (password != null) {
				session.setPassword(password);
			}
			Properties config = new Properties();
			config.put("StrictHostKeyChecking", "no");

			session.setConfig(config);
			session.connect();
			log.info("Session is connected");

			Channel channel = session.openChannel("sftp");
			channel.connect();
			log.info("channel is connected");

			sftp = (ChannelSftp) channel;
			log.info(String.format("sftp server host:[%s] port:[%s] is connect successfull", host, port));
		} catch (JSchException e) {
			log.error("Cannot connect to specified sftp server : {}:{} \n Exception message is: {}",
					new Object[] { host, port, e.getMessage() });
		}
	}

	/**
	 * 关闭连接 server
	 */
	public void logout() {
		if (sftp != null) {
			if (sftp.isConnected()) {
				sftp.disconnect();
				log.info("sftp is closed already");
			}
		}
		if (session != null) {
			if (session.isConnected()) {
				session.disconnect();
				log.info("sshSession is closed already");
			}
		}
	}

	/**
	 * 将输入流的数据上传到sftp作为文件
	 * 
	 * @param directory    上传到该目录
	 * @param sftpFileName sftp端文件名
	 * @param in           输入流
	 * @throws SftpException
	 * @throws Exception
	 */
	public String upload(String directory, String sftpFileName, InputStream input) throws SftpException {
		try {
			sftp.cd(directory);
		} catch (SftpException e) {
			log.warn("directory is not exist");
			sftp.mkdir(directory);
			sftp.cd(directory);
		}
		sftp.put(input, sftpFileName);
		log.info("file:{} is upload successful", sftpFileName);
		String filePath = "http://"+host+"/imges/"+sftpFileName;
		return filePath;
	}
}

具体实现可以参考博客:https://blog.csdn.net/duan196_118/article/details/103837059

httpUtil工具类

public class HttpUtil {
	private static ArrayList<Integer> list = null;
	static {
		list = new ArrayList<Integer>();
		list.add(HttpURLConnection.HTTP_OK);
		list.add(HttpURLConnection.HTTP_CREATED);
		list.add(HttpURLConnection.HTTP_ACCEPTED );
	}
	
	/**
	 * 模拟浏览器的请求
	 * @param httpURL 发送请求的地址
	 * @param params  请求参数
	 * @return
	 * @throws Exception
	 */
	public static String sendHttpRequest(String httpURL,Map<String,Object> params) throws Exception{
		//建立URL连接对象
		URL url = new URL(httpURL);
		//创建连接
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		//设置请求的方式(需要是大写的)
		conn.setRequestMethod("POST");
		//设置需要输出
		conn.setDoOutput(true);
		//判断是否有参数.
		if(params!=null&&params.size()>0){
			StringBuilder sb = new StringBuilder();
			for(Entry<String, Object> entry:params.entrySet()){
				sb.append("&").append(entry.getKey()).append("=").append(entry.getValue().toString());
			}
			//sb.substring(1)去除最前面的 &
			conn.getOutputStream().write(sb.substring(1).toString().getBytes("utf-8"));
		}
		//发送请求到服务器
		conn.connect();
		String responseContent = "";
		int responseCode = conn.getResponseCode();
		//当返回不是HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED, HttpURLConnection.HTTP_ACCEPTED 时,不能用getInputStream(),而是应该用getErrorStream()。
		if(list.contains(responseCode)) {
			//获取远程响应的内容.
			responseContent = StreamUtils.copyToString(conn.getInputStream(),Charset.forName("utf-8"));
		}else {
			//获取远程响应的内容.
			responseContent = StreamUtils.copyToString(conn.getErrorStream(),Charset.forName("utf-8"));
		}
		conn.disconnect();
		return responseContent;
	}
	
	/**
	 * 模拟浏览器的请求
	 * @param httpURL 发送请求的地址
	 * @param jesssionId 会话Id
	 * @return
	 * @throws Exception
	 */
	public static void sendHttpRequest(String httpURL,String jesssionId) throws Exception{
		//建立URL连接对象
		URL url = new URL(httpURL);
		//创建连接
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		//设置请求的方式(需要是大写的)
		conn.setRequestMethod("POST");
		//设置需要输出
		conn.setDoOutput(true);
		conn.addRequestProperty("Cookie","JSESSIONID="+jesssionId);
		//发送请求到服务器
		conn.connect();
		conn.getInputStream();
		conn.disconnect();
	}
}

在项目整合需要根据需求视具体情况而定,只要我们掌握了每个框架的原理,就可以灵活运用了。希望对看到的小伙伴们有帮助呦!!

发布了171 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/duan196_118/article/details/105176496