📄 16. ejb note.txt
字号:
jboss.mq:service=DestinationManager</depends>
</mbean>
配置主题目的地
<mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mq.destination:service=Topic,name=tarenaTopic">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager</depends>
</mbean>
//发送消息
1)获取连接工厂(服务器端需配置连接工厂) //这一步之前已经学过(熟透了吧)
System.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
System.setProperty(Context.PROVIDER_URL, "localhost");
Context ctx = new InitialContext();
ConnectionFactory cf = (ConnectionFactory)ctx.lookup("ConnectionFactory");//跟之前唯一的不同
2)创建连接
Connection conn = cf.createConnection();
3)创建会话
Session sess = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
//false:不使用事务;Session.AUTO_ACKNOWLEDGE:收到消息后,自动确认消息(有时会要求接收者确认收到消息)
4)获取目的地(服务器端需配置目的地)
Destination dest = (Destination)ctx.lookup("queue/tarenaQueue");
//lookup是队列跟主题唯一的区别,主题用"topic/tarenaTopic"
5)创建生产者(Message Producer)
MessageProducer mp = sess.createProducer(dest);
6)创建消息
TextMessage msg = sess.createTextMessage("无语了...");
msg.setStringProperty("sender", "发言者名字");//这句话,标识自己在发言,让人监听;没有监听者则免了
7)发送消息
mp.send(msg);
8)关闭资源(一般都把前7步放到 try 代码块里,再 catch(JMSException);而这第8步放到 finally 代码块里)
try { mp.close(); } catch (JMSException e) {e.printStackTrace();}
try {sess.close();} catch (JMSException e) {e.printStackTrace();}
try {conn.close();} catch (JMSException e) {e.printStackTrace();}
//接受消息 (前4步跟发送一样)
1)获取连接工厂(服务器端需配置连接工厂)
2)创建连接
3)创建会话
4)获取目的地(服务器端需配置目的地)
5)创建消费者(Message Consumer)
MessageConsumer mc = sess.createConsumer(dest);
6)启动连接(Connection.close())
conn.start();
7)接受消息(recive()或者佣人MessageListener)
Message msg = mc.receive(2000);
// 2000是接收信息的时间(毫秒),在这段时间内收不到就不收了;不写时间则一直等待
8)处理消息
if(msg instanceof TextMessage) System.out.println(((TextMessage)msg).getText());
// Message 是 TextMessage 的父类
9)关闭资源
这一步跟发送消息的相同
//ConnectionFactory的接口
createConnection();
createSession(boolean transacted, int acknowledge);
transacted: JMS消息是否使用事务
acknowledge:Session.AUTO_ACKNOWLEDGE //收到消息时,自动确认消息
Session.Client_ACKNOWLEDGE //到消息时,调用Message.acknowledge()确认消息
Session.DUPS_OK_ACKNOWLEDGE //延时确认消息,(批量确认消息,提高性能)
//JMS消息结构
消息头:消息的标识/路由信息 --系统设置的属性
消息体:真正的消息内容 --程序设置
标识属性:给消息的接收有一个过滤的关键字(可选)--程序设置
message.setStringProperty("sender", "maxwell"); //设置发送者属性(属性名称也是任意的)
5. 消息驱动Bean
容器收消息,收到后调用消息驱动Bean
1)和Stateless SessionBean一样表示无状态的业务逻辑
2)和SessionBean的区别,不由客户调用,由消息驱动,也没有返回值
3)毒消息(由于一直不能确认收到消息,服务器不断的发送重复消息)
解决方法: a.使用Bean管理的事务,不使用默认的CMT事务
b.不要抛出系统异常,try{} catch{} 捕获异常
b.JMX控制台设置重复次数: jboss.mq.destination
继承 javax.jms.MessageListener 接口
消息驱动Bean的生命周期
不存在 -> 就绪
@PostConstruct //当被监听的人第一次发信息时调用;其他人发信息不理会
@PreDestroy //当工程销毁或者关闭服务器时调用
@MessageDriven(activationConfig = { //写在监听类前面
@ActivationConfigProperty //信息类型
(propertyName = "destinationType", propertyValue = "javax.jms.Topic") //队列用"Queue"
,@ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/tt")
,@ActivationConfigProperty //指定只接收某个人的;不写这句则接收所有人
(propertyName = "messageSelector", propertyValue = "sender='Lily'") })
//接收 Queue 消息时,如果有接收者,则直接发给接受着,不会发给监听者
-----------------------------------------------------------
Day7 part6 标注,定时器和拦截器
1. 标注
//常规标注:
@Stateless(name="ejb name")
@Stateful
@MessageDriven
@Remote({If1.class}) //如果这个类实现多个接口,可以只指定其中某个接口是远程接口;默认所有接口都是远程的
@Local(会话Bean接口标注,1.标注远程接口, 2.列出远程接口)
//依赖注入标注
@Resoure(mappedName="JNDI name")
@EJB(beanName="ejb name")
@PersistenceContext(unitName="unit name") //persistence.xml包含多个持久化单元,必须指定unitName
//JPA标注
参看文档
2. 拦截器
拦截器中定义的方法能够在EJB方法调用时自动调用
//四种拦截器:
1)缺省拦截器 部署在 ejb-jar.xml 中;最外层拦截
2)类拦截器 拦截方法写在另一个类,在Bean类名前加 @Interceptors(拦截器类.class);对整个类的方法都有效
3)方法拦截器 拦截方法写在另一个类,在需要拦截的方法前加 @Interceptors(拦截器类.class);仅对这方法有效
4)自我拦截器 拦截方法定义在Bean本身(一个Bean只能有一个自我拦截方法)
@Interceptors(Class.clas) //注册拦截类
@ArrounInvoke //拦截类中的拦截方法
public Object someMethod(InvocationContext ic); //返回值是Object
//拦截器链:
所有拦截器组成了一个拦截器链
ic.proceed(); //调用一下个拦截方法处理
调用顺序:
缺省拦截器,类拦截器,方法拦截器,自我拦截器;同级别拦截器,按声明顺序调用
-----------------------------------------------------------
part7 安全管理
1. 保证安全的四个环节
1)身份验证。 要求用户标识自己的身份,提供证明自己身份的依据,计算机系统对其进行鉴别
2)授权。 一旦用户身份验证通过,系统给用户分配访问资源的权限
3)访问控制。 比较用户具有的权限和访问资源所需的权限
4)安全审计。 记录和分析历史操作事件及数据,查找系统漏洞和可以改进的地方。
目的是保证系统安全,保护数据,防止有意或无意的人为错误,防范和发现计算机网络犯罪活动。
2. JAAS(Java Authentication and Authorization Services )(java验证与授权服务)
专门处理 身份验证(authentication) 及 权限管控(authorization) 的标准服务
1)常用接口:
Subject (包含用户信息:Princial, Credential等)
Principal //身份,授权信息
Credential //密码
LoginContext //登录上下文,用来选择验证模块
使用LoginContext对象来验证Subject对象。LoginContext从配置文件中加载配置信息,这些配置信息告诉LoginContext对象在登录时使用哪一个LoginModule对象。
login() 进行登录操作。该方法激活了配置中制定的所有LoginModule对象。如果成功,它将创建一个经过了验证的Subject对象;否则抛出LoginException异常。
getSubject() 返回经过验证的Subject对象
logout() 注销Subject对象,删除与之相关的Principal对象和凭证
LoginModule //登录模块
CallbackHandler //用来和用户交互,要求用户输入用户名和密码
3. web安全验证
//1 服务器端配置安全域
%Jboss_home%/server/default/conf/login-config.xml
1) 基于属性文件的安全域
2) 基于数据库的安全域
//2 WebRoot/WEB-INF/jboss-web.xml 选择安全域
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<!-- java:/jaas/固定格式,后面的是login-config.xml中配置安全域名称 -->
<security-domain>java:/jaas/websecurity_db</security-domain>
</jboss-web>
//3 WEB-INF/web.xml
1)选择验证方法
表单验证(名称要求,固定写法)
表单name="j_security_check"
用户输入框name="j_user"
密码输入框name="j_password"
Basic验证(弹出一个系统对话框)
2)定义安全约束;限制访问资源的用户
<security-constraint>
<!-- 配置受保护的资源 -->
<web-resource-collection>
<web-resource-name>Director</web-resource-name>
<url-pattern>/admin/*</url-pattern> //定义可以访问的资源
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>director</role-name> //定义什么角色有效(可多个)
</auth-constraint>
</security-constraint>
3)申明安全约束使用的角色
<security-role> <role-name>director</role-name> </security-role>
<security-role> <role-name>trainer</role-name> </security-role>
<security-role> <role-name>student</role-name> </security-role>
//4 基于属性的安全域,web项目的类路径提供用户和角色属性文件
users.properties
roles.properties
备注:基于表单的验证方式不能直接访问login.html
//5 基于数据库的安全域,配置数据库
//编程式授权方式
String role = request.isUserInRole();
4. EJB安全验证
1)选择安全域
(1)部署描述符jboss.xml(优先级高)
(2)标注(jboss-annotations-ejb3.jar)@SecurityDoamin("domain")
2)访问控制
(1)RoleAllowed("role1","role2",)
类级别
方法级别(覆盖类级别设置)
(2)PermitAll
类级别(默认)
方法级别(覆盖类级别设置)
(3)DenyAll()
只能在方法级别上使用
(4)RunAs("other")
用户可以被当作other角色访问资源
3)客户端
SecurityAssociation
setPrincipal (SimplePrincipal)
setCredential (String)
这个帮助类会进行登陆验证,并返回一个Subject,此Subject对象会自动与ctx上下文自动关联
补充:定时器
特定时间执行的某项任务
//1 单动定时器;只运行一次
createTimer(Date expiration, String info) //expiration 指定时间, info 任务的描述信息
createTimer(int duration, String info) //duration 指定多久之后执行任务
//2 多动定时器
createTimer(Date initialExpiration,intervalDuration,info) //intervalDuration:每隔多久执行一次
createTimer(initialDuration, intervalDuration, info)
cancel() //取消任务
@Timeout //定时方法上标注
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -