在之前的章节中,我们已经完成了API系统、交易系统、定序系统、行情系统以及推送系统的设计与实现。今天我们将聚焦于构建UI系统,它是整个应用的前端交互部分。UI系统本质上是一个标准的Web系统,功能相对简单,主要提供用户登录和订单操作功能。
UI系统的架构遵循MVC模型。接下来,我们将详细介绍如何使用Spring Boot、Pebble模板引擎以及Vue.js框架来实现这个UI系统。
1. 引入Pebble模板依赖
首先,我们需要在pom.xml中引入Pebble模板的Spring Boot启动器依赖。这是我们用于渲染HTML视图的模板引擎。
xml<dependency><groupId>io.pebbletemplates</groupId><artifactId>pebble-spring-boot-starter</artifactId><version>${pebble.version}</version></dependency>
接着,在application.yml或ui.yml中配置Pebble模板的基本信息,指定视图目录和后缀。
yamlpebble:prefix: /templates/suffix: .html
请注意,视图文件应放置在src/main/resources/templates/目录下。
2. 创建MVC Controller
我们需要编写一个Controller来处理用户的登录请求。这里使用Spring MVC的@Controller和@GetMapping、@PostMapping注解来分别处理显示登录页面和提交登录表单。
java@Controllerpublic class MvcController extends LoggerSupport {// 显示登录页@GetMapping("/signin")public ModelAndView signin(HttpServletRequest request) {if (UserContext.getUserId() != null) {return redirect("/"); // 如果已经登录,直接跳转到首页}return prepareModelAndView("signin");}// 登录处理@PostMapping("/signin")public ModelAndView signIn(@RequestParam("email") String email, @RequestParam("password") String password,HttpServletRequest request, HttpServletResponse response) {try {UserProfileEntity userProfile = userService.signin(email, password);// 登录成功,设置用户CookieAuthToken token = new AuthToken(userProfile.userId, System.currentTimeMillis() + 1000 * cookieService.getExpiresInSeconds());cookieService.setSessionCookie(request, response, token);} catch (ApiException e) {// 登录失败,返回错误信息return prepareModelAndView("signin", Map.of("email", email, "error", "Invalid email or password."));} catch (Exception e) {// 登录失败,返回内部错误return prepareModelAndView("signin", Map.of("email", email, "error", "Internal server error."));}// 登录成功,跳转到首页return redirect("/");}}
在登录成功后,我们会设置一个代表用户身份的Cookie,其中包含userId和expiresAt等信息。为了保证安全性,我们使用HMAC(哈希消息认证码)来计算哈希值,从而避免客户端伪造Cookie。
3. 编写UI Filter
为了验证用户身份并将用户信息绑定到UserContext中,我们需要编写一个UI过滤器。这个过滤器将在每个请求中检查Cookie并将用户ID与请求绑定。
javapublic class UIFilter {@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)throws IOException, ServletException {// 查找CookieAuthToken auth = cookieService.findSessionCookie(req);Long userId = auth == null ? null : auth.userId();try (UserContext ctx = new UserContext(userId)) {// 执行后续请求chain.doFilter(req, resp);}}}
4. 创建Proxy Filter
UI系统通过转发API请求来简化JavaScript的调用,避免跨域问题,并确保请求已经过身份认证。ProxyFilter的作用是将前端页面的API调用转发给实际的API系统,并附加一次性Token进行验证。
javapublic class ProxyFilter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {Long userId = UserContext.getUserId();// 创建一次性TokenString authToken = null;if (userId != null) {AuthToken token = new AuthToken(userId, System.currentTimeMillis() + 60_000);authToken = "Bearer " + token.toSecureString(hmacKey);}// 转发API请求并获取响应String responseJson = null;try {if ("GET".equals(request.getMethod())) {Map<String, String[]> params = request.getParameterMap();Map<String, String> query = params.isEmpty() ? null : convertParams(params);responseJson = tradingApiClient.get(String.class, request.getRequestURI(), authToken, query);} else if ("POST".equals(request.getMethod())) {responseJson = tradingApiClient.post(String.class, request.getRequestURI(), authToken,readBody(request));}// 返回响应response.setContentType("application/json;charset=utf-8");PrintWriter pw = response.getWriter();pw.write(responseJson);pw.flush();} catch (ApiException e) {writeApiException(request, response, e);} catch (Exception e) {writeApiException(request, response,new ApiException(ApiError.INTERNAL_SERVER_ERROR, null, e.getMessage()));}}}
5. 页面设计与实现
UI系统的页面主要由前端JavaScript来实现。我们选择Vue.js作为前端框架,来处理页面的交互功能。下面是UI系统中的几个主要页面:
-
signin.html:用户登录页面
-
signup.html:用户注册页面
-
index.html:交易页面
在交易页面中,JavaScript负责与后端API交互,获取实时数据并更新页面内容。具体的Vue组件和交互细节将在后续的章节中详细讲解。
6. 注册功能与开发环境支持
在注册新用户时,我们会检查当前环境是否为本地开发环境。如果是开发环境,我们会自动给用户添加一些虚拟资产,否则新注册用户将无法进行交易。
小结
UI系统是Web应用中的前端交互部分,除了注册和登录功能外,主要的交易功能都由页面中的JavaScript实现。通过使用Spring Boot与Pebble模板引擎,结合Vue.js框架,UI系统不仅实现了基本的登录功能,还通过转发请求简化了前端与后端API的交互,提供了更为安全与高效的用户体验。
希望今天的内容对你构建Spring Cloud应用中的UI系统有所帮助!

被折叠的 条评论
为什么被折叠?



