设为首页 收藏本站
查看: 1303|回复: 3

[经验分享] ActiveMq+spring jms+MQ主备

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-4-15 08:42:31 | 显示全部楼层 |阅读模式
项目中需要把原有清分系统的业务层和分发层,日志层拆分开做3个单独的服务节点,他们之间的通信

通过ActiveMq。我研究了下,最终部署上去了。附件中是文档。
一、架构和技术介绍1、简介
ActiveMQ Apache出品,最流行的,能力强劲的开源消息总线。完全支持JMS1.1J2EE 1.4规范的 JMS Provider实现
2、activemq的特性
1. 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
2. 完全支持JMS1.1J2EE 1.4规范 (持久化,XA消息,事务)
3. Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性
4. 通过了常见J2EE服务器( Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resourceadaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE1.4商业服务器上
5. 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
6. 支持通过JDBCjournal提供高速的消息持久化
7. 从设计上保证了高性能的集群,客户端-服务器,点对点
8. 支持Ajax
9. 支持与Axis的整合
10. 可以很容易得调用内嵌JMS provider,进行测试
3、下载和安装ActiveMQ
1、下载
ActiveMQ的最新版本是5.10.0,但由于我们内网下载存在问题,所以目前通过内网只能下载到5.9.0,下载地址:http://activemq.apache.org/activemq-590-release.html
2、安装
         如果是在windows系统中运行,可以直接解压apache-activemq-5.9.0-bin.zip,并运行bin目录下的activemq.bat文件,此时使用的是默认的服务端口:61616和默认的console端口:8161
         如果是在linuxunix下运行,在bin目录下执行命令:./activemq setup
3、修改ActiveMQ的服务端口和console端口
         A、修改服务端口:打开conf/activemq.xml文件,修改以下红色字体部分
        <transportConnectors>
           <transportConnector name="openwire" uri="tcp://10.42.220.72:61618"discoveryUri="multicast://default"/>
       </transportConnectors>
B、修改console的地址和端口:打开conf/jetty.xml文件,修改以下红色字体部分
    <bean id="jettyPort"class="org.apache.activemq.web.WebConsolePort"init-method="start">
       <property name="port" value="8162"/>
</bean>
4、通过客户端代码试用ActiveMQ
        需要提前将activemq解压包中的lib目录下的相关包引入到工程中,再进行如下编码:
1、发送端的代码:
importjavax.jms.Connection;
importjavax.jms.ConnectionFactory;
importjavax.jms.DeliveryMode;
importjavax.jms.Destination;
importjavax.jms.MessageProducer;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnection;
importorg.apache.activemq.ActiveMQConnectionFactory;
publicclass Sender {
    privatestaticfinalintSEND_NUMBER = 5;

    publicstaticvoid main(String[] args) {
        // ConnectionFactory:连接工厂,JMS用它创建连接
        ConnectionFactory connectionFactory;
        // ConnectionJMS客户端到JMS Provider的连接
        Connection connection = null;
        // Session一个发送或接收消息的线程
        Session session;
        // Destination:消息的目的地;消息发送给谁.
        Destination destination;
        // MessageProducer:消息发送者
        MessageProducer producer;
        // TextMessage message;
        //构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
        connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD,
                "failover:(tcp://10.42.220.72:61617,tcp://10.42.220.72:61618)");
        try {
            //构造从工厂得到连接对象
            connection =connectionFactory.createConnection();
            //启动
            connection.start();
            //获取操作连接
            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            //获取session
            destination = session.createQueue("FirstQueue");
            //得到消息生成者【发送者】
            producer =session.createProducer(destination);
            //设置不持久化,此处学习,实际根据项目决定
           producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
            //构造消息,此处写死,项目就是参数,或者方法获取
            sendMessage(session, producer);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != connection)
                    connection.close();
            } catch (Throwable ignore) {
            }
        }
        }
   
    publicstaticvoid sendMessage(Session session,MessageProducer producer)
            throws Exception {
        for (int i = 1; i <=SEND_NUMBER; i++) {
            TextMessage message = session
                    .createTextMessage("ActiveMq发送的消息" + i);
            //发送消息到目的地方
            System.out.println("发送消息:" + "ActiveMq 发送的消息" + i);
            producer.send(message);
        }
    }
}
2、接收端代码:
importjavax.jms.Connection;
importjavax.jms.ConnectionFactory;
importjavax.jms.Destination;
importjavax.jms.MessageConsumer;
importjavax.jms.Session;
importjavax.jms.TextMessage;
importorg.apache.activemq.ActiveMQConnection;
importorg.apache.activemq.ActiveMQConnectionFactory;

