Spring Boot嵌入式HornetQ集群不转发消息

时间:2015-04-09 10:52:43

标签: spring-boot hornetq

我尝试使用嵌入式HornetQ服务器创建两个Spring Boot应用程序的静态集群。一个应用程序/服务器将处理外部事件并生成要发送到消息队列的消息。另一个应用程序/服务器将侦听消息队列并处理传入消息。由于两个应用程序之间的链接不可靠,因此每个应用程序仅使用本地/ inVM客户端在其各自的服务器上生成/使用消息,并依赖于群集功能将消息转发到群集中其他服务器上的队列。 / p>

我使用HornetQConfigurationCustomizer来自定义嵌入式HornetQ服务器,因为默认情况下它只附带InVMConnectorFactory

我已经创建了几个示例应用程序,用于说明此设置,在整个示例中," ServerSend",指的是将生成消息的服务器,以及" ServerReceive"指的是将消费消息的服务器。

两个应用程序的pom.xml包含:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-hornetq</artifactId>
</dependency>
<dependency>
    <groupId>org.hornetq</groupId>
    <artifactId>hornetq-jms-server</artifactId>
</dependency>

DemoHornetqServerSendApplication:

@SpringBootApplication
@EnableScheduling
public class DemoHornetqServerSendApplication {
    @Autowired
    private JmsTemplate jmsTemplate;
    private @Value("${spring.hornetq.embedded.queues}") String testQueue;

    public static void main(String[] args) {
        SpringApplication.run(DemoHornetqServerSendApplication.class, args);
    }

    @Scheduled(fixedRate = 5000)
    private void sendMessage() {
        String message = "Timestamp from Server: " + System.currentTimeMillis();
        System.out.println("Sending message: " + message);
        jmsTemplate.convertAndSend(testQueue, message);
    }

    @Bean
    public HornetQConfigurationCustomizer hornetCustomizer() {
        return new HornetQConfigurationCustomizer() {

            @Override
            public void customize(Configuration configuration) {
                String serverSendConnectorName = "server-send-connector";
                String serverReceiveConnectorName = "server-receive-connector";

                Map<String, TransportConfiguration> connectorConf = configuration.getConnectorConfigurations();

                Map<String, Object> params = new HashMap<String, Object>();
                params.put(TransportConstants.HOST_PROP_NAME, "localhost");
                params.put(TransportConstants.PORT_PROP_NAME, "5445");
                TransportConfiguration tc = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
                connectorConf.put(serverSendConnectorName, tc);

                Set<TransportConfiguration> acceptors = configuration.getAcceptorConfigurations();
                tc = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
                acceptors.add(tc);

                params = new HashMap<String, Object>();
                params.put(TransportConstants.HOST_PROP_NAME, "localhost");
                params.put(TransportConstants.PORT_PROP_NAME, "5446");
                tc = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
                connectorConf.put(serverReceiveConnectorName, tc);

                List<String> staticConnectors = new ArrayList<String>();
                staticConnectors.add(serverReceiveConnectorName);
                ClusterConnectionConfiguration conf = new ClusterConnectionConfiguration(
                        "my-cluster", // name
                        "jms", // address
                        serverSendConnectorName, // connector name
                        500, // retry interval
                        true, // duplicate detection
                        true, // forward when no consumers
                        1, // max hops
                        1000000, // confirmation window size
                        staticConnectors, 
                        true // allow direct connections only
                        );
                configuration.getClusterConfigurations().add(conf);

                AddressSettings setting = new AddressSettings();
                setting.setRedistributionDelay(0);
                configuration.getAddressesSettings().put("#", setting);
            }
        };
    }
}

application.properties(ServerSend):

spring.hornetq.mode=embedded
spring.hornetq.embedded.enabled=true
spring.hornetq.embedded.queues=jms.testqueue
spring.hornetq.embedded.cluster-password=password

DemoHornetqServerReceiveApplication:

@SpringBootApplication
@EnableJms
public class DemoHornetqServerReceiveApplication {
    @Autowired
    private JmsTemplate jmsTemplate;
    private @Value("${spring.hornetq.embedded.queues}") String testQueue;

    public static void main(String[] args) {
        SpringApplication.run(DemoHornetqServerReceiveApplication.class, args);
    }

    @JmsListener(destination="${spring.hornetq.embedded.queues}")
    public void receiveMessage(String message) {
        System.out.println("Received message: " + message);
    }

    @Bean
    public HornetQConfigurationCustomizer hornetCustomizer() {
        return new HornetQConfigurationCustomizer() {

            @Override
            public void customize(Configuration configuration) {
                String serverSendConnectorName = "server-send-connector";
                String serverReceiveConnectorName = "server-receive-connector";

                Map<String, TransportConfiguration> connectorConf = configuration.getConnectorConfigurations();

                Map<String, Object> params = new HashMap<String, Object>();
                params.put(TransportConstants.HOST_PROP_NAME, "localhost");
                params.put(TransportConstants.PORT_PROP_NAME, "5446");
                TransportConfiguration tc = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
                connectorConf.put(serverReceiveConnectorName, tc);

                Set<TransportConfiguration> acceptors = configuration.getAcceptorConfigurations();
                tc = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
                acceptors.add(tc);

                params = new HashMap<String, Object>();
                params.put(TransportConstants.HOST_PROP_NAME, "localhost");
                params.put(TransportConstants.PORT_PROP_NAME, "5445");
                tc = new TransportConfiguration(NettyConnectorFactory.class.getName(), params);
                connectorConf.put(serverSendConnectorName, tc);

                List<String> staticConnectors = new ArrayList<String>();
                staticConnectors.add(serverSendConnectorName);
                ClusterConnectionConfiguration conf = new ClusterConnectionConfiguration(
                        "my-cluster", // name
                        "jms", // address
                        serverReceiveConnectorName, // connector name
                        500, // retry interval
                        true, // duplicate detection
                        true, // forward when no consumers
                        1, // max hops
                        1000000, // confirmation window size
                        staticConnectors, 
                        true // allow direct connections only
                        );
                configuration.getClusterConfigurations().add(conf);

                AddressSettings setting = new AddressSettings();
                setting.setRedistributionDelay(0);
                configuration.getAddressesSettings().put("#", setting);
            }
        };
    }
}

application.properties(ServerReceive):

spring.hornetq.mode=embedded
spring.hornetq.embedded.enabled=true
spring.hornetq.embedded.queues=jms.testqueue
spring.hornetq.embedded.cluster-password=password

启动两个应用程序后,日志输出显示:

ServerSend:

  

2015-04-09 11:11:58.471 INFO 7536 --- [main] org.hornetq.core.server:HQ221000:实时服务器以配置HornetQ配置开始(clustered = true,backup = false,sharedStore =真,journalDirectory = C:\用户**** \应用程序数据\本地\ TEMP \ HornetQ的数据/杂志,bindingsDirectory =数据/绑定,largeMes​​sagesDirectory =数据/ largemessages,pagingDirectory =数据/寻呼)
  2015-04-09 11:11:58.501 INFO 7536 --- [main] org.hornetq.core.server:HQ221045:libaio不可用,将配置切换到NIO
  2015-04-09 11:11:58.595 INFO 7536 --- [main] org.hornetq.core.server:HQ221043:添加协议支持CORE
  2015-04-09 11:11:58.720 INFO 7536 --- [main] org.hornetq.core.server:HQ221003:尝试部署队列jms.queue.jms.testqueue
  2015-04-09 11:11:59.568 INFO 7536 --- [main] org.hornetq.core.server:HQ221020:已启动Netty Acceptor版本4.0.13.Final localhost:5445
  2015-04-09 11:11:59.593 INFO 7536 --- [main] org.hornetq.core.server:HQ221007:服务器现已生效
  2015-04-09 11:11:59.593 INFO 7536 --- [主要] org.hornetq.core.server:HQ221001:HornetQ Server版本2.4.5.FINAL(Wild Hornet,124)[c139929d-d90f-11e4-ba2e -e58abf5d6944]

ServerReceive:

  

