简体   繁体   中英

Asynchronous behavior in Java Servlet?

I am trying to design a Java Servlet for the first time. This is my final target behavior.

  1. Servlet receives a request.
  2. Servlet makes a HTTP Request to another server (Lets call it MServer).
  3. MServer can asynchronously send replies to my Servlets request within the next 20-25 mins.
  4. I want to send this data back to the user (who made the request to the servlet in step 1) as soon as the Servlet receives this data.

Any idea how I might do this?

As of now I have just made a "Hello World" Java Servlet. Also code to communicate with MServer is ready. But I dont know how can I achieve this asynchronous behavior.

Any help would be greatly appreciated.

Here is a sample hope it helps. It assumes that you have a browser as a client and implements jQuery Ajax call. It checks every 5 seconds if your long running call from Mserver is done and data is available for client to use. I hope it helps you :)

Your servlet code:

public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String data = Mserver.getInstance().getData();

        response.setContentType("text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        PrintWriter out = response.getWriter();
        out.println(data);
    }
}

Sample Mserver code:

public class Mserver {
    private String data;
    private static final Mserver mserver = new Mserver();

    public static Mserver getInstance() {
        return mserver;
    }

    private Mserver() {
        new Thread() {
            @Override
            public void run() {
                computeData();
            }
        }.start();
    }

    // Computing data by making multiple server calls etc..
    private void computeData() {
        try {
            System.out.println("Waiting for 20 seconds simulating long running call");
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        data = "Computed Data is ready now.";
    }

    public String getData() {
        return data;
    }
}

Html page using jQuery Ajax calls:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="js/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
    $(document).ready(function() {
        setInterval(function() {
            $.ajax({
                type:"get",
                url: "checkDataFromMserver",
                async: false,
                success: function (data) {
                    $("#response").html(data);
                }
            });
        }, 5000);
    });
</script>
</head>
<body>
    Getting data using jQuery Ajax
    <div id="response"></div>
</body>
</html>

I tested it and it works. The client keeps polling every 5 seconds to check if data is ready. And after 20 seconds it gets it's data from Mserver.

Hope you find it useful!

I think you should use an asynchronous servlet . I assume there is an MServer facade that looks like this:

interface MServer {
    void getStuff(Observer observer);
}

interface Observer {
    void onNewStuff(String stuff);
    void onThatWasAllStuff();
}

class MServerSingleton {
    MServer getInstance() {
        // Code that returns an MServer.
    }
}

Then you can implement your servlet something like this:

public class TheServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, final HttpServletResponse resp) {
        resp.setContentType("text/plain");
        final AsyncContext context = req.startAsync();
        MServerSingleton.getInstance().getStuff(new Observer() {
            void onNewStuff(String stuff) {
                try {
                    resp.getWriter().write(stuff + "\n\n");
                    resp.getWriter().flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            void onThatWasAllStuff() {
                context.complete();
            }
        });
    }
}

You will likely need to adjust timeouts for this to work.

You might want to consider using Server Sent Events .

You will probably have to implement a continuous check on the client's side and a queue on the server side. In other words the client will be contacting the servlet every 1-2 minutes to check for new messages addressed to him. The servlet should also have a method to get the data asynchronously and then store the recieved data in the queue. Implementing such queue can be done in many ways, for example by storing the responses from MServer in a database table.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM