ssm配置清单,注意事项
- spring
- spring mvc
- mybatis
对pom.xml文件的操作
pro.xml priject中,日常会经常用到的4个子标签 dependencyManagment、dependencies、build和profiles
-
打包的设置
<packaging>war</packaging>
-
构建的设置
<build> <plugins> <!-- java编译插件,指定jdk版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> <!-- 配置资源打包路径 --> <resources> <resource> <!--目录--> <directory>src/main/java</directory> <!--包括--> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <!--过滤--> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
-
依赖的导入
<!-- 依赖--> <dependencies> <!-- 单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${javax.servlet-api.version}</version> <scope>provided</scope> </dependency> <!-- jsp依赖--> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>${javax.servlet.jsp-api.version}</vers <scope>provided</scope> </dependency> <!-- jsp标准库 --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!-- myBatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- mybatisSpring--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis-spring.version}</version> </dependency> <!-- spring依赖--> <dependency> <!-- 切面编程--> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring-webmvc.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring-webmvc.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-webmvc.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring-webmvc.version}</version> </dependency> <dependency> <!--spring表达式,可以更灵活的注入--> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>${spring-webmvc.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring-webmvc.version}</version> </dependency> <dependency> <!--这个好像是事务管理--> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring-webmvc.version}</version> </dependency> <!-- springMvc依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring-webmvc.version}</version> </dependency> <!-- mysql依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql-connector-java.version}</versi </dependency> <!-- log4j--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> </dependencies>
-
依赖的版本配置
<!-- 依赖版本声明 project.build.sourceEncoding配置文件编码!!!一定要设置--> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring-webmvc.version>5.2.8.RELEASE</spring-webmvc.version> <log4j.version>1.2.17</log4j.version> <mysql-connector-java.version>5.1.47</mysql-connector-java.version> <mybatis-spring.version>2.0.0</mybatis-spring.version> <mybatis.version>3.5.5</mybatis.version> <jstl.version>1.2</jstl.version> <javax.servlet-api.version>4.0.0</javax.servlet-api.version> <javax.servlet.jsp-api.version>2.3.3</javax.servlet.jsp-api.version> <junit.version>4.12</junit.version> </properties>
```
到这里,已经配置好了pom文件,基本上使用没有什么问题了,否需有问题再记录
对spring mvc使用的配置
json转实体类使用RequestBody注解,实体类转json添加jackson-databind依赖
- json转实体类必须要有空构造方法,不然会报错
-
文件框架
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> </web-app>
-
配置DispatcherServlet进web.xml
<!-- 请求拦截--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- 这里指向了DispatcherServlet --> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 拦截了所有请求--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
-
配置springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns: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/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 配置扫描的路径 --> <context:component-scan base-package="com.phcCommunity"/> <!--配置字符串http消息转换器,返回json数据,注意命名空间必须是 xmlns:mvc="http://www.springframework.org/schema/mvc" --> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json;charset=UTF-8"/> </bean> </mvc:message-converters> </mvc:annotation-driven> </beans>
-
添加jackson依赖
<!-- 使用该依赖是需要将返回的室内类映射为json --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.6</version> </dependency>
mybatis结合使用
必须依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
配置mybatis-config.xml
<?xml version="1.0" encoding="GBK" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.198.128:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 映射表位置-->
<mappers>
<mapper resource="com/phc/dao/mapper/UserMapper.xml"/>
</mappers>
</configuration>
配置连接池
-
依赖
<dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency>
-
mybatis没有开发c3p0的的数据源连接,需要开发之自行实现,只需要继承UnpooledDataSourceFactory并把dataSourc 实现即可
public class C3p0DataSource extends UnpooledDataSourceFactory { public C3p0DataSource() { this.dataSource = new ComboPooledDataSource(); } }
-
修改mybatis 的全局配置,主要是将数据源替换为c3p0的,添加了initialPoolSize等连接池配置,还有修改了一些property的name,在使用pooled数据源时和c3p0数据源时 property中driver,url,username名字不同
<dataSource type="com.phcCommunity.utils.C3p0DataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://192.168.198.128:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/> <property name="user" value="root"/> <property name="password" value="123456"/> <property name="initialPoolSize" value="5"/> <property name="maxPoolSize" value="100"/> <property name="minPoolSize" value="5"/> </dataSource>
-
可能会警告需要log4j配置文件,创建log4j.properties文件
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码 log4j.rootLogger=DEBUG,console,file #控制台输出的相关设置 log4j.appender.console = org.apache.log4j.ConsoleAppender log4j.appender.console.Target = System.out log4j.appender.console.Threshold=DEBUG log4j.appender.console.layout = org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=[%p][%c]-%m%n #文件输出的相关设置 log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.File=./log/blog.txt log4j.appender.file.MaxFileSize=10mb log4j.appender.file.Threshold=DEBUG log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n #日志输出级别 log4j.logger.org.mybatis=DEBUG log4j.logger.java.sql=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.ResultSet=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG
-
顺便说一下log4j的使用
private static Logger logger = Logger.getLogger("test");
mybatis第三方c3p0连接池配置完成,等待使用过程技术补充
配置线程池
-
编写@EnableAsync配置类
@Configuration @EnableAsync public class AsyncConfiguration { @Bean public Executor asyncException(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(2); executor.setMaxPoolSize(10); executor.setThreadNamePrefix("phc_community_task_worker-"); executor.setQueueCapacity(30); return executor; } }
-
使用@Async来编写异步程序
@Async public String add() throws InterruptedException { for (int i = 0; i < 10; i++) { //暂停线程 Thread.sleep(1000); System.out.println(i); if (i == 9) { System.out.println(i); return String.valueOf(i); } } return "ghost know what this"; }
-
调用@Async标记的方法来执行异步程序
taskService.add();
配置线程池完成,等待使用过程技术补充
邮件发送配置
-
依赖
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.6.2</version> </dependency>
-
编写发送工具类
package com.phcCommunity.utils; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.*; import javax.mail.internet.*; import java.io.File; import java.net.URL; import java.util.*; /** * @Author: PengHaiChen * @Description: * @Date: Create in 15:58 2020/7/24 */ public class EmailSender { private static final String TAG = "EmailSender"; private static Session session; private static String user; private MimeMessage msg; private String text; private String html; private List<MimeBodyPart> attachments = new ArrayList<MimeBodyPart>(); private EmailSender() { EmailSender.config(EmailSender.SMTP_163(false), "phcbest_system@163.com", "MSJHKKZZOYNLQRWN"); } public static Properties defaultConfig(Boolean debug) { Properties props = new Properties(); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.ssl.enable", "true"); props.put("mail.transport.protocol", "smtp"); props.put("mail.debug", null != debug ? debug.toString() : "false"); props.put("mail.smtp.timeout", "10000"); props.put("mail.smtp.port", "465"); return props; } /** * smtp entnterprise qq * * @param debug * @return */ public static Properties SMTP_ENT_QQ(boolean debug) { Properties props = defaultConfig(debug); props.put("mail.smtp.host", "smtp.exmail.qq.com"); return props; } /** * smtp qq * * @param debug enable debug * @return */ public static Properties SMTP_QQ(boolean debug) { Properties props = defaultConfig(debug); props.put("mail.smtp.host", "smtp.qq.com"); return props; } /** * smtp 163 * * @param debug enable debug * @return */ public static Properties SMTP_163(Boolean debug) { Properties props = defaultConfig(debug); props.put("mail.smtp.host", "smtp.163.com"); return props; } /** * config username and password * * @param props email property config * @param username email auth username * @param password email auth password */ public static void config(Properties props, final String username, final String password) { props.setProperty("username", username); props.setProperty("password", password); config(props); } public static void config(Properties props) { final String username = props.getProperty("username"); final String password = props.getProperty("password"); user = username; session = Session.getInstance(props, new Authenticator() { @Override public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); } /** * set email subject * * @param subject subject title */ public static EmailSender subject(String subject) { EmailSender EmailSender = new EmailSender(); EmailSender.msg = new MimeMessage(session); try { EmailSender.msg.setSubject(subject, "UTF-8"); } catch (Exception e) { LogUtil.i(TAG, e+""); } return EmailSender; } /** * set email from * * @param nickName from nickname */ public EmailSender from(String nickName) { return from(nickName, user); } /** * set email nickname and from user * * @param nickName from nickname * @param from from email */ public EmailSender from(String nickName, String from) { try { String encodeNickName = MimeUtility.encodeText(nickName); msg.setFrom(new InternetAddress(encodeNickName + " <" + from + ">")); } catch (Exception e) { e.printStackTrace(); } return this; } public EmailSender replyTo(String... replyTo) { String result = Arrays.asList(replyTo).toString().replaceAll("(^\\[|\\]$)", "").replace(", ", ","); try { msg.setReplyTo(InternetAddress.parse(result)); } catch (Exception e) { e.printStackTrace(); } return this; } public EmailSender replyTo(String replyTo) { try { msg.setReplyTo(InternetAddress.parse(replyTo.replace(";", ","))); } catch (Exception e) { e.printStackTrace(); } return this; } public EmailSender to(String... to) throws MessagingException { return addRecipients(to, Message.RecipientType.TO); } public EmailSender to(String to) throws MessagingException { return addRecipient(to, Message.RecipientType.TO); } public EmailSender cc(String... cc) throws MessagingException { return addRecipients(cc, Message.RecipientType.CC); } public EmailSender cc(String cc) throws MessagingException { return addRecipient(cc, Message.RecipientType.CC); } public EmailSender bcc(String... bcc) throws MessagingException { return addRecipients(bcc, Message.RecipientType.BCC); } public EmailSender bcc(String bcc) throws MessagingException { return addRecipient(bcc, Message.RecipientType.BCC); } private EmailSender addRecipients(String[] recipients, Message.RecipientType type) throws MessagingException { String result = Arrays.asList(recipients).toString().replace("(^\\[|\\]$)", "").replace(", ", ","); msg.setRecipients(type, InternetAddress.parse(result)); return this; } private EmailSender addRecipient(String recipient, Message.RecipientType type) throws MessagingException { msg.setRecipients(type, InternetAddress.parse(recipient.replace(";", ","))); return this; } public EmailSender text(String text) { this.text = text; return this; } public EmailSender html(String html) { this.html = html; return this; } public EmailSender attach(File file) { attachments.add(createAttachment(file, null)); return this; } public EmailSender attach(File file, String fileName) { attachments.add(createAttachment(file, fileName)); return this; } public EmailSender attachURL(URL url, String fileName) { attachments.add(createURLAttachment(url, fileName)); return this; } private MimeBodyPart createAttachment(File file, String fileName) { MimeBodyPart attachmentPart = new MimeBodyPart(); FileDataSource fds = new FileDataSource(file); try { attachmentPart.setDataHandler(new DataHandler(fds)); attachmentPart.setFileName(null == fileName ? MimeUtility.encodeText(fds.getName()) : MimeUtility.encodeText(fileName)); } catch (Exception e) { e.printStackTrace(); } return attachmentPart; } private MimeBodyPart createURLAttachment(URL url, String fileName) { MimeBodyPart attachmentPart = new MimeBodyPart(); DataHandler dataHandler = new DataHandler(url); try { attachmentPart.setDataHandler(dataHandler); attachmentPart.setFileName(null == fileName ? MimeUtility.encodeText(fileName) : MimeUtility.encodeText(fileName)); } catch (Exception e) { e.printStackTrace(); } return attachmentPart; } public void send() { if (text == null && html == null) { throw new IllegalArgumentException("At least one context has to be provided: Text or Html"); } MimeMultipart cover; boolean usingAlternative = false; boolean hasAttachments = attachments.size() > 0; try { if (text != null && html == null) { // TEXT ONLY cover = new MimeMultipart("mixed"); cover.addBodyPart(textPart()); } else if (text == null && html != null) { // HTML ONLY cover = new MimeMultipart("mixed"); cover.addBodyPart(htmlPart()); } else { // HTML + TEXT cover = new MimeMultipart("alternative"); cover.addBodyPart(textPart()); cover.addBodyPart(htmlPart()); usingAlternative = true; } MimeMultipart content = cover; if (usingAlternative && hasAttachments) { content = new MimeMultipart("mixed"); content.addBodyPart(toBodyPart(cover)); } for (MimeBodyPart attachment : attachments) { content.addBodyPart(attachment); } msg.setContent(content); msg.setSentDate(new Date()); Transport.send(msg); LogUtil.i(TAG,"email send.........."); } catch (Exception e) { e.printStackTrace(); } } private MimeBodyPart toBodyPart(MimeMultipart cover) throws MessagingException { MimeBodyPart wrap = new MimeBodyPart(); wrap.setContent(cover); return wrap; } private MimeBodyPart textPart() throws MessagingException { MimeBodyPart bodyPart = new MimeBodyPart(); bodyPart.setText(text); return bodyPart; } private MimeBodyPart htmlPart() throws MessagingException { MimeBodyPart bodyPart = new MimeBodyPart(); bodyPart.setContent(html, "text/html; charset=utf-8"); return bodyPart; } public static void sendRegisterVerifyCode(String code,String address) throws Exception { EmailSender.subject("磷氢碳Blog注册码") .from("磷氢碳Blog服务器") .text("您的验证码为:"+code+"\n有效期为10分钟\n如非本人操作,请忽略该邮件") .to(address) .send(); } }
配置 图灵 验证码
-
添加依赖
<dependency> <groupId>com.github.whvcse</groupId> <artifactId>easy-captcha</artifactId> <version>1.6.2</version> </dependency>
-
编写实现
@Override public void sendCaptcha(HttpServletResponse response, String captchaKey) throws IOException, FontFormatException { //需要传递进来时间,近100年的时间戳都不会大于13位 if (captchaKey.length() < 13 | TextUtils.isEmpty(captchaKey)) { return; } long key; try { key = Long.parseLong(captchaKey); } catch (Exception e) { e.printStackTrace(); return; } //拿到了传入的时间戳 // 设置请求头为输出图片类型 response.setContentType("image/gif"); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); //随机类型 Captcha targetCaptcha = null; int captchaType = random.nextInt(3); if (captchaType == 0) { targetCaptcha = new SpecCaptcha(200, 60, 5); } else if (captchaType == 1) { targetCaptcha = new GifCaptcha(200, 60); } else { targetCaptcha = new ArithmeticCaptcha(200, 60); targetCaptcha.setLen(2); } //随机字体 targetCaptcha.setFont(CAPTCHA_FONT_TYPE[random.nextInt(CAPTCHA_FONT_TYPE.length)]); //字母数字混合类型 targetCaptcha.setCharType(Captcha.TYPE_DEFAULT); //存入redis // String content = targetCaptcha.text().toLowerCase(); // redisUtils.set(Constants.User.KEY_CAPTCHA_CONTENT + key, content, 60 * 10); //输入图片 targetCaptcha.out(response.getOutputStream()); }
-
实现环境
@Autowired Random random; @Bean public Random createRandom(){ return new Random(); } public static final int[] CAPTCHA_FONT_TYPE = {Captcha.FONT_1, Captcha.FONT_2, Captcha.FONT_3, Captcha.FONT_4, Captcha.FONT_5, Captcha.FONT_6, Captcha.FONT_7, Captcha.FONT_8, Captcha.FONT_9, Captcha.FONT_10};
配置 redis
-
添加依赖
<!-- java连接redis的包 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.3.0</version> </dependency> <!--spring整合redis的jar包--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.0.8.RELEASE</version> </dependency>
-
我不使用spring整合方式,直接使用jedis来对redis进行操作
-
编写配置文件
#连接池配置 maxTotal=50 maxIdle=10 #ip位置 host=192.168.198.128 #端口 port=6379 #密码 pwd=123456 #响应超时 timeout=2000
-
编写工具类
public class JedisUtils { /** * 创建一个连接池 */ private static JedisPool jedisPool; static { //读取配置文件 InputStream inputStream = JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties"); Properties properties = new Properties(); try { properties.load(inputStream); } catch (IOException e) { e.printStackTrace(); } //连接池配置 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(Integer.parseInt(properties.getProperty("maxTotal"))); config.setMaxIdle(Integer.parseInt(properties.getProperty("maxIdle"))); //初始化连接池,把对应参数传递进去 jedisPool =new JedisPool(config, properties.getProperty("host"), Integer.parseInt(properties.getProperty("port")), Integer.parseInt(properties.getProperty("timeout")), properties.getProperty("pwd")); } //返回jedis对象 public static Jedis getJedis(){ return jedisPool.getResource(); } }
-
调用该工具类的getJedis方法可以从连接池中获取一个jedis连接
@Test public void testJedis() { Jedis jedis = JedisUtils.getJedis(); SetParams setParams = new SetParams(); setParams.ex(60); jedis.set("hashah","axb",setParams); jedis.close(); }