骨架圖:
以下代碼開箱即用,直接複製即可(注意MQ配置讀取的是個人配置中心的MQ配置信息)
依次介紹:
一、MQ配置:RabbitConfig
通過@Bean注入了Spring IOC容器中
@Configuration
public class RabbitConfig {
@Value("${mqRabbitHost}")
private String addresses;//設置連接地址
@Value("${mqRabbitUserName}")
public String username;//設置用戶名稱
@Value("${mqRabbitPassword}")
public String password;//設置用戶密碼
//權限控制的基本單位,一個VirtualHost裏面有若干Exchange和MessageQueue,以及指定被哪些user或者團隊使用
@Value("${mqRabbitVirtualHost}")
private String virtualHost;//設置VirtualHost地址
@Value("${mqRabbitPublisher-confirms}")
private boolean publisherConfirms;//發行者確認
@Value("${mqRabbitApi-url}")
public String URL;//
@Bean
public ConnectionFactory connectionFactory() {
//創建連接工廠
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(addresses);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
/** 如果要進行消息回調,則這裏必須要設置爲true */
connectionFactory.setPublisherConfirms(publisherConfirms);
return connectionFactory;
}
/**
* 因爲要設置回調類,所以應是prototype類型,如果是singleton類型,則回調類爲最後一次設置
*
* @return
*/
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public RabbitTemplate rabbitTemplatenew() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
二、entity
(1)Binding:綁定
public class Binding {
/**
* 綁定源
*/
private String source;
/**
* 虛擬主機
*/
private String vhost;
/**
* 綁定目標
*/
private String destination;
/**
* 綁定的目標的類型
*/
private String destination_type;
/**
* 路由鍵
*/
private String routing_key;
/**
* 屬性鍵
*/
private String properties_key;
get and set...
}
(2)Exchange:交換機
public class Exchange {
/**
* 是否持久化
*/
private Boolean durable = true;
/**
* 交換機名稱
*/
private String name;
/**
* 原來交換機名稱
*/
private String oldName;
/**
* 虛擬主機
*/
private String vhost;
/**
* 交換機類型
*/
private String type = "fanout";
/**
* 是否只能交換機內部使用
*/
private String internal;
/**
* 是否自動刪除
*/
private Boolean auto_delete = false;
get and set...
}
(3)Queue:隊列
public class Queue {
/**
* 隊列運行狀態
*/
private String state;
/**
* 隊列名稱
*/
private String name;
/**
* 原來隊列名稱
*/
private String oldName;
/**
* 虛擬主機
*/
private String vhost;
/**
* 是否持久化
*/
private Boolean durable = true;
/**
* 是否自動刪除
*/
private Boolean auto_delete = false;
/**
* 是否排外
*/
private Boolean exclusive = false;
/**
* 對應的節點
*/
private String node;
get and set..
}
三、RabbitMqManageService
@Transactional()
public interface RabbitMqManageService {
/**
* 新增MQ隊列
*/
ResponseResult queueDeclare(Queue queue);
/**
* 修改MQ隊列名稱
*/
ResponseResult queueModify(Queue queue);
/**
* 刪除MQ隊列
*/
ResponseResult queueDelete(Queue queue);
/**
* 新增MQ交換機
*/
ResponseResult exchangeDeclare(Exchange exchange);
/**
* 修改MQ交換機名稱
*/
ResponseResult exchangeModify(Exchange exchange);
/**
* 刪除MQ交換機
*/
ResponseResult exchangeDelete(Exchange exchange);
/**
* MQ交換機綁定隊列
*/
ResponseResult binding(Binding binding);
/**
* 交換機解綁隊列
*/
ResponseResult unbinding(Binding binding);
}
四:RabbitMqManageServiceImpl
@Service
public class RabbitMqManageServiceImpl implements RabbitMqManageService {
@Autowired
private ConnectionFactory connectionFactory;
@Autowired
private RabbitConfig config;
@Override
public ResponseResult queueDeclare(Queue queue) {
// 參數 :
// 隊列名稱,是否持久化,是否排外,是否自動刪除,參數
// 隊列名以 mia.服務名稱.custom 命名
String name = queue.getName();
// boolean begin = name.startsWith("mia.");
// boolean end = name.endsWith(".custom");
ResponseResult result = new ResponseResult();
// if (!begin || !end) {
// throw new BusinessAccessException("隊列命名方式不對");
// }
try {
AMQP.Queue.DeclareOk queueResult =
connectionFactory.createConnection().createChannel(false).queueDeclare(name,
queue.getDurable(), queue.getExclusive(), queue.getAuto_delete(), null);
String resultName = queueResult.getQueue();
if (resultName != null && resultName.equals(name)) {
result.setCode("200");
result.setMsg("success");
}
} catch (AmqpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
@Override
public ResponseResult queueModify(Queue queue) {
String newName = queue.getName();
String oldName = queue.getOldName();
if (newName == null || oldName == null) {
throw new BusinessAccessException("請輸入正確的參數");
}
queue.setName(oldName);
ResponseResult result = this.queueDelete(queue);
if ("200".equals(result.getCode())) {
queue.setName(newName);
result = this.queueDeclare(queue);
if ("200".equals(result.getCode())) {
return result;
} else {
throw new BusinessAccessException("修改隊列失敗,請直接新建隊列");
}
}
return result;
}
@Override
public ResponseResult queueDelete(Queue queue) {
// 參數 :
// 隊列名稱,是否持久化,是否排外,是否自動刪除,參數
// 隊列名以 mia.服務名稱.custom 命名
String name = queue.getName();
// boolean begin = name.startsWith("mia.");
// boolean end = name.endsWith(".custom");
ResponseResult result = new ResponseResult();
Queue queryResult = this.getQueue(name);
if (queryResult.getName() == null) {
result.setMsg("not found queue " + name);
return result;
}
// if (!begin || !end) {
// throw new BusinessAccessException("只能刪除自定義創建隊列");
// }
try {
AMQP.Queue.DeleteOk queueResult =
connectionFactory.createConnection().createChannel(false).queueDelete(name);
if (queueResult.getMessageCount() >= 0) {
result.setCode("200");
result.setMsg("success");
}
} catch (AmqpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 根據名稱查詢某個隊列
*
* @param name
* @return
*/
public Queue getQueue(String name) {
String vHost = "/";
String url = config.URL + "queues/" + HttpUtil.getURLEncoderString(vHost) + "/" + name;
try {
String content = HttpUtil.get(url);
Queue result = JSON.parseObject(content, Queue.class);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 新增MQ交換機
*
* @param exchange
*/
@Override
public ResponseResult exchangeDeclare(Exchange exchange) {
// 參數 :
// 交換機名稱,類型,是否持久化,是否自動刪除,參數
// 交換機名以 mia.業務名稱.custom 命名
String name = exchange.getName();
// boolean begin = name.startsWith("mia.");
// boolean end = name.endsWith(".custom");
ResponseResult result = new ResponseResult();
// if (!begin || !end) {
// throw new BusinessAccessException("交換機命名方式不對");
// }
String type = exchange.getType();
if (!"direct".equals(type) && !"fanout".equals(type) && !"topic".equals(type)
&& !"headers".equals(type)) {
throw new BusinessAccessException("交換機的類型不對");
}
try {
AMQP.Exchange.DeclareOk exchangeResult =
connectionFactory.createConnection().createChannel(false).exchangeDeclare(name, type,
exchange.getDurable(), exchange.getAuto_delete(), null);
if (exchangeResult != null) {
result.setCode("200");
result.setMsg("success");
}
} catch (AmqpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
@Override
public ResponseResult exchangeModify(Exchange exchange) {
String newName = exchange.getName();
String oldName = exchange.getOldName();
if (newName == null || oldName == null) {
throw new BusinessAccessException("請輸入正確的參數");
}
exchange.setName(oldName);
ResponseResult result = this.exchangeDelete(exchange);
if ("200".equals(result.getCode())) {
exchange.setName(newName);
result = this.exchangeDeclare(exchange);
if ("200".equals(result.getCode())) {
return result;
} else {
throw new BusinessAccessException("修改交換機失敗,請直接新建交換機");
}
}
return result;
}
@Override
public ResponseResult exchangeDelete(Exchange exchange) {
// 參數 :
// 交換機名稱,類型,是否持久化,是否自動刪除,參數
// 交換機名以 mia.業務名稱.custom 命名
String name = exchange.getName();
// boolean begin = name.startsWith("mia.");
// boolean end = name.endsWith(".custom");
ResponseResult result = new ResponseResult();
Exchange queryResult = this.getExchange(name);
if (queryResult.getName() == null) {
result.setMsg("not found exchange " + name);
return result;
}
if (queryResult.getName() == null) {
result.setMsg("not found queue " + name);
return result;
}
// if (!begin || !end) {
// throw new BusinessAccessException("只能刪除自定義創建交換機");
// }
try {
AMQP.Exchange.DeleteOk exchangeResult =
connectionFactory.createConnection().createChannel(false).exchangeDelete(name);
if (exchangeResult != null) {
result.setCode("200");
result.setMsg("success");
}
} catch (AmqpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 根據名稱查詢某個交換機
*
* @param name
* @return
*/
public Exchange getExchange(String name) {
String vHost = "/";
String url = config.URL + "exchanges/" + HttpUtil.getURLEncoderString(vHost) + "/" + name;
try {
String content = HttpUtil.get(url);
Exchange result = JSON.parseObject(content, Exchange.class);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public ResponseResult binding(Binding binding) {
// 參數 :
// 隊列名稱,交換機名稱,路由鍵值,參數
String queueName = binding.getDestination();
String exchangeName = binding.getSource();
String key = binding.getRouting_key();
ResponseResult result = new ResponseResult();
Queue queue = this.getQueue(queueName);
Exchange exchange = this.getExchange(exchangeName);
if (queue.getName() == null || exchange.getName() == null) {
result.setMsg("not found queue or exchange");
return result;
}
if (queueName == null || exchangeName == null || key == null) {
throw new BusinessAccessException("關鍵參數不能爲空");
}
try {
AMQP.Queue.BindOk bindOk = connectionFactory.createConnection().createChannel(false)
.queueBind(queueName, exchangeName, key, null);
if (bindOk != null) {
result.setCode("200");
result.setMsg("success");
}
} catch (AmqpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
@Override
public ResponseResult unbinding(Binding binding) {
// 參數 :
// 隊列名稱,交換機名稱,路由鍵值,參數
String queueName = binding.getDestination();
String exchangeName = binding.getSource();
String key = binding.getRouting_key();
ResponseResult result = new ResponseResult();
Queue queue = this.getQueue(queueName);
Exchange exchange = this.getExchange(exchangeName);
if (queue.getName() == null || exchange.getName() == null) {
result.setMsg("not found queue or exchange");
return result;
}
if (queueName == null || exchangeName == null || key == null) {
throw new BusinessAccessException("關鍵參數不能爲空");
}
try {
AMQP.Queue.UnbindOk unbindOk = connectionFactory.createConnection().createChannel(false)
.queueUnbind(queueName, exchangeName, key, null);
if (unbindOk != null) {
result.setCode("200");
result.setMsg("success");
}
} catch (AmqpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
}
五、HttpClient封裝的Get請求,根據名稱查隊列、根據名稱查交換機
public class HttpUtil {
/**
* HttpClient封裝的Get請求
*
* @param url
* @return
*/
public static String get(String url) {
// 創建HttpClientBuilder
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// HttpClient
CloseableHttpClient httpClient = httpClientBuilder.build();
HttpGet httpGet = new HttpGet(url);
RabbitConfig config = new RabbitConfig();
final String authInfo = config.getUsername() + ":" + config.getPassword();
System.out.println("authInfo : " + authInfo);
try {
String encoding = DatatypeConverter.printBase64Binary("guest:guest".getBytes("utf-8"));
httpGet.setHeader("Authorization", "Basic " + encoding);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(httpGet.getRequestLine());
try {
// 執行get請求
HttpResponse httpResponse = httpClient.execute(httpGet);
// 獲取響應消息實體
HttpEntity entity = httpResponse.getEntity();
String content = EntityUtils.toString(entity);
// 響應狀態
System.out.println("status:" + httpResponse.getStatusLine());
System.out.println("content:" + content);
// 判斷響應實體是否爲空
if (entity != null) {
System.out.println("contentEncoding:" + entity.getContentEncoding());
}
return content;
} catch (IOException e) {
e.printStackTrace();
} finally {
try { // 關閉流並釋放資源
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* URL 解碼
*
*/
public static String getURLDecoderString(String str) {
String result = "";
if (null == str) {
return "";
}
try {
result = java.net.URLDecoder.decode(str, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
/**
* URL 轉碼
*
*/
public static String getURLEncoderString(String str) {
String result = "";
if (null == str) {
return "";
}
try {
result = java.net.URLEncoder.encode(str, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return result;
}
}