publicclass Receive {
    publicstaticvoid main(String[] args) {
        // ConnectionFactory:连接工厂,JMS用它创建连接
        ConnectionFactory connectionFactory;
        // ConnectionJMS客户端到JMS Provider的连接
        Connection connection = null;
        // Session一个发送或接收消息的线程
        Session session;
        // Destination:消息的目的地;消息发送给谁.
        Destination destination;
        //消费者,消息接收者
        MessageConsumer consumer;
        connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD,
                "failover:(tcp://10.42.220.72:61617,tcp://10.42.220.72:61618)");
        try {
            //构造从工厂得到连接对象
            connection =connectionFactory.createConnection();
            //启动
            connection.start();
            //获取操作连接
            session = connection.createSession(false,
                    Session.AUTO_ACKNOWLEDGE);
            //获取session
            destination = session.createQueue("FirstQueue");
            consumer =session.createConsumer(destination);
            while (true) {
                //设置接收者接收消息的时间,为了便于测试,这里谁定为100s
                TextMessage message =(TextMessage) consumer.receive(100000);
                if (null != message) {
                    System.out.println("收到消息" + message.getText());
                } else {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != connection)
                    connection.close();
            } catch (Throwable ignore) {
            }
        }
    }
}
3、通过监控查看消息堆栈的记录:
      登陆http://localhost:8162/admin/queues.jsp,默认的用户名和密码:admin/admin
20140515120044_198.jpg
二、ActiveMQ的多种部署方式
         单点的ActiveMQ作为企业应用无法满足高可用和集群的需求,所以ActiveMQ提供了master-slavebroker cluster等多种部署方式,但通过分析多种部署方式之后我认为需要将两种部署方式相结合才能满足我们公司分布式和高可用的需求,所以后面就重点将解如何将两种部署方式相结合。
1、Master-Slave部署方式1)shared filesystem Master-Slave部署方式         主要是通过共享存储目录来实现masterslave的热备,所有的ActiveMQ应用都在不断地获取共享目录的控制权,哪个应用抢到了控制权,它就成为master
         多个共享存储目录的应用,谁先启动,谁就可以最早取得共享目录的控制权成为master,其他的应用就只能作为slave
20140515120001_591.jpg
2)shared database Master-Slave方式         shared filesystem方式类似,只是共享的存储介质由文件系统改成了数据库而已。
3)Replicated LevelDB Store方式         这种主备方式是ActiveMQ5.9以后才新增的特性,使用ZooKeeper协调选择一个node作为master。被选择的master broker node开启并接受客户端连接。
其他node转入slave模式,连接master并同步他们的存储状态。slave不接受客户端连接。所有的存储操作都将被复制到连接至Master的slaves。
如果master死了,得到了最新更新的slave被允许成为master。fialed node能够重新加入到网络中并连接master进入slave mode。所有需要同步的disk的消息操作都将等待存储状态被复制到其他法定节点的操作完成才能完成。所以,如果你配置了replicas=3,那么法定大小是(3/2)+1=2. Master将会存储并更新然后等待 (2-1)=1个slave存储和更新完成,才汇报success。至于为什么是2-1,熟悉Zookeeper的应该知道,有一个node要作为观擦者存在。
单一个新的master被选中,你需要至少保障一个法定node在线以能够找到拥有最新状态的node。这个node将会成为新的master。因此,推荐运行至少3个replica nodes,以防止一个node失败了,服务中断。
20140515115951_604.jpg
2、Broker-Cluster部署方式         前面的Master-Slave的方式虽然能解决多服务热备的高可用问题,但无法解决负载均衡和分布式的问题。Broker-Cluster的部署方式就可以解决负载均衡的问题。
         Broker-Cluster部署方式中,各个broker通过网络互相连接,并共享queue。当broker-A上面指定的queue-A中接收到一个message处于pending状态,而此时没有consumer连接broker-A时。如果cluster中的broker-B上面由一个consumer在消费queue-A的消息,那么broker-B会先通过内部网络获取到broker-A上面的message,并通知自己的consumer来消费。
