本博客介绍基于SSM框架(Spring4.0+SpringMVC+Mybatis)组合的Javamail应用,邮箱的话基于腾讯的QQ邮箱,其实也是Foxmail邮箱

先要了解一下SMTP协议和SSL加密
SMTP:称为简单邮件传输协议(Simple Mail Transfer Protocal),目标是向用户提供高效、可靠的邮件传输。SMTP是一种请求响应的协议,也就是客户机向远程服务器发送请求,服务器响应,监听端口是25,所以其工作模式有两种:发送SMTP,接收SMTP

SSL加密:用来保障浏览器和网站服务器的安全性,其原理用译文解释就是:
当你的浏览器向服务器请求一个安全的网页(通常是 https://)

服务器就把它的证书和公匙发回来

浏览器检查证书是不是由可以信赖的机构颁发的,确认证书有效和此证书是此网站的。

使用公钥加密了一个随机对称密钥,包括加密的URL一起发送到服务器

服务器用自己的私匙解密了你发送的钥匙。然后用这把对称加密的钥匙给你请求的URL链接解密。

服务器用你发的对称钥匙给你请求的网页加密。你也有相同的钥匙就可以解密发回来的网页了

然后介绍怎么实现javamail发送邮件,先要下载javamail的jar:http://download.csdn.net/detail/u014427391/9721520

去充当服务器的QQ邮箱开启SMTP服务:
这里写图片描述

写个发送邮件的业务类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.appms.email;
import java.util.Date;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import com.sun.mail.util.MailSSLSocketFactory;
public class JavaEmailSender {
public static void sendEmail(String toEmailAddress,String emailTitle,String emailContent)throws Exception{
Properties props = new Properties();
// 开启debug调试
props.setProperty("mail.debug", "true");
// 发送服务器需要身份验证
props.setProperty("mail.smtp.auth", "true");
// 设置邮件服务器主机名
props.setProperty("mail.host", "smtp.qq.com");
// 发送邮件协议名称
props.setProperty("mail.transport.protocol", "smtp");
/**SSL认证,注意腾讯邮箱是基于SSL加密的,所有需要开启才可以使用**/
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.ssl.socketFactory", sf);
//创建会话
Session session = Session.getInstance(props);
//发送的消息,基于观察者模式进行设计的
Message msg = new MimeMessage(session);
msg.setSubject(emailTitle);
//使用StringBuilder,因为StringBuilder加载速度会比String快,而且线程安全性也不错
StringBuilder builder = new StringBuilder();
builder.append("\n"+emailContent);
builder.append("\n时间 " + new Date());
msg.setText(builder.toString());
msg.setFrom(new InternetAddress("你的QQ邮箱"));
Transport transport = session.getTransport();
transport.connect("smtp.qq.com", "你的QQ邮箱", "你开启SMTP服务申请的独立密码");
//发送消息
transport.sendMessage(msg, new Address[] { new InternetAddress(toEmailAddress) });
transport.close();
}
}

然后写个SpringMVC框架的Controller类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* 跳转到发送邮件页面
* @return
* @throws Exception
*/
@RequestMapping("/goSendEmail")
public ModelAndView goSendEmail(HttpServletRequest request)throws Exception{
ModelAndView mv = this.getModelAndView();
String email = request.getParameter("email");
if(email!=null&&!"".equals(email)){
email = email.trim();
mv.setViewName("member/send_email");
mv.addObject("email", email);
}
return mv;
}
/**
* 发送邮件
* @return
* @throws Exception
*/
@RequestMapping(value="/sendEmail",produces="application/json;charset=UTF-8")
@ResponseBody
public Object sendEmail(HttpServletRequest request)throws Exception{
Map<String,String> map = new HashMap<String,String>();
String msg = "ok"; //发送状态
String toEMAIL = request.getParameter("EMAIL"); //对方邮箱
String TITLE = request.getParameter("TITLE"); //标题
String CONTENT = request.getParameter("CONTENT"); //内容
JavaEmailSender.sendEmail(toEMAIL, TITLE, CONTENT);
map.put("result", msg);
return map;
}

这里用了Jquery TIP插件进行验证提示,所以需要引入相应的Jquery文件

1
2
3
<script type="text/javascript" src="source/js/jquery-1.7.2.js"></script>
<!--提示框-->
<script type="text/javascript" src="source/js/jquery.tips.js"></script>

Jquery表单验证和Ajax异步请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<!-- 发送邮件 -->
<script type="text/javascript">
//发送
function sendEm(){
if($("#TYPE").val()=="1"){
$("#CONTENT").val(getContentTxt());
}else{
$("#CONTENT").val(getContent());
}
if($("#EMAIL").val()==""){
$("#EMAIL").tips({
side:3,
msg:'请输入邮箱',
bg:'#AE81FF',
time:2
});
$("#EMAIL").focus();
return false;
}
if($("#TITLE").val()==""){
$("#TITLE").tips({
side:3,
msg:'请输入标题',
bg:'#AE81FF',
time:2
});
$("#TITLE").focus();
return false;
}
if($("#CONTENT").val()==""){
$("#nr").tips({
side:1,
msg:'请输入内容',
bg:'#AE81FF',
time:3
});
return false;
}
var EMAIL = $("#EMAIL").val();
var TYPE = $("#TYPE").val();
var TITLE = $("#TITLE").val();
var CONTENT = $("#CONTENT").val();
$("#zhongxin").hide();
$("#zhongxin2").show();
$.ajax({
type: "POST",
url: 'retroaction/sendEmail.do?tm='+new Date().getTime(),
data: {EMAIL:EMAIL,TITLE:TITLE,CONTENT:CONTENT},
dataType:'json',
//beforeSend: validateData,
cache: false,
success: function(data){
if("ok" == data.result){
$("#msg").tips({
side:3,
msg:'发送成功!',
bg:'#68B500',
time:5
});
setTimeout("showdiv()",1000);
}else{
$("#msg").tips({
side:3,
msg:'发送失败!',
bg:'#68B500',
time:5
});
}
}
});
}
</script>

JSP页面的调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- 编辑邮箱 -->
<div>
<table style="width:98%;" >
<tr>
<td style="margin-top:0px;">
<div style="float: left;" style="width:81%"><textarea name="EMAIL" id="EMAIL" rows="1" cols="50" style="width:600px;height:20px;" placeholder="请选输入对方邮箱,多个请用(;)分号隔开" title="请选输入对方邮箱,多个请用(;)分号隔开">${email}</textarea></div>
<div style="float: right;" style="width:19%"><a class='btn btn-mini btn-info' title="编辑邮箱" onclick="dialog_open();">编辑邮箱</i></a></div>
</td>
</tr>
<tr>
<td>
<input type="text" name="TITLE" id="TITLE" value="" placeholder="请选输入邮件标题" style="width:98%"/>
</td>
</tr>
<tr>
<td id="nr">
<script id="editor" type="text/plain" style="width:650px;height:259px;"></script>
</td>
</tr>
<tr>
<td style="text-align: center;">
<a class="btn btn-mini btn-primary" onclick="sendEm();">发送</a>
<a class="btn btn-mini btn-danger" onclick="top.Dialog.close();">取消</a>
</td>
</tr>
</table>
</div>
<div id="zhongxin2" class="center" style="display:none"><br/><img src="assets/images/jzx.gif" id='msg' /><br/><h4 class="lighter block green" id='msg'>正在发送...</h4></div>

这里写图片描述

目录

[TOC]

###前言
最近在写自己的个人博客系统,框架采用SpringMVC、Spring4.0、Spring Data/JPA组合,本博客就文档归档功能在Spring Data JPA框架下是如何实现的进行记录。
现在可以star(收藏),watch(关注),但是还在开发中,所以还是还在先别下载
项目github:https://github.com/u014427391/myblog

###文章信息设计
数据暂时这样设计,仅供学习参考,对于文章评论回复,栏目之间的关联还没设计,不过本博客的目的是记录文档归档功能的实现,这个并不会影响
这里写图片描述

VO类:全部采用注解,注意因为我数据库表名为article,所以不需要写@Table注解,表名为其它的话,就需要自己添加@Table注解了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package net.myblog.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* 博客系统文章信息的实体类
* @author Nicky
*/
@Entity
public class Article {
/** 文章Id,自增**/
private int articleId;
/** 文章名称**/
private String articleName;
/** 文章发布时间**/
private Date articleTime;
/** 图片路径,测试**/
private String imgPath;
/** 文章内容**/
private String articleContent;
/** 查看人数**/
private int articleClick;
/** 是否博主推荐。0为否;1为是**/
private int articleSupport;
/** 是否置顶。0为;1为是**/
private int articleUp;
/** 文章类别。0为私有,1为公开,2为仅好友查看**/
private int articleType;
@GeneratedValue
@Id
public int getArticleId() {
return articleId;
}
public void setArticleId(int articleId) {
this.articleId = articleId;
}
@Column(length=100, nullable=false)
public String getArticleName() {
return articleName;
}
public void setArticleName(String articleName) {
this.articleName = articleName;
}
@Temporal(TemporalType.DATE)
@Column(nullable=false, updatable=false)
public Date getArticleTime() {
return articleTime;
}
public void setArticleTime(Date articleTime) {
this.articleTime = articleTime;
}
@Column(length=100)
public String getImgPath() {
return imgPath;
}
public void setImgPath(String imgPath) {
this.imgPath = imgPath;
}
@Column(nullable=false)
public String getArticleContent() {
return articleContent;
}
public void setArticleContent(String articleContent) {
this.articleContent = articleContent;
}
public int getArticleClick() {
return articleClick;
}
public void setArticleClick(int articleClick) {
this.articleClick = articleClick;
}
public int getArticleSupport() {
return articleSupport;
}
public void setArticleSupport(int articleSupport) {
this.articleSupport = articleSupport;
}
public int getArticleUp() {
return articleUp;
}
public void setArticleUp(int articleUp) {
this.articleUp = articleUp;
}
@Column(nullable=false)
public int getArticleType() {
return articleType;
}
public void setArticleType(int articleType) {
this.articleType = articleType;
}
}

###代码实现步骤

文章表里有很多数据,要按照年月获取文章进行归档的话,我们可以使用如下SQL对数据进行分组

1
2
SELECT YEAR(articleTime) AS 'year',MONTH(articleTime) AS 'month',COUNT(*) AS 'count' FROM article
GROUP BY YEAR(articleTime) DESC,MONTH(articleTime);

然后编写数据库层的Repository类,类实现Spring Data JPA提供的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package net.myblog.repository;
import java.util.Date;
import java.util.List;
import net.myblog.entity.Article;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
public interface ArticleRepository extends PagingAndSortingRepository<Article,Integer>{
/**
* 文章归档信息获取
* @return
*/
@Query(value="select year(a.articleTime) as year,month(a.articleTime) as month,"
+ "count(a) as count from Article a group by year(a.articleTime),month(a.articleTime)",
countQuery="select count(1) from (select count(1) from Article a group by year(a.articleTime),month(a.articleTime))")
public List<Object[]> findArticleGroupByTime();
}

然后在Service类,用@Autowired注解调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package net.myblog.service;
import java.util.Date;
import java.util.List;
import net.myblog.entity.Article;
import net.myblog.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class ArticleService {
@Autowired ArticleRepository articleRepository;
/**
* 文章归档信息获取
* @return
*/
@Transactional
public List<Object[]> findArticleGroupByTime(){
return articleRepository.findArticleGroupByTime();
}
}

然后在Controller里调用,用的是SpringMVC框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package net.myblog.web.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.myblog.service.ArticleService;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class BlogIndexController extends BaseController{
@Autowired
ArticleService articleService;
/**
* 访问博客主页
* @return
*/
@RequestMapping(value="/toblog",produces="text/html;charset=UTF-8")
public ModelAndView toBlog(HttpServletRequest request, HttpServletResponse response, Model model)throws ClassNotFoundException{
//获取归档文章信息
List<Object[]> archiveArticles = articleService.findArticleGroupByTime();
model.addAttribute("archiveArticles", archiveArticles);
mv.setViewName("myblog/frame/index");
return mv;
}
}

在JSP页面调用显示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h2><p>文章归档</p></h2>
<ul class="news">
<c:choose>
<c:when test="${not empty archiveArticles }">
<c:forEach items="${archiveArticles }" var="ac">
<li><a href="getArchiveArticles.do?yearmonth=${ac[0]}-${ac[1]}">
${ac[0]}年${ac[1]}月(${ac[2] })</a></li>
</c:forEach>
</c:when>
<c:otherwise>
<li><a href="#">没有相关数据</a></li>
</c:otherwise>
</c:choose>
</ul>

效果如图所示:
这里写图片描述

###文档归档信息查询
然后介绍点击文档归档信息后,获取文章信息的实现,其实也就是按年月查询文档信息

在Repository类里添加方法:

1
2
3
4
5
6
7
8
9
/**
* 按月份获取文章信息
* @param month
* 月份数
* @return
*/
@Query("from Article a where date_format(a.articleTime,'%Y%m')=date_format((:yearmonth),'%Y%m') "
+ "order by articleTime desc")
public List<Article> findArticleByMonth(@Param("yearmonth")Date yearmonth);

Service类里调用:

1
2
3
4
5
6
7
8
9
/**
* 按月份获取文章信息
* @param month
* @return
*/
@Transactional
public List<Article> findArticleByMonth(Date month){
return articleRepository.findArticleByMonth(month);
}

在JSP页面写入,getArchiveArticles.do就是要访问的url,传入yearmonth参数就可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h2><p>文章归档</p></h2>
<ul class="news">
<c:choose>
<c:when test="${not empty archiveArticles }">
<c:forEach items="${archiveArticles }" var="ac">
<li><a href="getArchiveArticles.do?yearmonth=${ac[0]}-${ac[1]}">
${ac[0]}年${ac[1]}月(${ac[2] })</a></li>
</c:forEach>
</c:when>
<c:otherwise>
<li><a href="#">没有相关数据</a></li>
</c:otherwise>
</c:choose>
</ul>

在Controller类里进行处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RequestMapping("/getArchiveArticles")
public ModelAndView getArticleByMonth(HttpServletRequest request){
String yearMonthString = request.getParameter("yearmonth");
System.out.println("month:"+yearMonthString);
ModelAndView mv = this.getModelAndView();
Date yearmonth = DateUtils.parse("yyyy-MM", yearMonthString);
List<Article> articles = articleService.findArticleByMonth(yearmonth);
mv.addObject("articles", articles);
mv.setViewName("myblog/article/archive_articles");
return mv;
}

这里写图片描述

###附录(工具类、公共类代码)
DateUtils.java、BaseController.java类
DateUtil.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package net.myblog.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import net.myblog.core.Constants;
public class DateUtils {
public static String formatDate(Date date) throws ParseException{
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return dateFormat.format(date);
}
/**
* 解析日期,注:此处为严格模式解析,即20151809这样的日期会解析错误
*
* @param pattern
* @param date
* @return
*/
public static Date parse(String pattern, String date){
return parse(pattern, date, Constants.LOCALE_CHINA);
}
/**
* 解析日期,注:此处为严格模式解析,即20151809这样的日期会解析错误
*
* @param pattern
* @param date
* @param locale
* @return
*/
public static Date parse(String pattern, String date, Locale locale){
SimpleDateFormat format = new SimpleDateFormat(pattern, locale);
format.setLenient(false);
Date result = null;
try{
result = format.parse(date);
}catch(Exception e){
e.printStackTrace();
}
return result;
}
}

BaseController.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package net.myblog.web.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;
public class BaseController {
/**
* 得到request对象
*/
public HttpServletRequest getRequest() {
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
return request;
}
/**
* 得到ModelAndView
*/
public ModelAndView getModelAndView(){
return new ModelAndView();
}
}

[TOC]

##前言##
本博客介绍Java中间件的一些知识,仅仅是一些知识储备。

##中间件##

###中间件概念###
中间件:中间件是一种介于操作系统和应用软件之间的一种软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的。
若是以新一代的中间件系列产品来组合应用,同时配合以可复用的商务对象构件,则应用开发费用可节省至80%。

###中间件分类###

  1. 消息中间件
    消息中间件适用与进行网络通讯的系统,建立网络通讯的通道,进行数据和文件的传送
    产品:ActiveMQ、ZeroMQ、RabbitMQ、IBM webSphere MQ…
  2. 交易中间件
    交易中间件管理分布与不同操作系统的数据,实现数据一致性,保证系统的负载均衡
    产品:IBM CICS,Bea tuxedo…
  3. 对象中间件
    保证不同厂家的软件之间的交互访问
    产品:IBM componentbroker, iona orbix,borland visibroker…
  4. 应用服务器
    用来构造internet/intranet应用和其它分布式构件应用
    产品:IBM Websphere,Bea weblogic…
  5. 安全中间件
    以公钥基础设施(pki)为核心的、建立在一系列相关国际安全标准之上的一个开放式应用开发平台
    产品:entrust entrust…
  6. 应用集成服务器
    把工作流和应用开发技术如消息及分布式构件结合在一起,使处理能方便自动地和构件、script 应用、工作流行为结合在一起,同时集成文档和电子邮件
    产品:lss flowman、ibm flowmark、vitria businessagiliti

##ESB##
ESB,即企业服务总线
松散耦合一直是企业软件开发中的一个很重要的内容,而面向服务的SOA编程在随着ESB的应用得到了进一步的发展,ESB就像服务提供者和服务使用者之间的中间层
这里写图片描述

##JMS##
JMS,即Java Message Service
ESB仅仅是作为一个中间层,所以应用程序之间的消息通讯必须借助JMS,即通过JMS从服务使用者接收消息,并将其转发到相应的服务提供者。
而且,JMS 还定义了可发送的若干不同类型的消息。例如,Text 消息包含消息的字符串表示形式;Object 消息包含序列化的 Java 对象;Map 消息包含键/值对的映射,等等。

附录:
MQ DEMO:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
package com.wms.batchMsg;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.Date;
import org.apache.log4j.Logger;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.MQConstants;
public class MQUtil {
private static String qmName;
private static MQQueueManager qMgr;
private static Logger logger = Logger.getLogger(MQUtil.class);
static{
try{
MQEnvironment.hostname=ConfigManager.getValue("MQ_MQHost");
MQEnvironment.channel=ConfigManager.getValue("MQ_Server_Channel");
MQEnvironment.CCSID=Integer.parseInt(ConfigManager.getValue("MQ_CCSID"));
MQEnvironment.port=Integer.parseInt(ConfigManager.getValue("MQ_port"));
//MQEnvironment.userID = ConfigManager.getValue("MQ_UserId");
//MQEnvironment.password = ConfigManager.getValue("MQ_pass");
qmName = ConfigManager.getValue("MQ_QMname");
MQEnvironment.properties.put(MQConstants.TRANSPORT_PROPERTY,MQConstants.TRANSPORT_MQSERIES_CLIENT);
qMgr = new MQQueueManager(qmName);
}catch(MQException e){
e.printStackTrace();
logger.info("qManager failed: Completion code " + e.completionCode + " Reason Code is "
+ e.reasonCode);
}
}
public static MQQueue getSendQueue(String queueName) {
MQQueue sQueue;
int openSendOptions = MQConstants.MQOO_OUTPUT | MQConstants.MQOO_FAIL_IF_QUIESCING
| MQConstants.MQOO_SET_IDENTITY_CONTEXT;
try {
sQueue = qMgr.accessQueue(queueName, openSendOptions);
} catch (MQException e) {
e.printStackTrace();
return null;
}
return sQueue;
}
public static MQQueue getReceiveQueue(String revQueueName){
MQQueue rQueue ;
int openRcvOptions = MQConstants.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_FAIL_IF_QUIESCING;
try{
rQueue = qMgr.accessQueue(revQueueName, openRcvOptions);
}catch(MQException e){
e.printStackTrace();
return null;
}
return rQueue;
}
public static void sendMsg(MQMsgEntity entity,String queueName) {
MQQueue sendQ = null;
try {
MQMessage qMsg = new MQMessage();
byte[] qByte = entity.getMsgStr().getBytes("UTF-8");
// String message = entity.getMsgStr();
qMsg.messageId = MQConstants.MQMI_NONE;
//TODO send and receive
if(entity.getCorrelId()!=null){
qMsg.correlationId = entity.getCorrelId();
}
qMsg.format = MQConstants.MQFMT_STRING;
qMsg.write(qByte);
MQPutMessageOptions pmo = new MQPutMessageOptions();
pmo.options = pmo.options + MQConstants.MQPMO_NEW_MSG_ID;
pmo.options = pmo.options + MQConstants.MQPMO_NO_SYNCPOINT;
pmo.options = pmo.options + MQConstants.MQPMO_SET_IDENTITY_CONTEXT;
sendQ = getSendQueue(queueName);
sendQ.put(qMsg, pmo);
qMgr.commit();
//logger.info("The send message is: " +new String(qByte,"UTF-8"));
} catch (MQException e) {
logger.info("A WebSphere MQ error occurred : Completion code "
+ e.completionCode + " Reason Code is "
+ e.reasonCode);
} catch (java.io.IOException e) {
logger.info("An error occurred whilst to the message buffer "
+ e);
}finally{
try{
if(sendQ!=null){
sendQ.close();
}
}catch(MQException e){
// TODO Auto-generated catch block
e.printStackTrace();
logger.info("Error for MQ connection:"+e.getMessage());
}
}
}
// public static void messageHandlerByQueueName(MQMsgEntity entity,String queueName) {
// try {
// if(queueName.equalsIgnoreCase("sap_OrdersQueue")){
// ECOrder order = new ECOrder();
// order.CallOrderCURFC(entity, "ZECI001");
// }else if(queueName.equalsIgnoreCase("sap_OrderPendReqQueue")){
// ECOrderPending orderPending = new ECOrderPending();
// orderPending.CallOrderPendRFC(entity, "ZECI005");
// }else if(queueName.equalsIgnoreCase("sap_OrderPendCancelQueue")){
// ECOrderPending orderPending = new ECOrderPending();
// orderPending.CallCancelOrderPendRFC(entity, "ZECI006");
// }else if(queueName.equalsIgnoreCase("sap_ECReturnsQueue")){
// ECOrder order = new ECOrder();
// order.callOrderCancelRFC(entity, "ZECI001");
// }else if(queueName.equalsIgnoreCase("sap_downpaymentQueue")){
// ECDownPayment downPayment = new ECDownPayment();
// downPayment.callDownPaymentRFC(entity, "ZECI007");
// }else if(queueName.equalsIgnoreCase("sap_360LBPQueue")){
// EC360LBP lbp = new EC360LBP();
// lbp.generateHtmlFromQueue(entity.getMsgStr());
// }
// } catch (Exception e) {
// e.printStackTrace();
// logger.error(e.getMessage());
// }
//
// }
public MQQueueManager generateNewMQQM(){
MQQueueManager qMgr = null;
try{
MQEnvironment.hostname=ConfigManager.getValue("MQ_MQHost");
MQEnvironment.channel=ConfigManager.getValue("MQ_Server_Channel");
MQEnvironment.CCSID=Integer.parseInt(ConfigManager.getValue("MQ_CCSID"));
MQEnvironment.port=Integer.parseInt(ConfigManager.getValue("MQ_port"));
String qmName = ConfigManager.getValue("MQ_QMname");
MQEnvironment.properties.put(MQConstants.TRANSPORT_PROPERTY,MQConstants.TRANSPORT_MQSERIES_CLIENT);
qMgr = new MQQueueManager(qmName);
}catch(MQException e){
e.printStackTrace();
logger.info("qManager failed: Completion code " + e.completionCode + " Reason Code is "
+ e.reasonCode);
}
return qMgr;
}
public void MultiThreadGetMqMessage(MQQueueManager qMgr,String queueName){
MQQueue revQ = null;
String mqString = null;
MQMsgEntity entity = new MQMsgEntity();
int openRcvOptions = MQConstants.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_FAIL_IF_QUIESCING;
try {
MQMessage retrievedMessage = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options += MQConstants.MQPMO_NO_SYNCPOINT;//
gmo.options = gmo.options + MQConstants.MQGMO_WAIT;//
gmo.options = gmo.options + MQConstants.MQGMO_FAIL_IF_QUIESCING;//
gmo.waitInterval = MQConstants.MQWI_UNLIMITED;//
gmo.matchOptions = MQConstants.MQMO_MATCH_MSG_ID;
retrievedMessage.format=MQConstants.MQFMT_STRING;
// MQC.MQWI_UNLIMITED;
revQ = qMgr.accessQueue(queueName, openRcvOptions);
revQ.get(retrievedMessage, gmo);
qMgr.commit();
int length = retrievedMessage.getDataLength();
if(length >0){
long startTime = System.currentTimeMillis();
byte[] msg = new byte[length];
retrievedMessage.readFully(msg);
mqString = new String(msg, "UTF-8");
if(queueName.equalsIgnoreCase("sap_360LBPQueue")){
mqString = mqString.replace("'", "\"");
}
long timeuse = System.currentTimeMillis() - startTime;
Date currentDate = new Date();
Timestamp receiveTimestamp = new Timestamp(currentDate.getTime());
logger.info("=========mqString from "+queueName+" :"+mqString);
DBUtil.insertIntoMQLog("Receive",queueName, mqString, timeuse, "success", "", null, receiveTimestamp);
entity.setMsgStr(mqString);
//messageHandlerByQueueName(entity,queueName);
}else{
logger.info("Error MQ string Sent!");
}
}
catch (MQException e) {
e.printStackTrace();
if (e.reasonCode != 2033)
{
logger.info(e.getMessage());
logger.info("Completion code "
+ e.completionCode + " Reason Code is " + e.reasonCode);
}
} catch (IOException e) {
logger.info("IO error:" + e.getMessage());
} finally{
try{
if(revQ!=null){
revQ.close();
}
}catch(MQException mqEx){
int rc = mqEx.reasonCode;
if (rc != MQException.MQRC_NO_MSG_AVAILABLE)
{
logger.info(" PUT Message failed with rc = "
+ rc);
}
}
}
}
public static String getMQMessage(String queueName) throws ParseException {
MQQueue revQ = null;
String mqString = null;
MQMsgEntity entity = new MQMsgEntity();
try {
MQMessage retrievedMessage = new MQMessage();
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options += MQConstants.MQPMO_NO_SYNCPOINT;//
gmo.options = gmo.options + MQConstants.MQGMO_WAIT;//
gmo.options = gmo.options + MQConstants.MQGMO_FAIL_IF_QUIESCING;//
gmo.waitInterval = MQConstants.MQWI_UNLIMITED;//
gmo.matchOptions = MQConstants.MQMO_MATCH_MSG_ID;
retrievedMessage.format=MQConstants.MQFMT_STRING;
// MQC.MQWI_UNLIMITED;
revQ = getReceiveQueue(queueName);
revQ.get(retrievedMessage, gmo);
qMgr.commit();
int length = retrievedMessage.getDataLength();
if(length >0){
byte[] msg = new byte[length];
retrievedMessage.readFully(msg);
mqString = new String(msg, "UTF-8");
logger.info("=========getMQMessage===mqString from "+queueName+" :"+mqString);
entity.setMsgStr(mqString);
//messageHandlerByQueueName(entity,queueName);
}else{
logger.info("Error MQ string Sent!");
}
}
catch (MQException e) {
e.printStackTrace();
if (e.reasonCode != 2033)
{
e.printStackTrace();
logger.info("Completion code "
+ e.completionCode + " Reason Code is " + e.reasonCode);
}
} catch (java.io.IOException e) {
System.out.println("error" + e.getMessage());
}finally{
try{
if(revQ!=null){
revQ.close();
}
}catch(MQException mqEx){
int rc = mqEx.reasonCode;
if (rc != MQException.MQRC_NO_MSG_AVAILABLE)
{
System.out.println(" PUT Message failed with rc = "
+ rc);
}
}
}
return mqString;
}
public void revAndSend(MQMsgEntity entity,String queueName){
//
sendMsg(entity,queueName);
}
public void subscribeMessage() throws ParseException{
while(true){
logger.info("waiting to get message.....");
getMQMessage("sap_OrdersQueue");
}
}
public void subscribeOrderPendMessage() throws ParseException{
while(true){
logger.info("waiting to get message.....");
getMQMessage("sap_ECReturnsQueue");
}
}
public static void main(String[] args) throws IOException, ParseException {
MQMsgEntity entity = new MQMsgEntity();
String sendMsg = XMLBeanUtil.readFileToString(new File("D://batchXML0108.txt"));
int intPktCtlNbr = 1;
String StrPkt = null;
String newPktCtlNbr =null;
for (int i = 0; i < 20000; i++) {
newPktCtlNbr = String.format("%09d", intPktCtlNbr+i);
StrPkt="<PktCtlNbr>"+"V"+newPktCtlNbr+"</PktCtlNbr>";
String changeSendMsg = sendMsg.replaceAll("<PktCtlNbr>6001996171</PktCtlNbr>", StrPkt);
System.out.println(StrPkt);
entity.setMsgStr(changeSendMsg);
sendMsg(entity,"wms_SAPOrderQueue");
}
// MQUtil util = new MQUtil();
// util.subscribeMessage();
// util.subscribeOrderPendMessage();
// util.messageHandlerByQueueName(entity, "sap_360LBPQueue");
// getMQMessage("sap_OrderPendCancelQueue");
// System.out.println("rev message is:"+message);
}
}
|