Spring boot学习笔记
1 安全验证
package com.example.springbootdemo.pojo; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; import javax.validation.constraints.Null; import javax.validation.constraints.Pa
t; import java.util.Date; public class Student { int myid; @Length(min = 1,max = 5,message = "lenthnot right") // @NotNull(message = "wo bu null") String name; @Null String esu; @Past(message = "must is post") Date birth; @Email(message = "email budui") String email; }
@RequestMapping("/hello2") @ResponseBody public String helloIndex2(@Valid Student student, BindingResult bindingResult){ // System.out.println(bindingResult.getModel()); if(bindingResult.hasErrors()){ bindingResult.getAllErrors().forEach(e->{ System.out.println(e.getDefaultMessage()); }); } return "hello chaiguowen2"; }
8 application.properties 配置的属性公共的:
https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/common-application-properties.html
9 enaable自动配置的原理,再启动的时候
会加载meta/info/xxxx
3 spring boot初始化器 使用失败的原因,联网超时,
使用4g网络秒开,因为4g时移动网络,wifi是xxxxxx网络
4 自动生成 serializable 方法的配置再idea中
4 真实的 测试dubbo的例子
/** * 订单服务相关接口 */ public interface OrderService { /** * 初始化订单 * @param userId */ List<User> initOrder(String userId); } public interface UserService { /** * 获取用户信息 * @param userId * @return */ List<User> getUserList(String userId); List<User> getUserAddressList(String userId); } user-service-provider <dependency> <groupId>com.darling.dubboDemo</groupId> <artifactId>pub-interfence</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- 引入dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 注册中心使用的是zookeeper,引入操作zookeeper的客户端端 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> package com.provider.userserviceprovider.service; import com.pubinter.pubinterface.dao.UserService; import com.pubinter.pubinterface.pojo.User; import java.util.ArrayList; import java.util.List; public class UserServiceImpl implements UserService { public List<User> getUserAddressList(String userId) { List<User> list = new ArrayList(); list.add(new User(3,"韦德",36,"迈阿密")); list.add(new User(23,"詹姆斯",34,"洛杉矶")); list.add(new User(24,"科比",39,"洛杉矶")); return list; } @Override public List<User> getUserList(String userId) { return null; } } <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 当前服务的名称 --> <dubbo:application name="user-service-provider"/> <!-- 注册中心的地址 这里注册中心用的是zookeeper --> <dubbo:registry protocol="zookeeper" address="148.70.4.44:2181"/> <!-- 指定通信规则(通信协议?通信端口) --> <dubbo:protocol name="dubbo" port="20883"></dubbo:protocol> <!-- 需要暴露的服务 --> <dubbo:service interface="com.pubinter.pubinterface.dao.UserService" ref="userService" version="1.0.0"/> <!-- 需要暴露的服务的实现类 --> <bean id="userService" class="com.provider.userserviceprovider.service.UserServiceImpl"/> <!-- 监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心 --> <dubbo:monitor protocol="registry"></dubbo:monitor> <!-- timeout:超时时间配置 retries:重试次数配置(超时报错后重试连接的次数,不含第一次调用,如果目标服务有多个重试的时候会自动切换别的服务) --> <dubbo:provider timeout="2000" retries="6"></dubbo:provider> </beans> public class TestProviderDemo { public static void main(String[] args) throws IOException { // 加载配置文件 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("provider.xml"); // 容器启动 applicationContext.start(); // 使程序阻塞(由于是单元测试,如果程序跑完了我们再dubbo控制台看不到效果) System.in.read(); } } 不启用spring boot 主类,因为没必要,只启动了这个一个配置文件 order-service-consumer <!-- 引入公共接口层的依赖 --> <dependency> <groupId>com.darling.dubboDemo</groupId> <artifactId>pub-interfence</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- 引入dubbo --> <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 注册中心使用的是zookeeper,引入操作zookeeper的客户端端 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> /** * @author 董琳琳 * @date 2018/9/14 11:50 * @description 订单服务的实现类 */ @Service public class OrderServiceImpl implements OrderService { @Autowired UserService userService; /** * 初始化订单并调用用户服务的接口 * @param userId * @return */ @Override public List<User> initOrder(String userId) { return userService.getUserAddressList(userId); } } <?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://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context" 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-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 开启springmvc的包扫描 --> <context:component-scan base-package="com.order.orderserviceconsumer"></context:component-scan> <!-- 当前服务的名称 --> <dubbo:application name="order-service-consumer"/> <!-- 注册中心的地址 这里注册中心用的是zookeeper --> <dubbo:registry protocol="zookeeper" address="148.70.4.44:2181"/> <!-- 声明需要调用的远程服务的接口;生成远程服务代理 --> <dubbo:reference id="userService" check="false" interface="com.pubinter.pubinterface.dao.UserService" version="*"/> <!-- 监控中心协议,如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心 --> <dubbo:monitor protocol="registry"></dubbo:monitor> </beans> user必须实现serializable接口 必须要加扫描路径,不然会出错,找不到类 <context:component-scan base-package="com.darling.order"></context:component-scan> /** * @author 董琳琳 * @date 2018/9/14 15:57 * @description 测试服务调用者是否成功从注册中心订阅服务 */ public class TestConsumerDemo { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("consumer.xml"); OrderService service = applicationContext.getBean(OrderService.class); List<User> list = service.initOrder("1"); for (User user:list) { System.out.println(user.toString()); } System.in.read(); } } import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = -2844400681715908324L; private int age; private String name; private String address; private int number; User(){}; public User(int age,String name,int number,String address){ this.address=address; this.age=age; this.number=number; this.name=name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } }
大概流程是,public 接口,有两个,一个user 类,需要实现serializable接口和 set get方法,第二个项目provider引入公共的刚才的想pub,进行生产者配置,第三个消费者配置,兜售ideal 项目的module方式,
最终的效果是
10 邮箱发送 邮件每天限制
各大邮箱每天发送数量限制
网易邮箱:
企业邮箱:单个用户每天最多只能发送 1000 封邮件。单个邮件最多包含 500 个收件人邮箱地址。
163VIP邮箱:每天限制最多能发送800封邮件。
163 、 126 、 yeah 的邮箱:一封邮件最多发送给 40 个收件人 , 每天发送限额为 50 封。
尚易企业邮箱:
一个 IP 一分钟最多发送 400 个邮件地址。
一封邮件最多 200 个邮件地址。
如果一封邮件包括 200 个收信人地址,一分钟最多不能超过 2 封邮件。
如果一封邮件只有一个收信人地址 , 一分钟发送的邮件不能超过 6 封。
QQ邮箱:
为了防范少数垃圾邮件发送者的过量邮件发送行为, QQ邮箱根据不同用户类型设置了不同的发送总数的限制:
2G 的普通用户每天最大发信量是 100 封。
3G 会员、移动 QQ 、 QQ 行及 4G 大肚邮用户每天最大发信量是 500 封。
Foxmail 免费邮箱每天发送量限制为 50 封 。
Gmail邮箱:
邮件数量限制为每天 500 封 。
新申请的邮箱 每天发送量限制 50 封 。
新浪邮箱
企业邮箱试用期用户每天限制 80 封,购买后发信没有限制。
新浪免费邮箱,每天限制发送 30 封 。
雅虎免费邮箱
每小时发送量限制为100封。
每天发送量限制为 200 封。
阿里巴巴英文站提高的企业邮箱:
单个用户每天发送 200 封邮件 。
超过 200 封 / 天可能被系统自动冻结 。
HotMail 邮箱:
每天发送限量限制为 100封 。
每次最多可以将同一封邮件发送给 50 个电子邮件地址。
其他邮箱发送邮箱限制:
搜狐 免费邮箱:每天发送量限制为 100 封 。
GMX 免费邮箱:每天发送量限制为 100 封 。
Gawab 免费邮箱:每天发送量限制为 100 封 。
AOL 免费邮箱:每天发送限制为 100 封 。
中国移动 139 免费邮箱:每天发送限制量为 100 封 。
原文:https://blog.csdn.net/qq_31617637/article/details/73230942
11 使用多服务配置发送邮件的方法email
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> /** * 多邮箱发送邮件 * */ public interface EmailMoreService { /** * 发送文本邮件 * */ boolean sendSimpleMail(String to, String subject, String content); /** * 发送HTML邮件 * */ boolean sendHtmlMail(String to, String subject, String content); } package com.example.springbootdemo.email; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.mail.internet.MimeMessage; import java.util.*; @Service public class EmailMoreServiceImpl implements EmailMoreService { private Logger logger = LoggerFactory.getLogger(getClass()); private int emailId = 0; private List<Map<String, Object>> listEmail; @PostConstruct private void setListEmail() { // 设置邮箱发送列表, 从数据库中获取可发送邮箱列表 logger.info("=== 初始化可发送邮箱列表 ==="); this.listEmail =new ArrayList<Map<String,Object>>(); Map<String,Object> initemail=new HashMap<String, Object>() ; // initemail.put(); // initemail.put(); // initemail.put(); // initemail.put(); listEmail.add(initemail); if (listEmail == null || listEmail.isEmpty()) { logger.error("=== 可发送邮箱列表为NULL, 请检测代码 ==="); } else { for (Map<String, Object> email : listEmail) { logger.info("=== 可发送邮箱: " + email.get("email")); } } } private synchronized void setEmailId() { // 设置下次可发送邮箱 boolean isMax = emailId == (listEmail.size()-1); emailId = isMax ? 0 : emailId+1; } private synchronized Map<String, Object> getEmail() { // 获取当前可发送邮箱 Map<String, Object> email = listEmail.get(emailId); setEmailId(); return email; } private synchronized JavaMailSenderImpl getJavaMailSender() { // 获取邮箱发送实例 Map<String, Object> email = getEmail(); String host = email.get("host_addr").toString(); String username = email.get("email").toString(); String password = email.get("pwd").toString(); String sslPort = email.get("ssl_port").toString(); JavaMailSenderImpl javaMailSenderImpl = new JavaMailSenderImpl(); javaMailSenderImpl.setHost(host); javaMailSenderImpl.setUsername(username); javaMailSenderImpl.setPassword(password); javaMailSenderImpl.setDefaultEncoding("UTF-8"); Properties properties = new Properties(); properties.setProperty("mail.smtp.auth", "true"); properties.setProperty("mail.smtp.socketFactory.port", sslPort); properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); javaMailSenderImpl.setJavaMailProperties(properties); return javaMailSenderImpl; } @Override public boolean sendSimpleMail(String to, String subject, String content) { logger.info("简单邮件开始发送"); try { JavaMailSenderImpl javaMailSender = getJavaMailSender(); String username = javaMailSender.getUsername(); logger.info("当前发送邮箱: " + username); SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(username); message.setTo(to); message.setSubject(subject); message.setText(content); javaMailSender.send(message); logger.info("简单邮件发送成功"); return true; } catch (Exception e) { logger.error("简单邮件发送异常", e); e.printStackTrace(); } return false; } @Override public boolean sendHtmlMail(String to, String subject, String content) { logger.info("HTML邮件开始发送"); try { JavaMailSenderImpl javaMailSender = getJavaMailSender(); MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper messageHelper = new MimeMessageHelper(message, true); String username = javaMailSender.getUsername(); logger.info("当前发送邮箱: " + username); messageHelper.setFrom(username); messageHelper.setTo(to); messageHelper.setSubject(subject); messageHelper.setText(content, true); javaMailSender.send(message); logger.info("HTML邮件发送成功"); return true; } catch (Exception e) { logger.error("HTML邮件发送异常", e); e.printStackTrace(); } return false; } }
9 spring boot activiti的用法
1 springboot 集成 activiti 第一步依赖包先不写, 地一样注解需要加上 exclude = SecurityAutoConfiguration.class 如何需要手动指定 映射类或配置文件 mapperscan 指定的 注解版配置类 @SpringBootApplication(exclude = SecurityAutoConfiguration.class, scanBasePackages = {"com.lvmoney.**"}) @MapperScan(basePackages = {"com.lvmoney.activiti.dao*"}) import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.lvmoney.activiti.po.User; import org.apache.ibatis.annotations.Select; import java.util.List; /** * @describe: * @author: lvmoney /xxxx科技有限公司 * @version:v1.0 2018年10月30日 下午3:29:38 */ public interface UserMapper extends BaseMapper<User> { @Select("select * from user") List<User> selectAll(); @Select("select * from user where name = #{name}") List<User> selectByName(String name); } 2 第二个思路 保持 登录后的用户名在 cookie更好一些 import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; Cookie cookie = new Cookie("userInfo", username); cookie.setPath("/"); response.addCookie(cookie); 3 注销用户的方法,用 cookie for (Cookie cookie : cookies) { if (cookie.getName().equals("userInfo")) { cookie.setValue(null); // 立即销毁cookie cookie.setMaxAge(0); cookie.setPath("/"); response.addCookie(cookie); break; } } 4 activiti 事件委托 import org.activiti.engine.delegate.DelegateExecution; import org.activiti.engine.delegate.Expression; import org.activiti.engine.delegate.JavaDelegate; /** * @describe: * @author: lvmoney /xxxx科技有限公司 * @version:v1.0 2018年10月30日 下午3:29:38 */ public class ServiceTask implements JavaDelegate { //流程变量 private Expression text1; //重写委托的提交方法 @Override public void execute(DelegateExecution execution) { System.out.println("serviceTask已经执行已经执行!"); String value1 = (String) text1.getValue(execution); System.out.println(value1); execution.setVariable("var1", new StringBuffer(value1).reverse().toString()); } } 执行具体的activiti import com.lvmoney.activiti.service.BaseActivitiService; import com.lvmoney.activiti.vo.*; import com.lvmoney.common.utils.JsonUtil; import org.activiti.bpmn.model.FlowNode; import org.activiti.bpmn.model.Process; import org.activiti.engine.*; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.history.HistoricTaskInstance; import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.activiti.engine.task.Task; import org.apache.commons.io.IOUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * @describe: * @author: lvmoney /xxxx科技有限公司 * @version:v1.0 2018年10月30日 下午3:29:38 */ @Service public class BaseActivitiServiceImpl implements BaseActivitiService { @Autowired private RuntimeService runtimeService; @Autowired HistoryService historyService; @Autowired private RepositoryService repositoryService; @Autowired private TaskService taskService; @Autowired ManagementService managementService; @Autowired private ProcessEngineConfigurationImpl processEngineConfiguration; @Override public void startProcessInstanceByKey(StartProcessVo startProcessVo) { runtimeService.startProcessInstanceByKey(startProcessVo.getBpmnId(), startProcessVo.getFormId(), startProcessVo.getVariables()); } @Override public List<Task> findTasksByFormId(QueryTaskVo queryTaskVo) { return taskService.createTaskQuery().processInstanceBusinessKey(queryTaskVo.getFormId()).list(); } @Override public List<Task> findTasksByUserId(QueryTaskVo queryTaskVo) { return taskService.createTaskQuery().processDefinitionKey(queryTaskVo.getBpmnId()).taskCandidateOrAssigned(queryTaskVo.getUserId()).list(); } @Override public List<Task> findTasksByKey(QueryTaskVo queryTaskVo) { return taskService.createTaskQuery().processDefinitionKey(queryTaskVo.getBpmnId()).list(); } @Override public Task findTaskByTaskId(QueryTaskVo queryTaskVo) { return taskService.createTaskQuery() // 创建任务查询 .taskId(queryTaskVo.getTaskId()) // 根据任务id查询 .singleResult(); } @Override public void completeTaskByTaskId(CompleteTaskVo completeTaskVo) { String taskId = completeTaskVo.getTaskId(); String userId = completeTaskVo.getUserId(); taskService.claim(taskId, userId); Map<String, Object> vars = completeTaskVo.getVariables(); taskService.complete(taskId, vars); } @Override public List<HistoryVo> findHistoryByFormId(HistoryVo historyVo) { String formId = historyVo.getFormId(); List<HistoryVo> processList = new ArrayList<HistoryVo>(); List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery() .processInstanceBusinessKey(formId).list(); if (list != null && list.size() > 0) { for (HistoricTaskInstance hti : list) { HistoryVo hv = new HistoryVo(); hv.setFormId(formId); BeanUtils.copyProperties(hti, hv); processList.add(hv); } } return processList; } @Override public List<HistoryVo> findHistoryByKey(HistoryVo historyVo) { String bpmnId = historyVo.getBpmnId(); List<HistoryVo> processList = new ArrayList<HistoryVo>(); List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery() .processDefinitionKey(bpmnId).list(); if (list != null && list.size() > 0) { for (HistoricTaskInstance hti : list) { HistoryVo hv = new HistoryVo(); hv.setFormId(hti.getProcessInstanceId()); BeanUtils.copyProperties(hti, hv); processList.add(hv); } } return processList; }
5 springboot 的 aop、的例子
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class ServiceMonitor { @AfterReturning("execution(* sample..*Service.*(..))") public void logServiceAccess(JoinPoint joinPoint) { System.out.println("Completed: " + joinPoint); } }
同时实现 commandlinerunner的例子
import sample.aop.service.HelloWorldService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SampleAopApplication implements CommandLineRunner { // Simple example shows how an application can spy on itself with AOP @Autowired private HelloWorldService helloWorldService; @Override public void run(String... args) { System.out.println(this.helloWorldService.getHelloMessage()); } public static void main(String[] args) { SpringApplication.run(SampleAopApplication.class, args); } }
可以实现 执行 service方法时 自动调用aop的方法
1 spring boot的多个模板引擎是 开启了缓存,如果改了html,页面不变化,需要关闭缓存
thymeleaf关闭方法
spring.thymeleaf.cache=false
其他模板关闭缓存 用其他的
2 idea 热部署三种方式
spring loaded/ jrebel 最佳 / spring-boot-devtools 只需要添加一个依赖就可以了
3 下面两个图分别是 jar文件在linux上部署时的方法,一个时centos6.6,一个时 centos7.0的 设置启动运行,开机启动,停止等方法,两种liunx命令不一样