一、ServerEndpoint注解作用
在Java EE 7规范中,WebSocket是一种新的协议,它允许服务器与客户端之间进行双向通信。而ServerEndpoint注解就是用来标记一个类是WebSocket服务器端点的。
简单来说,ServerEndpoint注解的作用是将一个java类标记为WebSocket服务器端点,从而使得客户端可以连接到服务器并且进行WebSocket通信。
二、ServerEndpoint注解前台无法连接
当我们使用ServerEndpoint注解标记一个java类后,我们可以通过浏览器进行WebSocket连接测试。但是一旦部署到实际环境中并开启SSL,我们就会遇到前台无法连接的问题。
这是因为在使用ServerEndpoint注解时,如果服务器需要SSL协议,那么就需要在注解中指定wss协议以及TLS协议版本。https的端口多是443,而wss的端口号通常为8443。
@ServerEndpoint(value="/websocket", configurator = WebSocketConfig.class) public class MyWebSocket { } 在web.xml中配置端口信息:javax.websocket.server.https.port 8443
三、ServerEndpoint注解中的属性
ServerEndpoint注解中有很多属性,其中最常用的是value、decoders和encoders。
value:用于指定WebSocket服务器端点的URI,它必须以"/"开头。例如,如果我们想要将MyEndpoint类标记为URI为"/myendpoint"的WebSocket服务器端点,则可以使用以下代码:
@ServerEndpoint("/myendpoint") public class MyEndpoint {}
decoders:用于指定需要在WebSocket服务器端点上使用的解码器(用于将接收到的消息解码为对象)的列表。例如,如果我们想要在MyEndpoint类上使用Base64解码器,则可以使用以下代码:
@ServerEndpoint( value="/myendpoint", decoders={Base64Decoder.class} ) public class MyEndpoint {}
encoders:用于指定需要在WebSocket服务器端点上使用的编码器(用于将发送的对象编码为消息)的列表。例如,如果我们想要在MyEndpoint类上使用 Base64编码器,则可以使用以下代码:
@ServerEndpoint( value="/myendpoint", encoders={Base64Encoder.class} ) public class MyEndpoint {}
四、@ServerEndpoint注解选取
在实际应用中,我们通常需要用到ServerEndpoint中的一些属性或者方法,下面是使用枚举类型、编码和解码器等注解。
1、使用枚举类型
在Java EE 7规范中,共引入了CompletableFuture和CompletionStage,这是Java关于并发编程的一项重大革命。同时,CompletableFuture和CompletionStage也支持WebSocket编程。
@ServerEndpoint(value = "/hello") public class HelloServer { @OnOpen public void onOpen(Session session) throws Exception { CompletableFuturefuture = CompletableFuture.supplyAsync(() -> "Hello from CompletableFuture."); future.thenAcceptAsync((message) -> { try { session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } }); } }
2、编解码器
在WebSocket通信中,我们需要将Java对象序列化为JSON字符串或者其他格式的字符串,然后才能在网络上传输。而我们可以使用编码器和解码器来自动实现Java对象到字符串的转换。
编码器将Java对象转换为字符串,而解码器则将字符串转换为Java对象。我们可以自定义编码器和解码器,也可以使用WebSocket API提供的现成的编码器和解码器。
@ServerEndpoint(value = "/greeting") public class GreetingServer { @OnMessage public void onMessage(Session session, String name) throws IOException, EncodeException { session.getBasicRemote().sendObject(new GreetingResponse("Hello, " + name + "!")); } } public class GreetingResponseEncoder implements Encoder.Text{ @Override public String encode(final GreetingResponse greetingResponse) { return new Gson().toJson(greetingResponse); } } public class GreetingResponseDecoder implements Decoder.Text { @Override public GreetingResponse decode(final String greetingResponseJson) { return new Gson().fromJson(greetingResponseJson, GreetingResponse.class); } @Override public boolean willDecode(final String s) { return true; } @Override public void init(final EndpointConfig endpointConfig) { } @Override public void destroy() { } }
3、路径参数
路径参数可以用来获取连接到服务器端点的WebSocket客户端的一些信息,例如连接到服务器端点的IP地址、端口号等。我们可以通过@PathParam注解将这些信息注入到我们的WebSocket服务器端点类中。
@ServerEndpoint(value = "/user/{id}") public class UserServerEndpoint { @OnOpen public void onOpen(Session session, @PathParam("id") long id) { System.out.println("User " + id + " connected to the server."); } }
五、总结
本文对ServerEndpoint注解的作用、前台无法连接问题、常见属性以及@ServerEndpoint注解相关应用场景进行了详细阐述。希望对读者对WebScoket的应用有所帮助。