项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送
Posted 阿善9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送相关的知识,希望对你有一定的参考价值。
1 Shiro整合ehCache缓存授权信息
当需要进行权限校验时候:四种方式url拦截、注解、页面标签、代码级别,当需要验证权限会调用realm中的授权方法
Shiro框架内部整合好缓存管理器,整合ehcache环境,只需要配置即可。
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
1、 提供ehcache缓存配置文件
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- 磁盘数据临时目录 -->
<diskStore path="java.io.tmpdir"/>
<!-- maxElementsInMemory:内存中存储数据最大个数
eternal:是否永久有效
timeToIdleSeconds:内存中对象空闲时间,单位秒
maxElementsOnDisk:磁盘中最大存储个数
timeToLiveSeconds:内存中对象存活时间,单位秒
diskExpiryThreadIntervalSeconds:指定清除内存数据线程执行时间周期
memoryStoreEvictionPolicy:清除数据策略: LRU:最近最少使用 FIFO:先进先出
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
</ehcache>
2、 配置缓存管理器
3、 将缓存管理器注入安全管理器
2 动态显示菜单数据
1、页面加载完成后,发送请求获取用户菜单数据:返回ztree的简单json数据格式。
2、服务端menuAction中添加方法
3、service:
4、dao:菜单数据去重
如果没有select问题:
3 Shiro框架总结
1、 Shiro框架:认证,授权(验权)
a) 认证逻辑:applicationCode—>通过工具类获取subject对象,调用login方法参数令牌信息->安全管理器------>调用realm中认证方法(1、根据用户名查询真实密码,2、框架比对密码)
Shiro框架实现权限控制方式:
1、 在spring配置文件中配置过滤器链-设置项目中url拦截规则:url拦截-过滤器(anon,authc,perms,roles)
2、 注解方式:在service方法上使用shiro提供注解-代理技术
3、 页面标签:只能在jsp页面中使用
4、 代码级别 subject.checkPermisssion(“code”);
在realm中完成授权:根据用户ID查询所有的角色以及权限—查询数据库;
Shiro框架使用:
1、 当完成自己负责模块功能后,将本模块中权限先添加到数据库表:角色表中角色标识,权限表中字段:权限标识(将来用于权限控制,用在url拦截中权限过滤器中 perms,roles配置url对应需要权限或者角色)
2、 如过使用url拦截方式
3、 如过使用注解方式:方法上使用注解中属性值:跟数据库中权限标识
4、 在realm中动态查询数据库中用户的权限,角色
4 Quartz定时任务调度框架
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz的最新版本为Quartz 2.3.0。
定时任务调度:定时或者一定周期执行服务器上一段代码逻辑。
注意:需要在common_parent项目pom.xml中添加quaratz相关的依赖依赖:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.3</version>
</dependency>
4.1 入门案例
需求:5秒中执行一段代码;
1、 引入依赖
2、 创建作业(任务)类,创建若干任务方法
3、 在spring配置文件中配置quartz定时任务
4、 配置作业对象
5、 配置任务详情
6、 配置触发器
7、 配置调度工厂
<!-- 配置作业对象 -->
<bean id="myJob" class="cn.itcast.jobs.MyJob"></bean>
<!-- 配置作业详情:指定调用哪个对象中哪个方法 -->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myJob"></property>
<property name="targetMethod" value="sayHello"></property>
</bean>
<!-- 配置触发器:1、执行作业详情中配置目标对象中目标方法 2、配置作业执行时间周期 -->
<bean id="trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobDetail"></property>
<!-- 通过Cron表达式指定执行周期 -->
<property name="cronExpression">
<!-- 每五秒执行一次 -->
<value>0/5 * * * * ?</value>
</property>
</bean>
<!-- 配置定时调度容器对象:执行任务 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="trigger"/>
</list>
</property>
</bean>
4.2 Cron表达式
http://cron.qqe2.com/
参考客户资料文档:
4.3 基于Quartz定时发送邮件
需求:每天0点给管理员发送一封邮件,当天工单数据。
配置参考入门案例
4.4 Spring整合javamail定时发送邮件
1、 导入依赖
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
2、 在spring配置文件中配置spring整合javamail后提供的发送邮件工具类对象
<!-- spring框架提供的用于发送邮件的工具类 -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<!-- 邮件服务器 -->
<property name="host" value="smtp.126.com"></property>
<!-- 发件人邮件地址 -->
<property name="username" value="itcast_java@126.com"></property>
<!-- 发件人邮箱密码 -->
<property name="password" value="bos123"></property>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.host">smtp.126.com</prop>
<prop key="mail.transport.protocol">smtp</prop>
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
</bean>
3、 在需要发送邮件的位置注入发送邮件工具对象进行发送邮件
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:beans.xml")
public class SimpleSender {
@Autowired
private JavaMailSenderImpl mailSender;
// 发送简单邮件
@Test
public void test1() {
// 构建简单邮件对象,见名知意
SimpleMailMessage smm = new SimpleMailMessage();
// 设定邮件参数
smm.setFrom(mailSender.getUsername());
//设置收件人
smm.setTo("test@itcast.cn");
//邮件主题
smm.setSubject("这是一封简单邮件");
//邮件内容
smm.setText("Hello world via spring mail sender");
// 发送邮件
mailSender.send(smm);
}
// 发送带有附件的邮件
/*spring Resource主要介绍3种方式
FileSystemResource:以文件的绝对路径方式进行访问
ClassPathResourcee:以类路径的方式访问
ServletContextResource:web应用根目录的方式访问
主要公用方法介绍(Resource接口下的)
getFilename() : 获得文件名称
contentLength() : 获得文件大小
createRelative(path) : 在资源的相对地址上创建新文件
exists() : 是否存在
getFile() : 获得Java提供的File 对象
getInputStream() : 获得文件的流*/
@Test
public void test2() throws Exception {
// 使用JavaMail的MimeMessage,支付更加复杂的邮件格式和内容
MimeMessage msg = mailSender.createMimeMessage();
// 创建MimeMessageHelper对象,处理MimeMessage的辅助类
MimeMessageHelper helper = new MimeMessageHelper(msg, true);
// 使用辅助类MimeMessage设定参数
helper.setFrom(mailSender.getUsername());
helper.setTo("test@itcast.cn");
helper.setSubject("这是一封带有附件的邮件");
helper.setText("这是一封带有附件的邮件");
// 加载文件资源,作为附件
//ClassPathResource file = new ClassPathResource("1.txt");
FileSystemResource file = new FileSystemResource("H:\\\\test\\\\logo.png");
// 加入附件
helper.addAttachment("重要文件.png", file);
// 发送邮件
mailSender.send(msg);
}
// 发送富文本邮件
@Test
public void test3() throws Exception {
MimeMessage msg = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(msg, true, "UTF-8");
helper.setFrom(mailSender.getUsername());
helper.setTo("test@itcast.cn");
helper.setSubject("这是一封富文本邮件");
// 第二个参数true,表示text的内容为html
//<img/>标签,src=\'cid:file\',\'cid\'是contentId的缩写,\'file\'是一个标记,需要在后面的代码中调用MimeMessageHelper的addInline方法替代成文件
helper.setText("<!DOCTYPE html><html><body>"
+ "<table border=\'1\' style=\'width: 99%\'>"
+ "<tr>"
+ "<th colspan=\'4\'>工单信息统计[2018.01.05]</th>"
+ "</tr><tr>"
+ "<td>工单编号</td>"
+ "<td>取件状态</td>"
+ "<td>生成时间</td>"
+ "<td>快递员</td></tr>"
+ "<tr><td>0100001</td><td>取件中</td><td>2018.01.04 11:22:34</td><td>张三</td></tr>"
+ "</table>"
+ "<br><br><br>"
+ "<img src=\'cid:file\'/></body></html>", true);
FileSystemResource file = new FileSystemResource("H:\\\\test\\\\logo.png");
helper.addInline("file", file);
mailSender.send(msg);
}
}
MailJOb.java
public class MailJob {
@Autowired
private JavaMailSenderImpl mailSender;
@Autowired
private WorkBillDao workBillDao;
//给管理员每天发送当日工单数据
public void sendMail(){
try {
//TODO 下去改为查询当日
List<WorkBill> list = workBillDao.findAll();
MimeMessage msg = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(msg, true, "UTF-8");
helper.setFrom(mailSender.getUsername());
helper.setTo("lvhonglong816@126.com");
helper.setSubject(new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "日工单数据");
// 第二个参数true,表示text的内容为html
// <img/>标签,src=\'cid:file\',\'cid\'是contentId的缩写,\'file\'是一个标记,需要在后面的代码中调用MimeMessageHelper的addInline方法替代成文件
String domHtml = "";
for (WorkBill workBill : list) {
domHtml += "<tr><td>" + workBill.getId() + "</td><td>" + workBill.getPickstate() + "</td>" + "<td>"
+ new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(workBill.getBuildtime()) + "</td>" + "<td>"
+ workBill.getCourier().getName() + "</td></tr>";
}
helper.setText("<!DOCTYPE html><html><body>" + "<table border=\'1\' bordercolor=\'#000000\' style=\'width: 99%\'>"
+ "<tr>" + "<th colspan=\'4\'>" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "</th>"
+ "</tr><tr>" + "<td>工单编号</td>" + "<td>取件状态</td>" + "<td>生成时间</td>" + "<td>快递员</td></tr>"
+ domHtml
// + "<tr><td>0100001</td><td>取件中</td><td>2018.01.04 11:22:34</td><td>张三</td></tr>"
+ "</table>" + "<br><br><br>" + "<img src=\'cid:file\'/></body></html>", true);
// 获取当前的spring容器,任何java类中适用
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
ServletContext servletContext = webApplicationContext.getServletContext();
ServletContextResource resource = new ServletContextResource(servletContext, "/mail/logo.png");
// FileSystemResource file = new
// FileSystemResource("H:\\\\test\\\\logo.png");
helper.addInline("file", resource);
mailSender.send(msg);
} catch (MailException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
5 基于POI将分区数据导出excel文件
需求:将数据分区表中分区数据导出,将数据写入excel文件中,将文件下载。
1、 页面:sub_area.jsp
2、 发送请求
3、 在action中添加导出分区excel文件的方法
/**
* @Description: 1、查询分区记录 2、将记录写入excel文件中 3、将文件下载
*/
@Action("subAreaAction_exportXls")
public String exportXls() throws Exception {
List<SubArea> list = subAreaService.findAll();
//创建excel文件对象(空白)
HSSFWorkbook workbook = new HSSFWorkbook();
//创建标签页
HSSFSheet sheet = workbook.createSheet("分区记录");
//创建标题行
HSSFRow headRow = sheet.createRow(0);
headRow.createCell(0).setCellValue("编号");
headRow.createCell(1).setCellValue("关键字");
headRow.createCell(2).setCellValue("辅助关键字");
headRow.createCell(3).setCellValue("区域");
headRow.createCell(4).setCellValue("定区");
//创建数据行
HSSFRow dataRow;
for (SubArea subArea : list) {
dataRow = sheet.createRow(sheet.getLastRowNum()+1);
dataRow.createCell(0).setCellValue(subArea.getId());
dataRow.createCell(1).setCellValue(subArea.getKeyWords());
dataRow.createCell(2).setCellValue(subArea.getAssistKeyWords());
dataRow.createCell(3).setCellValue(subArea.getArea().getName());
dataRow.createCell(4).setCellValue(subArea.getFixedArea().getFixedAreaName());
}
String fileName = "分区.xls";
//判断浏览器不同,编码方式也不同
String agent = ServletActionContext.getRequest().getHeader("User-Agent");
fileName = FileUtils.encodeDownloadFilename(fileName, agent);
//文件下载:一个流 两个头(1、文件MIME类型 2、文件打开方式(浏览器内部打开,附件下载))
HttpServletResponse response = ServletActionContext.getResponse();
response.setHeader("Content-Type", "application/vnd.ms-excel");
response.setHeader("content-disposition", "attachment;fileName="+fileName);
//将文件下载
workbook.write(response.getOutputStream());
workbook.close();
return NONE;
}
4、 问题:下载文件没有文件名,后缀名
5、 解决:设置两个头信息
6、 问题:文件中文
7、 需要导入工具类,对中文进行编码设置
以上是关于项目一:第十四天 1.在realm中动态授权 2.Shiro整合ehcache 缓存realm中授权信息 3.动态展示菜单数据 4.Quartz定时任务调度框架—Spring整合javamail发送的主要内容,如果未能解决你的问题,请参考以下文章
项目一:第十三天 1菜单数据管理 2权限数据管理 3角色数据管理 4用户数据管理 5在realm中动态查询用户权限,角色 6Shiro中整合ehcache缓存权限数据
008-shiro与spring web项目整合认证授权session管理