Browse Source
- Renamed SseEvent to ServerSentEvent to make the name less redundant. - ServerSentEvent is now immutable, having a builder to create new instances. - Realigned the class properties to more closely match the events described in the spec, so that `reconnectTime` becomes `retry`, and `name` becomes `event`.pull/1143/merge
6 changed files with 310 additions and 254 deletions
@ -0,0 +1,226 @@
@@ -0,0 +1,226 @@
|
||||
/* |
||||
* Copyright 2002-2016 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.http.codec; |
||||
|
||||
import java.time.Duration; |
||||
import java.util.Optional; |
||||
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder; |
||||
|
||||
/** |
||||
* Representation for a Server-Sent Event for use with Spring's reactive Web |
||||
* support. {@code Flux<SseEvent>} or {@code Observable<SseEvent>} is the |
||||
* reactive equivalent to Spring MVC's {@code SseEmitter}. |
||||
* |
||||
* @param <T> the type of data that this event contains |
||||
* @author Sebastien Deleuze |
||||
* @author Arjen Poutsma |
||||
* @see ServerSentEventHttpMessageWriter |
||||
* @see <a href="https://www.w3.org/TR/eventsource/">Server-Sent Events W3C recommendation</a> |
||||
* @since 5.0 |
||||
*/ |
||||
public class ServerSentEvent<T> { |
||||
|
||||
private final String id; |
||||
|
||||
private final String event; |
||||
|
||||
private final T data; |
||||
|
||||
private final Duration retry; |
||||
|
||||
private final String comment; |
||||
|
||||
private ServerSentEvent(String id, String event, T data, Duration retry, String comment) { |
||||
this.id = id; |
||||
this.event = event; |
||||
this.data = data; |
||||
this.retry = retry; |
||||
this.comment = comment; |
||||
} |
||||
|
||||
/** |
||||
* Return a builder for a {@code SseEvent}. |
||||
* |
||||
* @param <T> the type of data that this event contains |
||||
* @return the builder |
||||
*/ |
||||
public static <T> Builder<T> builder() { |
||||
return new BuilderImpl<>(); |
||||
} |
||||
|
||||
/** |
||||
* Return a builder for a {@code SseEvent}, populated with the give {@linkplain #data() data}. |
||||
* |
||||
* @param <T> the type of data that this event contains |
||||
* @return the builder |
||||
*/ |
||||
public static <T> Builder<T> builder(T data) { |
||||
return new BuilderImpl<>(data); |
||||
} |
||||
|
||||
/** |
||||
* Return the {@code id} field of this event, if available. |
||||
*/ |
||||
public Optional<String> id() { |
||||
return Optional.ofNullable(this.id); |
||||
} |
||||
|
||||
/** |
||||
* Return the {@code event} field of this event, if available. |
||||
*/ |
||||
public Optional<String> event() { |
||||
return Optional.ofNullable(this.event); |
||||
} |
||||
|
||||
/** |
||||
* Return the {@code data} field of this event, if available. |
||||
*/ |
||||
public Optional<T> data() { |
||||
return Optional.ofNullable(this.data); |
||||
} |
||||
|
||||
/** |
||||
* Return the {@code retry} field of this event, if available. |
||||
*/ |
||||
public Optional<Duration> retry() { |
||||
return Optional.ofNullable(this.retry); |
||||
} |
||||
|
||||
/** |
||||
* Return the comment of this event, if available. |
||||
*/ |
||||
public Optional<String> comment() { |
||||
return Optional.ofNullable(this.comment); |
||||
} |
||||
|
||||
/** |
||||
* A mutable builder for a {@code SseEvent}. |
||||
* |
||||
* @param <T> the type of data that this event contains |
||||
*/ |
||||
public interface Builder<T> { |
||||
|
||||
/** |
||||
* Set the value of the {@code id} field. |
||||
* |
||||
* @param id the value of the id field |
||||
* @return {@code this} builder |
||||
*/ |
||||
Builder<T> id(String id); |
||||
|
||||
/** |
||||
* Set the value of the {@code event} field. |
||||
* |
||||
* @param event the value of the event field |
||||
* @return {@code this} builder |
||||
*/ |
||||
Builder<T> event(String event); |
||||
|
||||
/** |
||||
* Set the value of the {@code data} field. If the {@code data} argument is a multi-line {@code String}, it |
||||
* will be turned into multiple {@code data} field lines as defined in Server-Sent Events |
||||
* W3C recommendation. If {@code data} is not a String, it will be |
||||
* {@linkplain Jackson2JsonEncoder encoded} into JSON. |
||||
* |
||||
* @param data the value of the data field |
||||
* @return {@code this} builder |
||||
*/ |
||||
Builder<T> data(T data); |
||||
|
||||
/** |
||||
* Set the value of the {@code retry} field. |
||||
* |
||||
* @param retry the value of the retry field |
||||
* @return {@code this} builder |
||||
*/ |
||||
Builder<T> retry(Duration retry); |
||||
|
||||
/** |
||||
* Set SSE comment. If a multi-line comment is provided, it will be turned into multiple |
||||
* SSE comment lines as defined in Server-Sent Events W3C |
||||
* recommendation. |
||||
* |
||||
* @param comment the comment to set |
||||
* @return {@code this} builder |
||||
*/ |
||||
Builder<T> comment(String comment); |
||||
|
||||
/** |
||||
* Builds the event. |
||||
* |
||||
* @return the built event |
||||
*/ |
||||
ServerSentEvent<T> build(); |
||||
} |
||||
|
||||
private static class BuilderImpl<T> implements Builder<T> { |
||||
|
||||
private T data; |
||||
|
||||
private String id; |
||||
|
||||
private String event; |
||||
|
||||
private Duration retry; |
||||
|
||||
private String comment; |
||||
|
||||
public BuilderImpl() { |
||||
} |
||||
|
||||
public BuilderImpl(T data) { |
||||
this.data = data; |
||||
} |
||||
|
||||
@Override |
||||
public Builder<T> id(String id) { |
||||
this.id = id; |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public Builder<T> event(String event) { |
||||
this.event = event; |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public Builder<T> data(T data) { |
||||
this.data = data; |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public Builder<T> retry(Duration retry) { |
||||
this.retry = retry; |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public Builder<T> comment(String comment) { |
||||
this.comment = comment; |
||||
return this; |
||||
} |
||||
|
||||
@Override |
||||
public ServerSentEvent<T> build() { |
||||
return new ServerSentEvent<T>(this.id, this.event, this.data, this.retry, this.comment); |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,165 +0,0 @@
@@ -1,165 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2016 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.http.codec; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
|
||||
/** |
||||
* Representation for a Server-Sent Event for use with Spring's reactive Web |
||||
* support. {@code Flux<SseEvent>} or {@code Observable<SseEvent>} is the |
||||
* reactive equivalent to Spring MVC's {@code SseEmitter}. |
||||
* |
||||
* @author Sebastien Deleuze |
||||
* @since 5.0 |
||||
* @see SseEventHttpMessageWriter |
||||
* @see <a href="https://www.w3.org/TR/eventsource/">Server-Sent Events W3C recommendation</a> |
||||
*/ |
||||
public class SseEvent { |
||||
|
||||
private String id; |
||||
|
||||
private String name; |
||||
|
||||
private Object data; |
||||
|
||||
private MediaType mediaType; |
||||
|
||||
private Long reconnectTime; |
||||
|
||||
private String comment; |
||||
|
||||
|
||||
/** |
||||
* Create an empty instance. |
||||
*/ |
||||
public SseEvent() { |
||||
} |
||||
|
||||
/** |
||||
* Create an instance with the provided {@code data}. |
||||
*/ |
||||
public SseEvent(Object data) { |
||||
this.data = data; |
||||
} |
||||
|
||||
/** |
||||
* Create an instance with the provided {@code data} and {@code mediaType}. |
||||
*/ |
||||
public SseEvent(Object data, MediaType mediaType) { |
||||
this.data = data; |
||||
this.mediaType = mediaType; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Set the {@code id} SSE field |
||||
*/ |
||||
public void setId(String id) { |
||||
this.id = id; |
||||
} |
||||
|
||||
/** |
||||
* @see #setId(String) |
||||
*/ |
||||
public String getId() { |
||||
return id; |
||||
} |
||||
|
||||
/** |
||||
* Set the {@code event} SSE field |
||||
*/ |
||||
public void setName(String name) { |
||||
this.name = name; |
||||
} |
||||
|
||||
/** |
||||
* @see #setName(String) |
||||
*/ |
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
/** |
||||
* Set {@code data} SSE field. If a multiline {@code String} is provided, it will be |
||||
* turned into multiple {@code data} field lines as defined in Server-Sent Events |
||||
* W3C recommendation. |
||||
* |
||||
* If no {@code mediaType} is defined, default {@link SseEventHttpMessageWriter} will: |
||||
* - Turn single line {@code String} to a single {@code data} field |
||||
* - Turn multiline line {@code String} to multiple {@code data} fields |
||||
* - Serialize other {@code Object} as JSON |
||||
* |
||||
* @see #setMediaType(MediaType) |
||||
*/ |
||||
public void setData(Object data) { |
||||
this.data = data; |
||||
} |
||||
|
||||
/** |
||||
* @see #setData(Object) |
||||
*/ |
||||
public Object getData() { |
||||
return data; |
||||
} |
||||
|
||||
/** |
||||
* Set the {@link MediaType} used to serialize the {@code data}. |
||||
* {@link SseEventHttpMessageWriter} should be configured with the relevant encoder to be |
||||
* able to serialize it. |
||||
*/ |
||||
public void setMediaType(MediaType mediaType) { |
||||
this.mediaType = mediaType; |
||||
} |
||||
|
||||
/** |
||||
* @see #setMediaType(MediaType) |
||||
*/ |
||||
public MediaType getMediaType() { |
||||
return this.mediaType; |
||||
} |
||||
|
||||
/** |
||||
* Set the {@code retry} SSE field |
||||
*/ |
||||
public void setReconnectTime(Long reconnectTime) { |
||||
this.reconnectTime = reconnectTime; |
||||
} |
||||
|
||||
/** |
||||
* @see #setReconnectTime(Long) |
||||
*/ |
||||
public Long getReconnectTime() { |
||||
return reconnectTime; |
||||
} |
||||
|
||||
/** |
||||
* Set SSE comment. If a multiline comment is provided, it will be turned into multiple |
||||
* SSE comment lines by {@link SseEventHttpMessageWriter} as defined in Server-Sent Events W3C |
||||
* recommendation. |
||||
*/ |
||||
public void setComment(String comment) { |
||||
this.comment = comment; |
||||
} |
||||
|
||||
/** |
||||
* @see #setComment(String) |
||||
*/ |
||||
public String getComment() { |
||||
return comment; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue