基于Java Web的POS应用客显(Customer Display)开发实现方法咨询
Hey there! 我之前参与过Java Web POS系统的开发,对客显模块的实现有一些实际经验,结合Web环境的特性,给你整理了几种可行的方案,你可以根据自己的场景来选:
Java Web环境下POS客显模块的实现方案
1. 基于WebSocket的实时推送方案(最适合现代Web环境)
如果你的POS系统是基于Spring Boot/Spring MVC这类现代框架,WebSocket绝对是首选——它能实现后端和客显端的双向实时通信,完美适配客显需要即时更新的场景。
实现步骤:
- 后端用Spring WebSocket搭建消息推送服务
- 客显端用独立Web页面部署在收银副屏,通过WebSocket连接后端接收消息
- 收银台完成操作(比如扫码、结算)时,后端触发消息推送,客显页面实时更新内容
代码示例:
后端WebSocket配置
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { // 配置消息代理,客显端订阅这个主题接收消息 config.enableSimpleBroker("/topic"); // 设置后端接口的前缀 config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // 注册WebSocket端点,允许SockJS降级适配 registry.addEndpoint("/customer-display").withSockJS(); } }
消息推送控制器
@Controller public class CustomerDisplayController { @Autowired private SimpMessagingTemplate messagingTemplate; // 收银业务模块调用这个接口推送客显内容 @PostMapping("/push-display-content") public ResponseEntity<Void> pushDisplayContent(@RequestBody DisplayContent content) { // 向所有订阅/topic/customer-display的客户端推送消息 messagingTemplate.convertAndSend("/topic/customer-display", content); return ResponseEntity.ok().build(); } } // 客显内容实体类 @Data public class DisplayContent { private String itemName; private BigDecimal itemPrice; private BigDecimal totalAmount; }
客显端Web页面JS
var stompClient = null; // 连接WebSocket服务 function connectToDisplayService() { var socket = new SockJS('/customer-display'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { console.log('已连接客显服务: ' + frame); // 订阅消息主题 stompClient.subscribe('/topic/customer-display', function(message) { var content = JSON.parse(message.body); // 更新页面显示元素 document.getElementById("current-item").innerText = content.itemName; document.getElementById("item-price").innerText = "¥" + content.itemPrice; document.getElementById("total").innerText = "总价: ¥" + content.totalAmount; }); }); } // 页面加载时自动连接 window.onload = connectToDisplayService;
优缺点:
- ✅ 完全基于Web技术,无需额外客户端软件,兼容性强
- ✅ 实时性高,双向通信延迟极低
- ✅ 容易和现有Java Web系统集成
- ❌ 若使用老式专用LED客显,需额外中间层转换Web消息为硬件指令
2. 集成硬件厂商SDK方案(针对专用客显设备)
如果你的客显是收银专用的硬件(比如LED点阵屏、带串口的客显设备),通常厂商会提供Java版SDK或串口通信API,直接调用即可控制硬件。
实现步骤:
- 引入厂商提供的SDK依赖到项目中
- 后端通过串口/USB或网络连接客显设备,初始化硬件连接
- 收银业务操作时,调用SDK方法发送显示指令
代码示例:
@Component public class CustomerDisplayHardwareService { private VendorDisplayDevice displayDevice; // 初始化硬件连接(项目启动时执行) @PostConstruct public void initDevice() { // 假设厂商SDK需要指定串口端口 displayDevice = new VendorDisplayDevice("COM3"); displayDevice.openConnection(); } // 显示当前商品信息 public void showCurrentItem(String itemName, BigDecimal price) { displayDevice.sendCommand(String.format("SHOW_ITEM:%s|%.2f", itemName, price)); } // 显示结算总价 public void showTotalAmount(BigDecimal total) { displayDevice.sendCommand(String.format("SHOW_TOTAL:%.2f", total)); } // 项目关闭时释放硬件连接 @PreDestroy public void closeDevice() { displayDevice.closeConnection(); } }
优缺点:
- ✅ 直接控制硬件,显示效果稳定,支持设备特殊功能(比如滚动显示、高亮)
- ✅ 无需额外Web页面,适合专用硬件场景
- ❌ 依赖厂商SDK,更换设备需修改代码
- ❌ 若Web服务器和客显设备不在同一台机器,需通过串口服务器转网络连接
3. 基于Servlet+定时请求的方案(适合传统Web项目)
如果你的项目是老式Servlet/JSP架构,不想引入WebSocket这类新技术,可以用长轮询或定时请求的方式实现。
实现步骤:
- 后端写一个Servlet接口,返回当前需要显示的客显内容
- 客显端用桌面小程序(Java Swing/Electron)或Web页面,定时请求该接口更新显示
代码示例:
后端Servlet
@WebServlet("/get-display-content") public class DisplayContentServlet extends HttpServlet { // 用静态变量暂存当前需要显示的内容(实际项目建议用缓存或数据库) private static DisplayContent currentContent = new DisplayContent(); // 供收银业务模块调用更新内容 public static void updateDisplayContent(DisplayContent content) { currentContent = content; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("application/json;charset=UTF-8"); ObjectMapper mapper = new ObjectMapper(); mapper.writeValue(resp.getOutputStream(), currentContent); } }
客显端Java Swing小程序
public class CustomerDisplayApp extends JFrame { private JLabel displayLabel; public CustomerDisplayApp() { displayLabel = new JLabel("", SwingConstants.CENTER); displayLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16)); add(displayLabel); setSize(300, 200); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); // 每隔1秒请求一次后端更新内容 Timer timer = new Timer(1000, e -> { try { URL url = new URL("http://localhost:8080/get-display-content"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); String json = reader.readLine(); ObjectMapper mapper = new ObjectMapper(); DisplayContent content = mapper.readValue(json, DisplayContent.class); displayLabel.setText(String.format("商品:%s\n价格:¥%.2f\n总价:¥%.2f", content.getItemName(), content.getItemPrice(), content.getTotalAmount())); reader.close(); conn.disconnect(); } catch (Exception ex) { ex.printStackTrace(); } }); timer.start(); } public static void main(String[] args) { SwingUtilities.invokeLater(CustomerDisplayApp::new); } }
优缺点:
- ✅ 技术栈简单,适合传统Web项目,无需引入新框架
- ✅ 开发成本低,快速上手
- ❌ 实时性差(取决于轮询间隔)
- ❌ 频繁请求会增加服务器压力
方案选择建议
- 现代Java Web项目(Spring Boot/Spring MVC):优先选WebSocket方案,实时性和兼容性最优
- 使用专用客显硬件:选厂商SDK方案,直接控制硬件更稳定
- 老式Servlet/JSP项目:选Servlet+定时请求方案,低成本适配现有架构
内容的提问来源于stack exchange,提问作者CaveMan