1)static Broker-Cluster部署         activemq.xml文件中静态指定Broker需要建立桥连接的其他Broker
1、  首先在Broker-A节点中添加networkConnector节点:
<networkConnectors>  
                <networkConnector   uri="static:(tcp:// 0.0.0.0:61617)"duplex="false"/>
</networkConnectors>
2、  修改Broker-A节点中的服务提供端口为61616:
<transportConnectors>
         <transportConnectorname="openwire"uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
3、  在Broker-B节点中添加networkConnector节点:
<networkConnectors>  
                <networkConnector   uri="static:(tcp:// 0.0.0.0:61616)"duplex="false"/>
</networkConnectors>
4、  修改Broker-A节点中的服务提供端口为61617:
<transportConnectors>
         <transportConnectorname="openwire"uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
5、分别启动Broker-ABroker-B
2)Dynamic Broker-Cluster部署         activemq.xml文件中不直接指定Broker需要建立桥连接的其他Broker,由activemq在启动后动态查找:
1、  首先在Broker-A节点中添加networkConnector节点:
<networkConnectors>  
                <networkConnectoruri="multicast://default"
           dynamicOnly="true"
           networkTTL="3"
           prefetchSize="1"
           decreaseNetworkConsumerPriority="true" />
</networkConnectors>
2、修改Broker-A节点中的服务提供端口为61616
<transportConnectors>
         <transportConnectorname="openwire"uri="tcp://0.0.0.0:61616? " discoveryUri="multicast://default"/>
</transportConnectors>
3、在Broker-B节点中添加networkConnector节点:
<networkConnectors>  
                <networkConnectoruri="multicast://default"
           dynamicOnly="true"
           networkTTL="3"
           prefetchSize="1"
           decreaseNetworkConsumerPriority="true" />
</networkConnectors>
4、修改Broker-B节点中的服务提供端口为61617
<transportConnectors>
         <transportConnectorname="openwire"uri="tcp://0.0.0.0:61617" discoveryUri="multicast://default"/>
</transportConnectors>
5、启动Broker-ABroker-B
2、Master-Slave与Broker-Cluster相结合的部署方式         可以看到Master-Slave的部署方式虽然解决了高可用的问题,但不支持负载均衡,Broker-Cluster解决了负载均衡,但当其中一个Broker突然宕掉的话,那么存在于该Broker上处于Pending状态的message将会丢失,无法达到高可用的目的。
         由于目前ActiveMQ官网上并没有一个明确的将两种部署方式相结合的部署方案,所以我尝试者把两者结合起来部署:
          20140515115919_992.jpg
1、部署的配置修改         这里以Broker-A + Broker-B建立clusterBroker-C作为Broker-Bslave为例:
1)首先在Broker-A节点中添加networkConnector节点:
<networkConnectors>  
                <networkConnector   uri="masterslave:(tcp://0.0.0.0:61617,tcp:// 0.0.0.0:61618)" duplex="false"/>
</networkConnectors>
2)修改Broker-A节点中的服务提供端口为61616
<transportConnectors>
         <transportConnectorname="openwire"uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
3)Broker-B节点中添加networkConnector节点:
<networkConnectors>  
                <networkConnector   uri="static:(tcp:// 0.0.0.0:61616)"duplex="false"/>
</networkConnectors>
4)修改Broker-B节点中的服务提供端口为61617
<transportConnectors>
         <transportConnectorname="openwire"uri="tcp://0.0.0.0:61617?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
5)修改Broker-B节点中的持久化方式:
     <persistenceAdapter>
           <kahaDB directory="/localhost/kahadb"/>
        </persistenceAdapter>
6)Broker-C节点中添加networkConnector节点:
<networkConnectors>  
                <networkConnector   uri="static:(tcp:// 0.0.0.0:61616)"duplex="false"/>
</networkConnectors>
7)修改Broker-C节点中的服务提供端口为61618
<transportConnectors>
         <transportConnectorname="openwire"uri="tcp://0.0.0.0:61618?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
8)修改Broker-B节点中的持久化方式:
     <persistenceAdapter>
           <kahaDB directory="/localhost/kahadb"/>
       </persistenceAdapter>
