Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making path parameters optional in WebSocket endpoints in Java EE

Given a WebSocket endpoint as follows.

@ServerEndpoint(value = "/Push/CartPush/{token}")
public final class CartPush {
    // ...
}

The endpoint is able to accept a path parameter {token}. The path parameter is however, optional which is determined dynamically at run-time in Java Script. Skipping this parameter in JavaScript like the following results in 404.

var ws = new WebSocket("wss://localhost:8443/ContextPath/Push/CartPush");

WebSocket connection to 'wss://localhost:8443/ContextPath/Push/CartPush' failed: Error during WebSocket handshake: Unexpected response code: 404

It makes the token value compulsory as follows.

var token = "token value";
var ws = new WebSocket("wss://localhost:8443/ContextPath/Push/CartPush" + "/" + token);

In order to exclude all unneeded HTTP methods except GET and POST, I use the following restrictions or constraints along with Servlet security constraints using appropriate URL patterns and role mappings in web.xml.

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Disable unneeded HTTP methods by 403</web-resource-name>

        <url-pattern>/Public/*</url-pattern>
        <url-pattern>/Push/*</url-pattern>
        <url-pattern>/javax.faces.resource/*</url-pattern>

        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
</security-constraint>

<deny-uncovered-http-methods/> <!-- Requires Servlet 3.1 -->

How to make the given path parameter optional?

The server in use is WildFly 10.0.0 final / Java EE 7.

like image 365
Tiny Avatar asked Dec 24 '22 08:12

Tiny


1 Answers

Unfortunately, WS URI template is documented to follow [RFC 6570 Level 1] 2 templates. So a Level 3 template like /Push/CartPush{/token} won't work out.

Your best bet is always suffixing it with / and let the token be an empty string.

var token = "";
var ws = new WebSocket("wss://localhost:8443/ContextPath/Push/CartPush/" + token);

It might be worth an enhancement request at WS spec guys.

Given that the parameter is fully defined in the client, an alternative is to supply it as a request parameter. Naturally, request parameters represent client-defined parameters.

var ws = new WebSocket("wss://localhost:8443/ContextPath/Push/CartPush?token=" + token);
String token = session.getRequestParameterMap().get("token").get(0);
like image 171
BalusC Avatar answered Jan 06 '23 03:01

BalusC