2015-04-09 11:12:04.401 INFO 4528 --- [main] org.hornetq.core.server:HQ221000:实时服务器从配置HornetQ配置开始(clustered = true,backup = false,sharedStore =真,journalDirectory = C:\用户**** \应用程序数据\本地\ TEMP \ HornetQ的数据/杂志,bindingsDirectory =数据/绑定,largeMes​​sagesDirectory =数据/ largemessages,pagingDirectory =数据/寻呼)
  2015-04-09 11:12:04.410 INFO 4528 --- [main] org.hornetq.core.server:HQ221045:libaio不可用,将配置切换到NIO
  2015-04-09 11:12:04.520 INFO 4528 --- [main] org.hornetq.core.server:HQ221043:添加协议支持CORE
  2015-04-09 11:12:04.629 INFO 4528 --- [main] org.hornetq.core.server:HQ221003:尝试部署队列jms.queue.jms.testqueue
  2015-04-09 11:12:05.545 INFO 4528 --- [main] org.hornetq.core.server:HQ221020:已启动Netty Acceptor版本4.0.13.Final localhost:5446
  2015-04-09 11:12:05.578 INFO 4528 --- [主要] org.hornetq.core.server:HQ221007:服务器现已上线   2015-04-09 11:12:05.578 INFO 4528 --- [主要] org.hornetq.core.server:HQ221001:HornetQ Server版本2.4.5.FINAL(Wild Hornet,124)[c139929d-d90f-11e4-ba2e -e58abf5d6944]

我在两个输出中都看到clustered=true,如果我从false删除了群集配置,则会显示HornetQConfigurationCustomizer,因此它必须有效。

现在,ServerSend在控制台输出中显示了这一点:

  

发送消息:来自服务器的时间戳:1428574324910
  发送消息:服务器的时间戳:1428574329899
  发送消息:服务器的时间戳:1428574334904

但是,ServerReceive没有显示任何内容。

似乎消息不会从ServerSend转发到ServerReceive。

我做了一些测试,通过创建另外两个Spring Boot应用程序(ClientSend和ClientReceive),这些应用程序嵌入了HornetQ服务器,而是连接到&#34; native&#34;服务器

两个客户端应用程序的pom.xml包含:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-hornetq</artifactId>
</dependency>

DemoHornetqClientSendApplication:

@SpringBootApplication
@EnableScheduling
public class DemoHornetqClientSendApplication {
    @Autowired
    private JmsTemplate jmsTemplate;
    private @Value("${queue}") String testQueue;

    public static void main(String[] args) {
        SpringApplication.run(DemoHornetqClientSendApplication.class, args);
    }

    @Scheduled(fixedRate = 5000)
    private void sendMessage() {
        String message = "Timestamp from Client: " + System.currentTimeMillis();
        System.out.println("Sending message: " + message);
        jmsTemplate.convertAndSend(testQueue, message);
    }
}

application.properties(ClientSend):

spring.hornetq.mode=native
spring.hornetq.host=localhost
spring.hornetq.port=5446

queue=jms.testqueue

DemoHornetqClientReceiveApplication:

@SpringBootApplication
@EnableJms
public class DemoHornetqClientReceiveApplication {
    @Autowired
    private JmsTemplate jmsTemplate;
    private @Value("${queue}") String testQueue;

    public static void main(String[] args) {
        SpringApplication.run(DemoHornetqClientReceiveApplication.class, args);
    }

    @JmsListener(destination="${queue}")
    public void receiveMessage(String message) {
        System.out.println("Received message: " + message);
    }
}

application.properties(ClientReceive):

spring.hornetq.mode=native
spring.hornetq.host=localhost
spring.hornetq.port=5445

queue=jms.testqueue

现在控制台显示:

ServerReveive:

  

收到消息:来自客户的时间戳:1428574966630
  收到消息:客户时间戳:1428574971600
  收到消息:来自客户的时间戳:1428574976595

ClientReceive:

  

收到消息:服务器的时间戳:1428574969436
  收到消息:服务器的时间戳:1428574974438
  收到消息:服务器的时间戳:1428574979446

如果我让ServerSend运行一段时间,然后启动ClientReceive,它还会收到排队到那时的所有消息,这样就表明这些消息不会在某个地方消失,或者从其他地方消失

为了完整起见,我还将ClientSend指向ServerSend和ClientReceive指向ServerReceive,以查看群集和InVM客户端是否存在某些问题,但同样没有任何输出表明ClientReceive中收到任何消息或ServerReceive。

因此,向每个嵌入式代理发送消息到直接连接的外部客户端的消息都可以正常工作,但集群中的代理之间不会转发任何消息。

