在ssm项目搭建时,需要我们结合项目选择需要的依赖,如何高效优雅的实现项目需求,是每个程序员孜孜以求的,本文的是根据自己的项目需求进行一个小结,可能并不优雅,高手勿喷。。。
ssm项目环境+shiro+redis+Email的maven配置:(可根据自己项目需求自行选择需要的jar包)
UTF-8
1.7
1.7
4.3.2.RELEASE
3.4.1
1.3.1
1.2.17
1.2.3
junit
junit
4.11
test
org.springframework
spring-context
${spring.version}
org.springframework
spring-core
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-oxm
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-aop
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-test
${spring.version}
org.mybatis
mybatis
${mybatis.version}
org.mybatis
mybatis-spring
${mybatis.spring.version}
com.github.pagehelper
pagehelper
5.1.2
mysql
mysql-connector-java
5.1.6
com.alibaba
druid
1.1.10
com.mchange
c3p0
0.9.5
redis.clients
jedis
2.9.0
org.springframework.data
spring-data-redis
1.6.2.RELEASE
log4j
log4j
${log4j.version}
org.slf4j
slf4j-api
1.7.5
org.slf4j
slf4j-log4j12
1.7.12
com.thetransactioncompany
cors-filter
2.6
com.fasterxml.jackson.core
jackson-core
2.7.5
com.fasterxml.jackson.core
jackson-annotations
2.7.5
com.fasterxml.jackson.core
jackson-databind
2.7.5
org.codehaus.jackson
jackson-mapper-asl
1.9.4
org.codehaus.jackson
jackson-core-asl
1.9.4
net.sf.json-lib
json-lib
2.4
jdk15
commons-httpclient
commons-httpclient
3.1
commons-fileupload
commons-fileupload
1.3.1
commons-io
commons-io
2.5
com.jcraft
jsch
0.1.49
org.apache.commons
commons-email
1.4
org.apache.logging.log4j
log4j-core
2.7
org.apache.httpcomponents
httpclient
4.5.2
org.apache.httpcomponents
httpcore
4.4.4
javax.servlet
javax.servlet-api
3.1.0
provided
javax.servlet.jsp
jsp-api
2.2
provided
org.glassfish.web
jstl-impl
1.2
javax.servlet
servlet-api
javax.servlet.jsp
jsp-api
org.apache.shiro
shiro-core
${shiro.version}
org.apache.shiro
shiro-spring
${shiro.version}
org.apache.shiro
shiro-cas
${shiro.version}
commons-logging
commons-logging
org.apache.shiro
shiro-web
${shiro.version}
org.apache.shiro
shiro-ehcache
${shiro.version}
org.apache.shiro
shiro-quartz
${shiro.version}
javax.mail
javax.mail-api
1.5.0
org.apache.maven.plugins
maven-compiler-plugin
3.1
1.8
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
classpath:applicationContext.xml,
classpath:springmvc.xml,
classpath:applicationContext-redis.xml,
classpath:spring-shiro.xml
characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
characterEncodingFilter
/*
shiroFilter
org.springframework.web.filter.DelegatingFilterProxy
targetFilterLifecycle
true
shiroFilter
/*
REQUEST
FORWARD
INCLUDE
ERROR
SSOClientFilter
com.lbis.rfq.web.filter.SSOClientFilter
excludedPaths
/delegation/dc
SSOClientFilter
/*
dispatcher
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
dispatcher
/
进行配置时需要注意配置的先后顺序, 尤其是对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的配置文件】
springmvc.xml【springMVC的配置】
applicationContext-redis.xml【redis的配置】
spring-shiro.xml【shiro的配置】
/delegation/dc=anon
/logOut=logout
/**=authc
redirect:/nopermission.jsp
shiro-ehcache.xml【shiro的缓存】
加载配置信息
/**
* 统一加载配置信息
* @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 redisTemplate;
public void setRedisTemplate(RedisTemplate 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
发邮件的核心类
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 list = null;
static {
list = new ArrayList();
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 params) throws Exception{
//建立URL连接对象
URL url = new URL(httpURL);
//创建连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求的方式(需要是大写的)
conn.setRequestMethod("POST");
//设置需要输出
conn.setDoOutput(true);
//判断是否有参数.
if(params!=null&¶ms.size()>0){
StringBuilder sb = new StringBuilder();
for(Entry 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();
}
}
在项目整合需要根据需求视具体情况而定,只要我们掌握了每个框架的原理,就可以灵活运用了。希望对看到的小伙伴们有帮助呦!!