您的位置:

全能编程开发工程师:深入理解ServerEndpoint注解

一、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 {
        CompletableFuture future = 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的应用有所帮助。