所以,在这一切之后,最重要的问题是,在集群内没有转发消息的设置有什么问题?

3 个答案:

答案 0 :(得分:0)

过滤器

package it.unitn.disi.webdev.claudiovigliarolo;

import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebFilter(filterName = "AuthenticationFilter", urlPatterns = { "/*" })
public class AuthenticationFilter implements Filter {
    private ServletContext context;

    public void init(FilterConfig fConfig) throws ServletException {
        this.context = fConfig.getServletContext();
        this.context.log("AuthenticationFilter initialized");
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        String uri = req.getRequestURI();
        HttpSession session = req.getSession(false);
        boolean isLoggedIn = session != null && session.getAttribute("username") != null;

        if (!isLoggedIn && !uri.endsWith("start.jsp")) {
            res.sendRedirect("start.jsp");

        } else {
            chain.doFilter(request, response);
        }
    }

    public void destroy() {
        // close any resources here
    }
}<filter-mapping><filter-name>AuthenticationFilter</filter-name><url-pattern>/*</url-pattern>
  </filter-mapping>




import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet(name = "GetItems", urlPatterns = { "/GetItems" })
public class GetItems extends HttpServlet {

    String dbURL = "jdbc:derby://localhost:1527/ExamDerbyDB";
    String user = "WEBENGINE";
    String password = "WEBENGINE";
    Connection conn = null;

    @Override
    public void init() {
        try {
            Class.forName("org.apache.derby.jdbc.ClientDriver");
            conn = DriverManager.getConnection(dbURL, user, password);
        } catch (ClassNotFoundException | SQLException ex) {
            ex.printStackTrace();

        }
    }

    @Override
    public void destroy() {
        try {
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException ex) {
            System.err.println("Database connection problem: can't close connection");

        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        StringBuilder ret = new StringBuilder();

        ArrayList<String> inserted = getAllItemsFromDB();

        String jsonResponse = getListJson(inserted);
        response.setContentType("application/json;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {

            out.println(jsonResponse);
        }
    }

    private ArrayList<String> getAllItemsFromDB() throws ServletException {
        ArrayList elements = new ArrayList();
        
        PreparedStatement stm = null;
        ResultSet result = null;
        
        try {
            String query = "SELECT USERNAME FROM USERS";
            stm = conn.prepareStatement(query);
            result = stm.executeQuery();
            while(result.next()) {
                String string = result.getString(1); 
                elements.add(string);
            }
            stm.close();
            result.close();

        } catch (SQLException ex) {
            System.err.println("Database connection problem");
        } finally {
            try {
                if(stm != null) stm.close();
                if(result != null) result.close();
            } catch (SQLException ex) {
               System.err.println("Database connection problem: can't close statement/result");
            }
        
        return elements;
    }

    public String getListJson(ArrayList<String> list) {
        if (list.size() == 0)
            return null;
        StringBuilder ret = new StringBuilder("[");
        String prefix = "";
        for (int i = 0; i < list.size(); i++) {
            StringBuilder sb = new StringBuilder();
            ret.append(prefix);
            prefix = ",";
            ret.append(sb.append("{\"message\":\"").append(list.get(i)).append("\"}").toString());
        }
        ret.append("]");
        return ret.toString();
    }
}

class.java

public class MessageList {
    protected final LinkedList<Message> list;

    public MessageList() {
        this.list = new LinkedList<>();
    }

    public void addMessage(Message m) {
        this.list.add(m);
    }

    public void deleteMessage(String message_id) {
        for (Message a : list) {
            if (a.message_id.equals(message_id)) {
                list.remove(a);
            }
        }
    }

    public Message getMessage(String message_id) {
        for (Message a : list) {
            if (a.message_id.equals(message_id)) {
                return a;
            }
        }
        return null;

    }

    public void addLike(String message_id) {
        for (Message a : list) {
            if (a.message_id.equals(message_id)) {
                a.isLiked++;
            }
        }
    }

    StringBuilder ret = new StringBuilder("[");
    String prefix = "";for(
    int i = 0;i<list.size();i++)
    {
        Message m = list.get(i);
        ret.append(prefix);
        prefix = ",";
        ret.append(m.toJson());
    }ret.append("]");

    return ret.toString();
    }

    public String getListJson()
    {
        if(list.size() == 0)
        {
            return null;
        }
        
        StringBuilder ret = new StringBuilder("[");
        String prefix = "";
        for(int i=0; i<list.size(); i++) {
            StringBuilder sb = new StringBuilder();
            ret.append(prefix);
            prefix = ",";
            ret.append(sb.append("{\"message\":\"").append(list.get(i)).append("\"}").toString());
        }
        ret.append("]");
        
        return ret.toString();
    }
}

表格

<!DOCTYPE html>
<html lang="en">
  <body>
    <script>
      function validateForm(form) {
        var username = document.getElementById("username").value;
        var password = document.getElementById("password").value;
        var error = document.getElementById("error");
        error.innerHTML = "";
        if (username === "" || password == "") {
          form.reset();
          error.innerHTML = "password / username empty";
          return false;
        }
        return true;
      }
    </script>

    <div class="container" style="width: 500px; float: left">
      <h2 class="text-center">Welcome to the App</h2>
      <form
        id="registerForm"
        method="POST"
        onsubmit="return validateForm(this)"
        action="Registration"
      >
        <div class="form-group">
          <label for="username">Username:</label>
          <input
            type="text"
            class="form-control"
            id="username"
            placeholder="Enter email"
            name="username"
          />
        </div>
        <div class="form-group">
          <label for="password">Password:</label>
          <input
            type="password"
            class="form-control"
            id="password"
            placeholder="Enter password"
            name="password"
          />
        </div>
        <div class="form-group form-check"></div>
        <button type="submit" class="btn btn-primary">Submit</button>
      </form>
      <div id="error" class="alert" role="alert"></div>
    </div>
  </body>
</html>

一般

//servelet context
ServletContext application=getServletContext();
application.setAttribute("messages", messages);



//SESSION
HttpSession session = request.getSession();
String name = (String) request.getParameter("username");
session.setAttribute("username", name);


//random id java
String uniqueID = UUID.randomUUID().toString();

//package
it.unitn.disi.webdev.claudiovigliarolo

//project name
VIGLIAROLO_C_202314

//get contextpath
    String contextPath = request.getContextPath();
        System.out.println("Context Path = " + contextPath);
        response.sendRedirect(contextPath + "/main.html");


//BOOTstrap
  <head>
    <title>Bootstrap Example</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  </head>



//redirect to other page
window.location.replace("http://stackoverflow.com");



//CONTENT type
response.setContentType("application/json;charset=UTF-8");  
response.setContentType("text/html;charset=UTF-8");






//zuccherino
    protected final LinkedList<Message> list;
    
      public MessageList() {
        this.list = new LinkedList<>();
    }



<!DOCTYPE html>
<html lang="en">
<body>
<script>
function validateForm(form) {
    var username = document.getElementById("username").value;
     var password = document.getElementById("password").value;
      var error = document.getElementById("error");
      error.innerHTML = "";
    if(username === "" || password == "") {
         form.reset();
         error.innerHTML = "password / username empty";
         return false;
    }
   return true;
}
</script>

<div class="container " style="width:500px; float: left;">
   
  <h2 class="text-center">Welcome to the App</h2>
  <form id="registerForm" method="POST" onsubmit="return validateForm(this)" action="Registration">
    <div class="form-group">
      <label for="username">Username:</label>
      <input type="text" class="form-control" id="username" placeholder="Enter email" name="username">
    </div>
    <div class="form-group">
      <label for="password">Password:</label>
      <input type="password" class="form-control" id="password" placeholder="Enter password" name="password">
    </div>
    <div class="form-group form-check">
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
  </form>
 <div id="error" class="alert" role="alert">
  
</div>
</div>
</body>
</html>


//change styles
 const val =  keywords.some(k=>item.message.includes(k));
const color = val ? "#FFFF00;" : "transparent;";
document.getElementById("data").innerHTML +=
        "<div style=' margin-top:50px;flexdirection: row; display:flex; width:500px; background:" + color + "; justify-content: row; '>" +
        item.message +
        "</div>";


//setimeout
function refresh() {
// make Ajax call here, inside the callback call:
setTimeout(refresh, 5000);
// ...
}
// initial call, or just call refresh directly
setTimeout(refresh, 5000);


//template strings
`string text`

getclaudio postclaudio


<script>
  function onSendData() {
    var title = document.getElementById("username").value;
    var description = document.getElementById("password").value;
    console.log(title, description);
    var http = new XMLHttpRequest();
    var url = "Registration";
    var params = "password=" + description + "&username=" + title;
    http.open("POST", url, true);
    //Send the proper header information along with the request
    http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    http.onreadystatechange = function () {
      //Call a function when the state changes.
      if (http.readyState == 4 && http.status == 200) {
        console.log("res", http.responseText);
      }
    };
    http.send(params);
  }
</script>
------GET---------------
  //loadData noparam
<script>

  loadData();

function loadData() {
    var xhttp = new XMLHttpRequest();
    xhttp.open("GET", "GetProducts", true);
    xhttp.responseType = "json";
    xhttp.onreadystatechange = function () {
        var done = 4,
                ok = 200;
        if (this.readyState === done && this.status === ok) {
            my_JSON_object = this.response;
            console.log("response", my_JSON_object);
            document.getElementById("data").innerHTML = "";
            my_JSON_object && my_JSON_object.forEach((item) => {
                console.log("item", item.message);
                document.getElementById("data").innerHTML +=
                        " <div class='card' style='width: 300px; margin-top:50px;'>" +
                        "<div class='card-body'>" +
                        " <h4 class='card-title'>" + item.name + "</h4>" +
                        "<p class='card-text'>" + item.description + "</p>" +
                        "  <p class='card-text'>Price: " + item.price + " $</p>" +
                        "    <a href='detail.html?name=" + item.name + "' class='card-link' >View details</a>" +
                        "   </div>    </div>";
            });
        }
    };
    xhttp.send();
}
</script>
<div id="data"></div>

 //loadData withparam
<script>
  function getData() {
  const urlParams = new URLSearchParams(window.location.search);
  const id = urlParams.get('id');
  const id2 = urlParams.get('id2');

  console.log(id)
  var url = "GetItems";
  let param1 = id;
  let param2 = id2;
  var params = "param1=" + param1 + "&param2=" + param2;
  var http = new XMLHttpRequest();
  http.open("GET", url + "?" + params, true);
  http.responseType = "json";
  http.onreadystatechange = function () {
      var done = 4,
              ok = 200;
      if (this.readyState === done && this.status === ok) {
          my_JSON_object = this.response;
          console.log("response", my_JSON_object);
          document.getElementById("data").innerHTML = "";
          my_JSON_object && my_JSON_object.forEach((item) => {
              console.log("item", item.message);
              document.getElementById("data").innerHTML +=
                      "<div style=' margin-top:50px;flexdirection: row; display:flex; width:500px; justify-content: row; '>" +
                      item.message +
                      "</div>";
          });
      }
  };
  http.send(null);
}
</script>
<div id="data"></div>







<div class="card" style="margin-top: 50px;">
  <div class="card-body">Content</div>
</div>


//render multiple parameters
onclick="showData('${item.name}', '${item.price}', '${item.punteggio}', '${item.extra}' )"

JSON servelet claudio


RETURN JSON
//create simple json response
response.setContentType("application/json;charset=UTF-8");  
StringBuilder ret = new StringBuilder();
ret.append("{\"ready\":\"").append("false").append("\"}");
try (PrintWriter out = response.getWriter()) {
    out.println(ret.toString());
}

JSON LIST CLASS
     public String toJSON() {
        StringBuilder ret = new StringBuilder("[");
        String prefix = "";
        for(int i=0; i<list.size(); i++) {
            Message m = list.get(i);
            ret.append(prefix);
            prefix = ",";
            ret.append(m.toJson());
        }
        ret.append("]");
                System.err.println("priting tojson"+ ret.toString());
        return ret.toString();
    }


JSON ITEM
    public String toJson() {
        StringBuilder ret = new StringBuilder();
        ret.append("{\"id\":\"").append(this.id).append("\",");
        ret.append("\"nome\":\"").append(this.nome).append("\",");
        ret.append("\"imgName\":\"").append(this.imgName).append("\"}");
        return ret.toString();
    }




STRING LIST
    public String wordsToJSON(ArrayList<String> list) {
        System.err.println("lunghezza" + list.size());
        if (list.size() == 0) {
            return null;
        }
        StringBuilder ret = new StringBuilder("[");
        String prefix = "";
        for (int i = 0; i < list.size(); i++) {
            StringBuilder sb = new StringBuilder();
            ret.append(prefix);
            prefix = ",";
            ret.append(sb.append("{\"message\":\"").append(list.get(i)).append("\"}").toString());
        }

        ret.append("]");
        System.err.println("jjj" + ret.toString());
        return ret.toString();
    }

    }
JSON RESPONSE OK
           ServletContext application=getServletContext();
            MappaDiCoppie mappaDiCoppie =  (MappaDiCoppie) application.getAttribute("mappaDiCoppie");
            HttpSession session= request.getSession();
            String username = (String) session.getAttribute("username");
            StringBuilder ret = new StringBuilder();
            if(mappaDiCoppie != null && username != null)
            {
                if(mappaDiCoppie.exists(username))
                    //ok 
                    ret.append("{\"ready\":\"").append("true").append("\"}");
                else  
                    //no wait
                    ret.append("{\"ready\":\"").append("false").append("\"}")
                    try (PrintWriter out = response.getWriter()) {
                    out.println(ret.toString());
                }
            }


            ```
















答案 1 :(得分:0)

样式表

 <link rel="stylesheet" href="./styles/styles.css">
  <script type="text/javascript" src="./js/script.js"></script>

矩阵 html

 const N = 9;
const container = document.getElementById("container");

function makeRows(rows, cols) {
    container.style.setProperty('--grid-rows', rows);
    container.style.setProperty('--grid-cols', cols);
    for (c = 0; c < (cols); c++) {
        for (r = 0; r < rows; r++) {
            const myid = JSON.stringify({x: r, y: c});
            let cell = document.createElement("div");
            var textnode = document.createElement("span");
            textnode.setAttribute("id", myid);
            cell.appendChild(textnode);
            cell.onclick = function (event) {
                showVal(myid, r, c);
            }
            //cell.innerText = (c + 1);
            container.appendChild(cell).className = "grid-item";
            container.appendChild(cell).style = "border-color: red";
            container.appendChild(cell).style = "border-width: 4px";

        }
        ;
    }
}

//styles

.myinput{
    width: 50px;
    margin-right: 20px;
}


#container {
  display: grid;
  grid-gap: .5em;
  grid-template-rows: repeat(var(--grid-rows), 1fr);
  grid-template-columns: repeat(var(--grid-cols), 1fr);
  width: 100px;
}

.grid-item {
  border: 1px solid #ddd;
  text-align: center;
  width: 50px;
  height: 50px;
  border-width: 2px;
  border-color: green;
  
}

网格 java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package utils;

import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author claud
 */
