本文目录导读:

您提到的“服务随信”在Java中通常有两种常见含义,需要先确认您具体指的是哪一种场景:
场景A:服务端主动向客户端推送消息(Server-Sent Events, 简称SSE)
即“服务随信而动”,服务器可以主动向浏览器/客户端推送数据,无需客户端反复请求。
场景B:在JavaWeb应用中通过邮件/短信/即时通讯发送“随信”通知
比如用户操作后,系统自动发送一封确认邮件或短信。
为了提供最具针对性的帮助,请确认您的具体需求,下面我先分别给出两种场景的核心实现思路和示例代码框架。
场景A:服务端主动推送(类似“消息推送/服务随信”)
适用技术:
- SSE(推荐,简单且标准):基于HTTP长连接,单向推送(服务端→客户端)
- WebSocket:双向通信,更复杂但功能更强
- 轮询(Polling):过时方案,不推荐
SSE 实现示例(Java Spring Boot)
后端代码:
@RestController
public class SseController {
// 返回一个SseEmitter对象,浏览器可以持续接收事件流
@GetMapping("/subscribe")
public SseEmitter subscribe() {
SseEmitter emitter = new SseEmitter(0L); // 0L表示不超时
// 通常需要将emitter存储起来,以便在其他线程中发送消息
SseEmitterManager.addEmitter("user123", emitter);
return emitter;
}
// 模拟后台任务或业务事件触发推送
@GetMapping("/push-event")
public String pushEvent() {
// 向指定用户发送消息
SseEmitterManager.sendToUser("user123", "服务端主动推送的消息:" + LocalTime.now());
return "消息已推送";
}
}
// 管理所有SSE连接的工具类
@Component
public class SseEmitterManager {
private static final Map<String, SseEmitter> emitters = new ConcurrentHashMap<>();
public static void addEmitter(String userId, SseEmitter emitter) {
emitters.put(userId, emitter);
emitter.onCompletion(() -> emitters.remove(userId));
emitter.onError(e -> emitters.remove(userId));
}
public static void sendToUser(String userId, String message) {
SseEmitter emitter = emitters.get(userId);
if (emitter != null) {
try {
emitter.send(SseEmitter.event()
.name("message") // 事件名称,前端监听对应事件
.data(message));
} catch (IOException e) {
emitters.remove(userId);
}
}
}
}
前端(HTML + JavaScript)接收:
const eventSource = new EventSource('/subscribe');
eventSource.addEventListener('message', function(event) {
console.log('收到推送:', event.data);
// 更新页面UI
});
WebSocket 实现示例(Spring Boot + WebSocket)
依赖: spring-boot-starter-websocket
配置类:
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/ws/connect")
.setAllowedOrigins("*");
}
}
处理器:
public class MyWebSocketHandler extends TextWebSocketHandler {
// 存储所有连接
private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) {
sessions.put(session.getId(), session);
}
// 业务中调用此方法推送
public static void sendToAll(String message) {
sessions.values().forEach(s -> {
try { s.sendMessage(new TextMessage(message)); } catch (IOException e) {}
});
}
}
场景B:发送“随信”通知(例如自动发送邮件或短信)
适用技术:
- JavaMail:发送邮件
- 阿里云/腾讯云短信SDK:发送短信
- Webhook + 第三方IM:企业微信/钉钉机器人
用JavaMail发送“随信”(以Spring Boot为例)
依赖: spring-boot-starter-mail
application.yml配置:
spring:
mail:
host: smtp.qq.com
port: 587
username: your-email@qq.com
password: your-auth-code # 不是QQ密码,是授权码
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
发送服务类:
@Service
public class MailService {
@Autowired
private JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String from;
public void sendSimpleMail(String to, String subject, String content) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(content);
mailSender.send(message);
}
// 业务中调用:当用户注册、下单等事件发生时
public void notifyUserSignup(String userEmail) {
sendSimpleMail(userEmail, "欢迎注册", "感谢您成为我们的用户!");
}
}
发送短信(以阿里云为例)
依赖: aliyun-java-sdk-core + aliyun-java-sdk-dysmsapi
@Service
public class SmsService {
public void sendSms(String phone, String code) {
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou",
"your-access-key", "your-secret");
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("dysmsapi.aliyuncs.com");
request.setSysVersion("2017-05-25");
request.setSysAction("SendSms");
request.putQueryParameter("PhoneNumbers", phone);
request.putQueryParameter("SignName", "您的签名");
request.putQueryParameter("TemplateCode", "SMS_..."); // 模板ID
request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
try { client.getCommonResponse(request); } catch (Exception e) { e.printStackTrace(); }
}
}
请选择您的场景:
| 您的需求 | 推荐方案 |
|---|---|
| 实时推送数据到浏览器(如监控、通知) | SSE (Server-Sent Events) |
| 需要双向实时通信(如聊天室) | WebSocket |
| 发送邮件通知 | JavaMail (Spring Boot Mail) |
| 发送短信验证码或通知 | 第三方短信SDK |
如果您能补充具体业务场景,可以给出更完整的示例代码框架。