001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.http.codec; 018 019import java.time.Duration; 020 021import org.springframework.lang.Nullable; 022 023/** 024 * Representation for a Server-Sent Event for use with Spring's reactive Web support. 025 * {@code Flux<ServerSentEvent>} or {@code Observable<ServerSentEvent>} is the 026 * reactive equivalent to Spring MVC's {@code SseEmitter}. 027 * 028 * @author Sebastien Deleuze 029 * @author Arjen Poutsma 030 * @since 5.0 031 * @param <T> the type of data that this event contains 032 * @see ServerSentEventHttpMessageWriter 033 * @see <a href="https://www.w3.org/TR/eventsource/">Server-Sent Events W3C recommendation</a> 034 */ 035public final class ServerSentEvent<T> { 036 037 @Nullable 038 private final String id; 039 040 @Nullable 041 private final String event; 042 043 @Nullable 044 private final Duration retry; 045 046 @Nullable 047 private final String comment; 048 049 @Nullable 050 private final T data; 051 052 053 private ServerSentEvent(@Nullable String id, @Nullable String event, @Nullable Duration retry, 054 @Nullable String comment, @Nullable T data) { 055 056 this.id = id; 057 this.event = event; 058 this.retry = retry; 059 this.comment = comment; 060 this.data = data; 061 } 062 063 064 /** 065 * Return the {@code id} field of this event, if available. 066 */ 067 @Nullable 068 public String id() { 069 return this.id; 070 } 071 072 /** 073 * Return the {@code event} field of this event, if available. 074 */ 075 @Nullable 076 public String event() { 077 return this.event; 078 } 079 080 /** 081 * Return the {@code retry} field of this event, if available. 082 */ 083 @Nullable 084 public Duration retry() { 085 return this.retry; 086 } 087 088 /** 089 * Return the comment of this event, if available. 090 */ 091 @Nullable 092 public String comment() { 093 return this.comment; 094 } 095 096 /** 097 * Return the {@code data} field of this event, if available. 098 */ 099 @Nullable 100 public T data() { 101 return this.data; 102 } 103 104 105 @Override 106 public String toString() { 107 return ("ServerSentEvent [id = '" + this.id + "\', event='" + this.event + "\', retry=" + 108 this.retry + ", comment='" + this.comment + "', data=" + this.data + ']'); 109 } 110 111 112 /** 113 * Return a builder for a {@code SseEvent}. 114 * @param <T> the type of data that this event contains 115 * @return the builder 116 */ 117 public static <T> Builder<T> builder() { 118 return new BuilderImpl<>(); 119 } 120 121 /** 122 * Return a builder for a {@code SseEvent}, populated with the give {@linkplain #data() data}. 123 * @param <T> the type of data that this event contains 124 * @return the builder 125 */ 126 public static <T> Builder<T> builder(T data) { 127 return new BuilderImpl<>(data); 128 } 129 130 131 /** 132 * A mutable builder for a {@code SseEvent}. 133 * 134 * @param <T> the type of data that this event contains 135 */ 136 public interface Builder<T> { 137 138 /** 139 * Set the value of the {@code id} field. 140 * @param id the value of the id field 141 * @return {@code this} builder 142 */ 143 Builder<T> id(String id); 144 145 /** 146 * Set the value of the {@code event} field. 147 * @param event the value of the event field 148 * @return {@code this} builder 149 */ 150 Builder<T> event(String event); 151 152 /** 153 * Set the value of the {@code retry} field. 154 * @param retry the value of the retry field 155 * @return {@code this} builder 156 */ 157 Builder<T> retry(Duration retry); 158 159 /** 160 * Set SSE comment. If a multi-line comment is provided, it will be turned into multiple 161 * SSE comment lines as defined in Server-Sent Events W3C recommendation. 162 * @param comment the comment to set 163 * @return {@code this} builder 164 */ 165 Builder<T> comment(String comment); 166 167 /** 168 * Set the value of the {@code data} field. If the {@code data} argument is a multi-line 169 * {@code String}, it will be turned into multiple {@code data} field lines as defined 170 * in the Server-Sent Events W3C recommendation. If {@code data} is not a String, it will 171 * be {@linkplain org.springframework.http.codec.json.Jackson2JsonEncoder encoded} into JSON. 172 * @param data the value of the data field 173 * @return {@code this} builder 174 */ 175 Builder<T> data(@Nullable T data); 176 177 /** 178 * Builds the event. 179 * @return the built event 180 */ 181 ServerSentEvent<T> build(); 182 } 183 184 185 private static class BuilderImpl<T> implements Builder<T> { 186 187 @Nullable 188 private String id; 189 190 @Nullable 191 private String event; 192 193 @Nullable 194 private Duration retry; 195 196 @Nullable 197 private String comment; 198 199 @Nullable 200 private T data; 201 202 public BuilderImpl() { 203 } 204 205 public BuilderImpl(T data) { 206 this.data = data; 207 } 208 209 @Override 210 public Builder<T> id(String id) { 211 this.id = id; 212 return this; 213 } 214 215 @Override 216 public Builder<T> event(String event) { 217 this.event = event; 218 return this; 219 } 220 221 @Override 222 public Builder<T> retry(Duration retry) { 223 this.retry = retry; 224 return this; 225 } 226 227 @Override 228 public Builder<T> comment(String comment) { 229 this.comment = comment; 230 return this; 231 } 232 233 @Override 234 public Builder<T> data(@Nullable T data) { 235 this.data = data; 236 return this; 237 } 238 239 @Override 240 public ServerSentEvent<T> build() { 241 return new ServerSentEvent<>(this.id, this.event, this.retry, this.comment, this.data); 242 } 243 } 244 245}