public class Grid {

int N;
Cell[][] matrix;

public Grid(int N) {
    this.N = N;
    this.matrix = new Cell[N][N];
}

private int getRandom() {
    Random rn = new Random();
    int range = 0 - 0 + 1;
    int randomNum = rn.nextInt(N) + 0;
    return randomNum;
}

public int getValue(int x, int y) {
    if (x < N && y < N) {
        return this.matrix[x][y].value;
    } else {
        return -2;
    }
}

public void generate() {
    System.err.println("ffffffffffffggg");

    //fai il ciclo completo
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            this.matrix[i][j] = new Cell(i, j, 0);//aggiungi bombe con random altrimenti valore 0
        }
    }
}


public void print() {
    System.err.println("printiiiiiiiiiiiing START");
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            System.err.println(this.matrix[i][j].value);
        }
    }
}
}

答案 2 :(得分:-1)

http://docs.jboss.org/hornetq/2.2.5.Final/user-manual/en/html/architecture.html#d0e595

“HornetQ核心被设计为一组简单的POJO,因此如果您的应用程序需要内部消息传递功能,但您不希望将其作为HornetQ服务器公开,您可以直接在自己的应用程序中实例化和嵌入HornetQ服务器。“

如果要嵌入它,则不会将其作为服务器公开。每个容器都有一个单独的实例。它相当于启动2个大黄蜂副本并给它们相同的队列名称。一个在第一个实例上写入该队列,另一个在第二个实例上侦听队列。

如果您想以这种方式解耦应用程序,则需要有一个充当服务器的位置。可能你想集群。这不是大黄蜂BTW特有的。你经常会发现这种模式。