9)分别启动broker-Abroker-Bbroker-C,因为是broker-B先启动,所以“/localhost/kahadb”目录被lock住,broker-C将一直处于挂起状态,当人为停掉broker-B之后,broker-C将获取目录“/localhost/kahadb”的控制权,重新与broker-A组成cluster提供服务。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-57244-1-1.html 上篇帖子: RabbitMQ 消息队列 配置 下篇帖子: Rsync + Crontab实现定时文件同步(首次全量+后续增量) spring

尚未签到

发表于 2015-5-19 16:31:17 | 显示全部楼层


基于Spring+JMS+ActiveMQ+Tomcat,我使用的版本情况如下所示:

    Spring 2.5
    ActiveMQ 5.4.0
    Tomcat 6.0.30

下面通过学习与配置,实现消息服务的基本功能:发送与接收。Spring对JMS提供了很好的支持,可以通过JmsTemplate来方便地实现消息服务。这里,我们的消息服务不涉及事务管理。下面简单说明实现过程:

先看一下,我们最终的Spring配置文件applicationContext.xml的内容,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans"  
        xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
            http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">  
      
        <bean id="listenerContainer"  
            class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
            <property name="connectionFactory" ref="connectionFactory"></property>  
            <property name="destination" ref="messageQueue"></property>  
            <property name="messageListener" ref="receiveMessageListener"></property>  
        </bean>  
        <bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">  
            <property name="jndiName" value="java:comp/env/myJMS/ConnectionFactory"></property>  
        </bean>  
        <bean id="messageQueue" class="org.springframework.jndi.JndiObjectFactoryBean">  
            <property name="jndiName" value="java:comp/env/myJMS/MessageQueue"></property>  
        </bean>  
        <bean id="receiveMessageListener"  
            class="org.shirdrn.spring.jms.integration.ReceiveMessageListener"></bean>  
      
        <bean id="messageSender" class="org.shirdrn.spring.jms.integration.MessageSender">  
            <property name="jmsTemplate" ref="jmsTemplate"></property>  
        </bean>  
        <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
            <property name="connectionFactory" ref="connectionFactory"></property>  
            <property name="defaultDestination" ref="messageQueue"></property>  
        </bean>  
      
        <bean id="sendMessageController"  
            class="org.shirdrn.spring.jms.integration.SendMessageController">  
            <property name="messageSender" ref="messageSender" />  
            <property name="successView" value="/success" />  
        </bean>  
        <bean id="urlMapping"  
            class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
            <property name="mappings">  
                <props>  
                    <prop key="/sendMessage.do">sendMessageController</prop>  
                </props>  
            </property>  
        </bean>  
        <bean id="viewResolver"  
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
            <property name="requestContextAttribute" value="rc" />  
            <property name="viewClass"  
                value="org.springframework.web.servlet.view.JstlView" />  
            <property name="prefix" value="/" />  
            <property name="suffix" value=".jsp" />  
        </bean>  
         
    </beans>  

