大家好,又见面了,我是你们的朋友全栈君。
搭建RabbitMQ环境
Springboot整合RabbitMQ
1、添加整合依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2、配置application.yml
提供者
1)创建交换机和队列
@Configuration //一般放在启动类同目录下,由spring容器管理
public class RabbitMQConfiguration {
public static final String FANOUT_NAME="goods_fanoutexchange";
private static final String QUEUE1="goods_queue1";
private static final String QUEUE2="goods_queue2";
/* * 声明队列 * */
@Bean
public Queue getQueue1(){
return new Queue(QUEUE1);
}
/* * 声明队列 * */
@Bean
public Queue getQueue2(){
return new Queue(QUEUE2);
}
/* * 声明交换机 * */
@Bean
public FanoutExchange getFanoutExchange(){
return new FanoutExchange(FANOUT_NAME);
}
/* * 将队列和交换机绑定 * @Bean注解:将方法的返回值直接注入到spring的容器中,并能够有效的通过将另一个方法名作为参数,获得对应方法的返回值。 * */
@Bean
public Binding getBinding1(Queue getQueue1,FanoutExchange getFanoutExchange){
return BindingBuilder.bind(getQueue1).to(getFanoutExchange);
}
@Bean
public Binding getBinding2(Queue getQueue2,FanoutExchange getFanoutExchange){
return BindingBuilder.bind(getQueue2).to(getFanoutExchange);
}
}
2)注入rabbitmq模板对象,将消息放入队列中
@Service
public class GoodsServiceImpl implements IGoodsService {
@Autowired
private GoodsMapper goodsMapper;
@Autowired
private RabbitTemplate rabbitTemplate;
@Reference
private ISearchService searchService;
/* * 添加商品时: * 1、没有消息队列,通过调用搜索服务的方式,将商品信息同步到搜索库 * 2、通过消息队列,将消息放入队列中,搜索服务监听消息队列中的消息 * */
@Override
public int insertGoods(Goods goods) {
int result=goodsMapper.insert(goods);
//通过dubbo调用搜索服务,同步索引库
/*if (result>0){ searchService.insert(goods); }*/
//将添加商品的信息放入rabbitmq中,必须保证实体类序列化且存在id值
rabbitTemplate.convertAndSend(RabbitMQConfiguration.FANOUT_NAME,"",goods);
return result;
}
}
消费者1
——将商品信息添加到搜索库中
@Component
public class RabbitMQListener {
@Autowired
private SolrClient solrClient;
@RabbitListener(queues = "goods_queue1")
public void handlerGoods(Goods goods){
System.out.println("搜索工程消费消息");
//接收mq中的消息
SolrInputDocument solrInputDocument=new SolrInputDocument();
solrInputDocument.addField("id",goods.getId());
solrInputDocument.addField("gname",goods.getGname());
solrInputDocument.addField("gimage",goods.getGimage());
solrInputDocument.addField("ginfo",goods.getGinfo());
solrInputDocument.addField("gsave",goods.getGsave());
//不能传入BigDecimal类型
solrInputDocument.addField("gprice",goods.getGprice().doubleValue());
try {
solrClient.add(solrInputDocument);
solrClient.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
消费者2
——生成freemarker静态页面
@Component
public class RabbitMQListener {
@Autowired
private Configuration configuration;
@Autowired
private HttpServletRequest request;
@RabbitListener(queues = "goods_queue2")
public void handlerGoodsItem(Goods goods){
String [] images=goods.getGimage().split("\\|");
//通过模板生成商品静态页面
try {
System.out.println("详情工程消费消息");
//获取商品详情的模板对象
Template template = configuration.getTemplate("goodsItem.ftl");
String contextPath="";
try{
//request.getContextPath()可以返回当前页面所在的应用的名字(部署的项目名);
contextPath=request.getContextPath();
}catch (Exception e){
//利用catch捕获这个异常
// No thread-bound request found: Are you referring to request attributes outside of an actual web request,
// or processing a request outside of the originally receiving thread?
// If you are actually operating within a web request and still receive this message,
// your code is probably running outside of DispatcherServlet: In this case,
// use RequestContextListener or RequestContextFilter to expose the current request.
e.printStackTrace();
}
//准备商品数据
Map<String,Object> map=new HashMap<>();
map.put("goods",goods);
map.put("context",contextPath);
map.put("images",images);
//生成静态页
//获得classpath路径
String path = this.getClass().getResource("/static/page/").getPath()+goods.getId()+".html";;
template.process(map,new FileWriter(path));
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:通过监听触发的这个方法中,根据注入的request对象获取项目的根路径时异常。
补充
1、获取request对象
1)通过注解获取(推荐):
public class GoodsController{
@Autowired
HttpServletRequest request; //这里可以获取到request
}
2)spring自带的方式:
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
需要配置RequestContextListener监听
普通的web项目(含web.xml)
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
springboot项目(不含web.xml)
//启动类中
@Bean
public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
3)直接在参数中传递
public String getGoods(HttpServletRequest request)
2、对request.getContextPath()的理解:
——是在开发Web项目时,经常用到的方法,是为了解决相对路径的问题,可返回站点的根路径。
比如:要生成一个文件放在服务器上得一个目录下,可以使用request.getContextPath()+/dir,组成一个完整得目录结构!
当使用Tomcat作为Web服务器,项目一般部署在Tomcat下的webapps的目录下。具体来说主要用两种部署的路径:
(1)将web项目中的webRoot下的文件直接拷贝到webapps/ROOT下(删除ROOT下的原有文件);
(2)在Tomcat下的webapps中创建以项目名称命名(当然也可以用其他的名称)的文件夹,并将webRoot下的文件直接拷贝到该文件夹下。
对于第一部署方法,request.getContextPath()的返回值为空(即:””,中间无空格,注意区分null)。
对于第二部署方法,其返回值为:/创建的文件夹的名称。
假定你的web application 名称为news,你在浏览器中输入请求路径:
http://localhost:8080/news/main/list.jsp
则执行下面向行代码后打印出如下结果:
1、 System.out.println(request.getContextPath());
打印结果:/news
2、System.out.println(request.getServletPath());
打印结果:/main/list.jsp
3、 System.out.println(request.getRequestURI());
打印结果:/news/main/list.jsp
4、 System.out.println(request.getRealPath(“/”));
打印结果:F:\Tomcat 6.0\webapps\news\test
request.getContextPath()可以返回当前页面所在的应用的名字;
request.getSchema()可以返回当前页面使用的协议,http 或是 https;
request.getServerName()可以返回当前页面所在的服务器的名字;
request.getServerPort()可以返回当前页面所在的服务器使用的端口,就是80;
实际应用中,一般用来解决jsp测试和生产环境路径不同的问题:
<%
String appContext = request.getContextPath();
String basePath =request.getScheme()+”: //”+request.getServerName()+”:”+request.getServerPort() + appContext;
%>
3、获取项目根路径的方式:
//获取类加载的根路径(/classes)
(1)this.getClass().getResource(“/”).getPath();
// 获取当前类的所在工程路径
this.getClass().getResource(“”).getPath();
//获取类加载的根路径(/classes)
(2)this.getClass().getClassLoader().getResource(“”);
//获取当前项目路径
(3)System.getProperty(“user.dir”);
//获取所有的类路径 包括jar包的路径
(4)System.getProperty(“java.class.path”);
//获取类加载的根路径(/classes)
(5)Thread.currentThread().getContentClassLoader().getResource(“”).getPath();
//表示到项目的根目录下, 要是想到目录下的子文件夹,修改”/“即可
(6)request.getSession().getServletContext().getRealPath(”/”);
写作不易,既然来了,不妨点个关注,点个赞吧!!!
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/146335.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...