続けて@PathParamを試してみる。
APIによると
ServerEndpointに{パラメータ}で指定した値とバインドしてくれるらしい。
変数として使える型はStringかプリミティブOrそのボクシング型とのこと。
ただし、パラメータがデコードできなかったらエラーハンドラーを呼び出すらしい。
Java (zip:paramBindTest)
import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/hello/{hoge}/{fuga}") public class HelloWorld { static Set<Session> sessions = Collections .synchronizedSet(new HashSet<Session>()); @OnMessage public void onMessage(String message, @PathParam("hoge") Integer hoge,@PathParam("fuga") String fuga) { System.out.println("message[" + message + "]"); System.out.println("hoge[" + hoge + "]"); System.out.println("fuga[" + fuga + "]"); for (Session s : sessions) { s.getAsyncRemote().sendText(message); } }
JS
$(document).ready(function(){ var host="ws://localhost:8080/first/hello/12/ああ"; socket = new WebSocket(host); socket.onmessage = function(message){ $('#log').append(message.data + "<br/>"); }
結果
情報: 開始します:8ca15fe1-a79d-420e-afc6-3c5ab18a75ec 情報: message[あsdf] 情報: hoge[12] <- ボクシング型にバインドされている 情報: fuga[ああ] <- 日本語も素直にバインドされる模様
日本語もそのままうまくバインドされた。
ためしにIntegerの部分を少数にしたらNumberFormatExceptionをチェーンしたDecodeExceptionが発生。このケースは切り分け難しくない。
情報: エラーです:9366a9f2-2b24-4be3-8897-40427563d56e 重大: javax.websocket.DecodeException: Decoding failed at org.glassfish.tyrus.core.PrimitiveDecoders$IntegerDecoder.decode(PrimitiveDecoders.java:165) at org.glassfish.tyrus.core.PrimitiveDecoders$IntegerDecoder.decode(PrimitiveDecoders.java:157) at org.glassfish.tyrus.core.AnnotatedEndpoint$2.value(AnnotatedEndpoint.java:362) at org.glassfish.tyrus.core.AnnotatedEndpoint.callMethod(AnnotatedEndpoint.java:428) at org.glassfish.tyrus.core.AnnotatedEndpoint.access$100(AnnotatedEndpoint.java:83) at org.glassfish.tyrus.core.AnnotatedEndpoint$WholeHandler$1.onMessage(AnnotatedEndpoint.java:518) at org.glassfish.tyrus.core.SessionImpl.notifyMessageHandlers(SessionImpl.java:389) at org.glassfish.tyrus.core.EndpointWrapper.onMessage(EndpointWrapper.java:495) at org.glassfish.tyrus.server.TyrusEndpoint.onMessage(TyrusEndpoint.java:174) at org.glassfish.tyrus.websockets.DefaultWebSocket.onMessage(DefaultWebSocket.java:156) at org.glassfish.tyrus.websockets.frametypes.TextFrameType.respond(TextFrameType.java:66) at org.glassfish.tyrus.websockets.DataFrame.respond(DataFrame.java:102) at org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler.onDataAvailable(TyrusHttpUpgradeHandler.java:113) at org.apache.catalina.connector.InputBuffer$ReadHandlerImpl.processDataAvailable(InputBuffer.java:488) at org.apache.catalina.connector.InputBuffer$ReadHandlerImpl.onDataAvailable(InputBuffer.java:453) at org.glassfish.grizzly.http.io.InputBuffer.append(InputBuffer.java:855) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:222) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544) at java.lang.Thread.run(Thread.java:724) Caused by: java.lang.NumberFormatException: For input string: "1.2" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:492) at java.lang.Integer.valueOf(Integer.java:582) at org.glassfish.tyrus.core.PrimitiveDecoders$IntegerDecoder.decode(PrimitiveDecoders.java:163) ... 30 more
nullとした場合も素直にエラー
var host="ws://localhost:8080/first/hello/null/ああ"; -> Caused by: java.lang.NumberFormatException: For input string: "null"
空文字だと、予想外に素直なエラー
var host="ws://localhost:8080/first/hello//ああ"; -> Caused by: java.lang.NumberFormatException: For input string: ""
最後の文字列が空文字だと空文字としてバインドされる。
var host="ws://localhost:8080/first/hello/12/"; -> 情報: 開始します:75b4bc74-30e9-4a69-8af3-07ed67e6a296 情報: message[あ] 情報: hoge[12] 情報: fuga[]
/{空文字}/{数字}の順でも動いた。(//となるので環境次第では不具合が出る??)
@ServerEndpoint("/hello/{fuga}/{hoge}")と最初を文字列にする -> var host="ws://localhost:8080/first/hello//12"; -> 情報: 開始します:028c5db1-a60f-4d82-970f-8933058b2bfb 情報: message[あああ] 情報: hoge[12] 情報: fuga[]
{変数名}と@PathParamで誤記をするとバインドされない(null)。
@ServerEndpoint("/hello/{fuga}/{hoge}") -> public void onMessage(String message, @PathParam("hoge") Integer hoge, @PathParam("fuga2") String fuga) -> 情報: 開始します:49d01de4-4a6b-4b81-8c71-d6d48d9f0600 情報: message[あ] 情報: hoge[12] 情報: fuga[null]
URLパラーンの違いによっては呼び出されない。
一つ前のnullがバインドされる事象はバインド対象が不整合でも動いていたけど、そっちが中途半端に動いているだけで、呼び出されないのが正しいのかな??
@ServerEndpoint("/hello/{hoge}") <-fuga2はない -> public void onMessage(String message, @PathParam("hoge") Integer hoge,] @PathParam("fuga2") String fuga) { -> 23:27:25.244[23ms][total 23ms] Status: 404[Not Found] GET http://localhost:8080/first/hello/12/nasi Load Flags[LOAD_BYPASS_CACHE LOAD_BACKGROUND INHIBIT_CACHING ] Content Size[-1] Mime Type[application/x-unknown-content-type] Request Headers: Host[localhost:8080] User-Agent[Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0] Accept[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8] Accept-Language[ja,en-us;q=0.7,en;q=0.3] Accept-Encoding[gzip, deflate] Sec-WebSocket-Version[13] Origin[http://localhost:8080] Sec-WebSocket-Key[gq8u2S2nXT2xpIagf7qPaQ==] Cookie[JSESSIONID=e1e94c1a637e58c7ccaa61c6f17e] Connection[keep-alive, Upgrade] Pragma[no-cache] Cache-Control[no-cache] Upgrade[websocket] Response Headers: X-Powered-By[Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.0 Java/Oracle Corporation/1.7)] Server[GlassFish Server Open Source Edition 4.0] Set-Cookie[JSESSIONID=e2121d0c30e627004af713703b3d; Path=/first; HttpOnly]