我们使用Spring的org.springframework.jms.listener.DefaultMessageListenerContainer来收集消息,通过设置一个消息监听器,具体实现类为org.shirdrn.spring.jms.integration.ReceiveMessageListener,代码如下所示:

    package org.shirdrn.spring.jms.integration;  
      
    import javax.jms.JMSException;  
    import javax.jms.Message;  
    import javax.jms.MessageListener;  
    import javax.jms.TextMessage;  
      
    import org.apache.log4j.Logger;  
      
    public class ReceiveMessageListener implements MessageListener {  
      
        private static final Logger LOG = Logger.getLogger(ReceiveMessageListener.class);  
         
        public void onMessage(Message message) {  
            if (message instanceof TextMessage) {  
                TextMessage text = (TextMessage) message;  
                try {  
                    LOG.info("Received message:" + text.getText());  
                } catch (JMSException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
      
    }  

上面,对发送的消息进行监听,并接收处理,我们只是简单地打印出一条日志内容。

对于listenerContainer,还需要注入连接工厂connectionFactory和消息目的destination这两个属性:connectionFactory我们使用ActiveMQ的org.apache.activemq.ActiveMQConnectionFactory,并通过JNDI服务,绑定到名字java:comp/env/myJMS/ConnectionFactory上;而destination属性通过使用ActiveMQ的org.apache.activemq.command.ActiveMQQueue消息队列,也是通过JNDI服务绑定到名字java:comp/env/myJMS/MessageQueue上。所以,在Tomcat的conf/context.xml中的<Context>元素里面加上如下配置:

    <Resource name="myJMS/ConnectionFactory"   
        auth="Container"     
        type="org.apache.activemq.ActiveMQConnectionFactory"   
        description="JMS Connection Factory"  
        factory="org.apache.activemq.jndi.JNDIReferenceFactory"   
        brokerURL="vm://shirdrnUrl"   
        brokerName="MyActiveMQBroker"/>  
      
    <Resource name="myJMS/MessageQueue"   
        auth="Container"   
        type="org.apache.activemq.command.ActiveMQQueue"  
        description="My Message Queue"  
        factory="org.apache.activemq.jndi.JNDIReferenceFactory"   
        physicalName="MyMessageQueue"/>  

我们通过使用JmsTemplate来实现消息的发送,所以实现的发送类要将JmsTemplate注入进去,实现代码如下所示:

    package org.shirdrn.spring.jms.integration;  
      
    import javax.jms.JMSException;  
    import javax.jms.Message;  
    import javax.jms.Session;  
    import javax.jms.TextMessage;  
      
    import org.apache.log4j.Logger;  
    import org.springframework.jms.core.JmsTemplate;  
    import org.springframework.jms.core.MessageCreator;  
      
    public class MessageSender {  
         
        private static final Logger LOG = Logger.getLogger(MessageSender.class);  
        private JmsTemplate jmsTemplate;  
      
        public void setJmsTemplate(JmsTemplate jmsTemplate) {  
            this.jmsTemplate = jmsTemplate;  
        }  
         
        public void sendMessage(final String message) {  
            LOG.info("Send message: " + message);  
            jmsTemplate.send(new MessageCreator() {  
      
                public Message createMessage(Session session) throws JMSException {  
                    TextMessage textMessage = session.createTextMessage(message);  
                    return textMessage;  
                }  
                  
            });  
        }  
      
    }  

上面基于Spring的MessageCreator来创建消息,通过调用JmsTemplate的send方法发送出去。

对于Web,我们使用了Spring MVC,通过实现一个控制器org.shirdrn.spring.jms.integration.SendMessageController来控制页面消息的发送及其视图的派发。我们实现的SendMessageController类继承自MultiActionController,可以在一个控制器中实现多个Action,代码实现如下所示:

    package org.shirdrn.spring.jms.integration;  
      
    import java.util.HashMap;  
    import java.util.Map;  
      
    import javax.servlet.http.HttpServletRequest;  
    import javax.servlet.http.HttpServletResponse;  
      
    import org.springframework.web.servlet.ModelAndView;  
    import org.springframework.web.servlet.mvc.multiaction.MultiActionController;  
      
    public class SendMessageController extends MultiActionController {  
      
        private String successView;  
        private MessageSender messageSender;  
      
        public ModelAndView sendMessage(HttpServletRequest request,  
                HttpServletResponse response) throws Exception {  
              
            Map<String, Object> retMap = new HashMap<String, Object>();  
            String message = request.getParameter("message");  
            messageSender.sendMessage(message);  
              
            return new ModelAndView(successView, retMap);  
        }  
      
        public String getSuccessView() {  
            return successView;  
        }  
      
        public void setSuccessView(String successView) {  
            this.successView = successView;  
        }  
      
        public MessageSender getMessageSender() {  
            return messageSender;  
        }  
      
        public void setMessageSender(MessageSender messageSender) {  
            this.messageSender = messageSender;  
        }  
      
    }  

上面调用模型层(Model)的MessageSender来实现发送消息的处理逻辑,如果发送成功,视图派发到successView指定的页面。可以看到,最前面我们给出的Spring配置内容分为三组,最后一组是对控制器的配置:

viewResolver                     视图解析器配置,可以将控制器中指定前缀(/)解析为后缀是.jsp的页面,例如/success解析为/sucess.jsp

urlMapping                         请求URL与控制器的映射,例如对于满足/sendMessage.do模式的请求,都会被指派给sendMessageController去处理

sendMessageController      控制器实现类,里面的方法名称可以自定义,但要在org.springframework.web.servlet.handler.SimpleUrlHandlerMapping中的mappings属性中配置映射

然后,我们需要一个web部署描述文件,web.xml文件配置内容,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>  
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
      
        <context-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>  
                classpath:org/shirdrn/spring/jms/integration/applicationContext.xml  
            </param-value>  
        </context-param>  
        <listener>  
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
        </listener>  
      
        <servlet>  
            <servlet-name>controller</servlet-name>  
            <servlet-class>  
                org.springframework.web.servlet.DispatcherServlet  
            </servlet-class>  
            <init-param>  
                <param-name>contextConfigLocation</param-name>  
                <param-value>  
                    classpath:org/shirdrn/spring/jms/integration/applicationContext.xml  
                </param-value>  
            </init-param>  
            <load-on-startup>1</load-on-startup>  
        </servlet>  
      
        <servlet-mapping>  
            <servlet-name>controller</servlet-name>  
            <url-pattern>*.do</url-pattern>  
        </servlet-mapping>  
        
         
        <welcome-file-list>  
            <welcome-file>index.jsp</welcome-file>  
        </welcome-file-list>  
    </web-app>  

另外,我们还要实现一个页面,提供输入发送消息的表单,提交后交给后台处理,成功发送后跳转到一个成功页面。表单输入页面为index.jsp,如下所示:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
    <%  
        String path = request.getContextPath();  
        String basePath = request.getScheme() + "://"  
                + request.getServerName() + ":" + request.getServerPort()  
                + path + "/";  
    %>  
      
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    <html>  
        <head>  
            <base href=../../"<%=basePath%>">  
      
            <title>My JSP 'index.jsp' starting page</title>  
            <meta http-equiv="pragma" content="no-cache">  
            <meta http-equiv="cache-control" content="no-cache">  
            <meta http-equiv="expires" content="0">  
            <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
            <meta http-equiv="description" content="This is my page">  
            <!--  
        <link rel="stylesheet" type="text/css" href=../../"styles.css" mce_href=../../"styles.css">  
        -->  
        </head>  
      
        <body>  
            <div align="center" style="width: 500px; height: 300px; border:2px; borderColor:black">  
                <form action="sendMessage.do" method="post">  
                    <table align="center">  
                        <tr>  
                            <th colspan="2">  
                                消息发送控制台  
                            </th>  
                        </tr>  
                        <tr>  
                            <td>  
                                消息内容:  
                            </td>  
                            <td>  
                                <input type="text" name="message">  
                            </td>  
                        </tr>  
                        <tr>  
                            <td align="center" colspan="2">  
                                <input type="reset" value="清除">  
                                      
                                <input type="submit" value="发送">  
                            </td>  
                        </tr>  
                    </table>  
                </form>  
            </div>  
        </body>  
    </html>  

成功页面为success.jsp,就是给一个成功的提示信息,如下所示:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  
    <%  
        String path = request.getContextPath();  
        String basePath = request.getScheme() + "://"  
                + request.getServerName() + ":" + request.getServerPort()  
                + path + "/";  
    %>  
      
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    <html>  
        <head>  
            <base href=../../"<%=basePath%>">  
      
            <title>My JSP 'index.jsp' starting page</title>  
            <meta http-equiv="pragma" content="no-cache">  
            <meta http-equiv="cache-control" content="no-cache">  
            <meta http-equiv="expires" content="0">  
            <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
            <meta http-equiv="description" content="This is my page">  
            <!--  
        <link rel="stylesheet" type="text/css" href=../../"styles.css" mce_href=../../"styles.css">  
        -->  
        </head>  
      
        <body>  
            <div align="center" style="width: 500px; height: 300px; border:2px; borderColor:black">  
                <form action="sendMessage.do" method="post">  
                    <table align="center">  
                        <tr>  
                            <th colspan="2">  
                                消息发送报告  
                            </th>  
                        </tr>  
                        <tr>  
                            <td colspan="2">  
                                状态:发送成功  
                            </td>  
                        </tr>  
                        <tr>  
                            <td align="center" colspan="2">  
                                <a href=../../"index.jsp" mce_href=../../"index.jsp">返回</a>  
                            </td>  
                        </tr>  
                    </table>  
                </form>  
            </div>  
        </body>  
    </html>  

至此,我们可以将实现的简单web工程发布到Tomcat容器,然后启动Tomcat服务器,通过页面可以发送消息,并通过日志查看,实际消息发送和接收的情况。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表