Java EE 7 SDK |
This sample application demonstrates how to use the HTTP Protocol Upgrade API from the Servlet specification.
HTTP/1.1 allows the client to specify additional communication protocols that it supports
and would like to use. The Servlet specification includes support for the HTTP protocol upgrade
mechanism. The client (ClientTest
) initiates the upgrade request. The server
(ServerTest
) receives the upgrade request and invokes the
HttpServletRequest.upgrade()
method, which instantiates the
HttpUpgradeHandler
implementation (ProtocolUpgradeHandler
).
The HttpUpgradeHandler.init()
method is invoked after exiting the
ProcessRequest()
method of the servlet.
In this sample, the client sends the request to the server. The server accepts the request,
sends back the response, and then invokes the HttpUpgradeHandler.init()
method
and continues the communication using a dummy protocol. The client shows the request and response
headers during the handshake process.
Client
In ClientTest.java
, the client initiates the HTTP upgrade request.
@WebServlet(name = "ClientTest", urlPatterns = {"/"}) public class ClientTest extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... String reqStr = "POST " + contextRoot + "/ServerTest HTTP/1.1" + CRLF; reqStr += "User-Agent: Java/1.7" + CRLF; reqStr += "Host: " + host + ":" + port + CRLF; reqStr += "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2" + CRLF; reqStr += "Upgrade: Dummy Protocol" + CRLF; reqStr += "Connection: Upgrade" + CRLF; reqStr += "Content-type: application/x-www-form-urlencoded" + CRLF; reqStr += "Transfer-Encoding: chunked" + CRLF; reqStr += CRLF; reqStr += Data + CRLF; // Create socket connection to ServerTest s = new Socket(host, port); input = s.getInputStream(); output = s.getOutputStream(); // Send request header with data output.write(reqStr.getBytes()); output.flush(); } }
The header Upgrade: Dummy Protocol
is an HTTP/1.1 header field set to
Dummy Protocol
in this sample. The server decides whether to accept the protocol
upgrade request.
Server
ServerTest.java
checks the Upgrade
field in the request header.
When it accepts the upgrade requests, the server instantiates ProtocolUpgradeHandler
,
which is the implementation of HttpUpgradeHandler
. If the server does not support
the Upgrade
protocol specified by the client, it sends a response with 404 Status.
@WebServlet(name="ServerTest", urlPatterns={"/ServerTest"}) public class ServerTest extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Checking request header if ("Dummy Protocol".equals(request.getHeader("Upgrade"))) { System.out.println("Accept to upgrade"); response.setStatus(101); response.setHeader("X-Powered-By", "Servlet/3.1 " + "(GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)"); response.setHeader("Upgrade", "Dummy Protocol"); response.setHeader("Connection", "Upgrade"); response.flushBuffer(); // Call the upgrade API, and invoke the upgrade handler ProtocolUpgradeHandler handler = request.upgrade(ProtocolUpgradeHandler.class); } else { response.setStatus(400); response.setHeader("X-Powered-By", "Servlet/3.1 " + "(GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)"); response.setHeader("Connection", "Refused"); response.sendError(400, "The Upgrade request sent by the client was incorrect or can not be accept by the server"); System.out.println("Upgrade field is: " + request.getHeader("Upgrade")); System.out.println("Upgrade refused"); } } ... }
ProtocolUpgradeHandler
is the implementation of HttpUpgradeHandler
,
which processes the upgrade request and switchs the comminication protocol.
The server checks the value of the Upgrade
header to determine if it supports
that protocol. Once server accepts the request, it must use the Upgrade
header
field within a 101 (Switching Protocols) response to indicate which protocol(s) are being
switched.
Implementation of HttpUpgradeHandler
ProtocolUpgradeHandler
is the implementation of HttpUpgradeHandler
.
public class ProtocolUpgradeHandler implements HttpUpgradeHandler { @Override public void init(WebConnection wc) { this.wc = wc; try { ServletOutputStream output = wc.getOutputStream(); ServletInputStream input = wc.getInputStream(); Calendar calendar = Calendar.getInstance(); DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); // Reading the data into byte array input.read(echoData); // Setting new protocol header String resStr = "Dummy Protocol/1.0 " + CRLF; resStr += "Server: Glassfish/ServerTest" + CRLF; resStr += "Content-Type: text/html" + CRLF; resStr += "Connection: Upgrade" + CRLF; resStr += "Date: " + dateFormat.format(calendar.getTime()) + CRLF; resStr += CRLF; // Appending data with new protocol resStr += new String(echoData) + CRLF; // Sending back to client ... output.write(resStr.getBytes()); output.flush(); } catch (IOException ex) { Logger.getLogger(ProtocolUpgradeHandler.class.getName()).log(Level.SEVERE, null, ex); } ... } @Override public void destroy() { ... try { wc.close(); } catch (Exception ex) { Logger.getLogger(ProtocolUpgradeHandler.class.getName()).log(Level.SEVERE, "Failed to close connection", ex); } ... } }
The init()
method sets up the new protocol headers. The new protocol is used
for subsequent comminications. This sample uses a dummy protocol. The destroy()
method is invoked when the upgrade process is done.
This sample shows the handshake process of the protocol upgrade. After the handshake process, the subsequent communications use the new protocol. This mechanism only applies to upgrading application-layer protocols upon the existing transport-layer connection. This feature is normally most useful for Java EE Platform providers.
This sample application demonstrates how to handle HTTP Protocol Upgrade requests in Java EE Servlets.
Following are the instructions for building, deploying, and running
this sample application.
app_dir
is the sample application base
directory: samples_install_dir/servlet/http-upgrade-war
.
Change directory to app_dir.
mvn
target:Use the command below to run this sample which is using Cargo framework:
app_dir>
mvn clean verify cargo:run
You can point Cargo to an already installed and running Glassfish server:
app_dir> mvn clean verify cargo:run -Dglassfish.home=$<glassfish_dir>
(e.g. ../glassfish4)
You can also build, deploy the sample application without Cargo:
app_dir> mvn install
app_dir> asadmin deploy ./target/<app_name>.war
http://<javaee.server.name>:<javaee.server.port>/http-upgrade-war
Http Upgrade Process Sending upgrade request to server...... Request header with data: POST /http-upgrade-war/ServerTest HTTP/1.1 User-Agent: Java/1.7 Host: localhost:8080 Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Upgrade: Dummy Protocol Connection: Upgrade Content-type: application/x-www-form-urlencoded Transfer-Encoding: chunked Hello World --------------------------------------- Server accept upgrade request, send back the response: Response header: HTTP/1.1 101 Web Socket Protocol Handshake X-Powered-By: Servlet/3.1 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7) Server: GlassFish Server Open Source Edition 4.0 Upgrade: Dummy Protocol Connection: Upgrade --------------------------------------- Server send back the response with new protocol and data: Response header with data: Dummy Protocol/1.0 Server: Glassfish/ServerTest Content-Type: text/html Connection: Upgrade Date: 02/13/2013 18:03:28 Hello World --------------------------------------- Connection with new protocol established
app_dir>
asadmin undeploy
<app_name>
clean
to remove the temporary directories
like /target.
app_dir> mvn
clean
Perform the following steps to build, deploy, and run the application using NetBeans IDE:
samples_install_dir/servlet/
directory, select http-upgrade-war
, and click Open Project.http-upgrade-war
and select Run to build, deploy, and run the project.If you have problems when running the application, refer the troubleshooting document.
Copyright © 1997-2013 Oracle and/or its affiliates. All rights reserved.