单页应用程序正Swift吸引人们的注意力,以实现基于Web的丰富,健壮和移动友好的应用程序。 本质上,这需要改变应用程序体系结构,其中整个应用程序用户界面是使用JavaScript来实现的,而服务器端代码则为服务器端应用程序逻辑和数据访问提供了基于RESTful,基于JSON的API。 该模型如下所示:

单独的客户端和服务器端部署组件的案例

SPA的这种转变为用户带来了体验和性能上的好处,并提供了将用户界面与服务器端逻辑完全分离的机会。 从代码分区的角度来看,我们通过应用模型视图控制器(MVC)模式将UI与应用程序逻辑分离。 从部署应用程序生命周期的角度来看,它们仍然是耦合的–也就是说,应用程序在一个组件中与静态客户端元素和服务器端元素一起打包和部署。

似乎自然的本能是将客户端和服务器端元素都打包到单个JEE WAR组件中。 这可以使应用程序的生命周期更简单,但是,应用程序的构建似乎自然地组织了使用UI的开发人员和使用服务器端API的开发人员,并且由于使用了两种不同的开发语言,因此更为自然。 因此,将应用程序分为用于UI和服务器端API元素的单独的可部署WAR,而不是一个WAR,可以带来以下好处:

  • API对于UI开发保持稳定(不是移动目标)
  • UI控制何时引入服务器端API更改
  • 支持UI和API层的并发开发人员路径
  • 可以测试对UI的更改并将其移至质量检查和生产环境中,而无需重新测试API层
  • 可以更改底层API实施/技术,而不会影响UI
  • UI实现/技术可以更改而不会影响API
  • 在运行时引入UI元素的机会(利用JavaScript动态行为)

这是此拓扑的图片:

怎么样?

由于UI是使用动态JavaScript实现的,因此不必使用JEE WAR组件来容纳UI资源。 可以使用任何Web服务器,例如Apache或非常流行的Node.js服务器 。 但是,已经支持JEE的企业将获得对WAR的生命周期支持,这为使用服务器端动态行为进行资源的初始加载,身份验证以及以动态方式集成或中介事物打开了大门。

例如,代替最初使用index.html加载SPA,可以使用index.jsp将某些用户/客户端特定的逻辑应用于加载过程。

Servlet解决方案

支持SPA API /端点的一种解决方案是在静态内容SPA WAR中实现Servlet,该Servlet将API URL路由重定向到端点所驻留的服务器。 这是通过在web.xml中定义一个servlet以及对服务器的API调用的映射来实现的。

这是一个处理以API开头的URI的示例web.xml配置:

<servlet><servlet-name>api</servlet-name><display-name>api</display-name><servlet-class>com.khs.spa.servlet.ApiServlet</servlet-class><init-param><param-name>redirect</param-name><param-value>localhost:8080/khs-command-ref</param-value></init-param></servlet><servlet-mapping><servlet-name>api</servlet-name><url-pattern>/api/*</url-pattern></servlet-mapping>

Servlet将根据上面显示的重定向初始化参数值中定义的URL重定向到API WAR。

重定向API HTTP GET / POST / PUT / DELETE请求的API Servlet实现如下所示:

package com.khs.spa.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ApiServlet extends HttpServlet {private static final long serialVersionUID = 4345668988238038540L;private String redirect = null;@Overridepublic void init() throws ServletException {super.init();// load redirect for servletredirect = getServletConfig().getInitParameter("redirect");if (redirect == null) {throw new RuntimeException("redirect value not set in servlet <init-param>");}}private void doService(HttpServletRequest request,HttpServletResponse response) throws RuntimeException, IOException {// you could do extra stuff here, i.e. logging etc...String path = request.getRequestURI().split(request.getContextPath())[1];String route = redirect + path;response.sendRedirect(route);}@Overrideprotected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doService(request, response);}@Overrideprotected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doService(request, response);}@Overrideprotected void doPut(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doService(request, response);}@Overrideprotected void doDelete(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {doService(request, response);}@Overrideprotected long getLastModified(HttpServletRequest req) {return super.getLastModified(req);}@Overrideprotected void doHead(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {super.doHead(req, resp);}@Overrideprotected void doOptions(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {super.doOptions(req, resp);}@Overrideprotected void doTrace(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {super.doTrace(req, resp);}
}

注意事项

此方法假定无状态API实现。 由于涉及重定向,因此如果API WAR基于会话,则除非采用某种联合会话机制,否则它将不起作用。 身份验证和授权机制可以在客户端SPA UI-WAR和/或API层进行。 同样,如果需要为SPA访问多个API服务或企业系统,则仍可以在SPA UI-WAR中应用它们。

单页应用程序不仅使我们能够实现丰富/响应的用户界面,而且还促进了数据和应用程序逻辑的轻巧易用的宁静API的使用。 用户界面的这种物理运行时解耦使“废弃”用户界面的概念更加切合实际,并且可以通过API层实现可重用服务的可用性。

  • 代码项目
参考: Keyhole Software博客上的JAR合作伙伴 David Pitt 将SPA资源和API实施划分为单独的WAR组件 。

翻译自: https://www.javacodegeeks.com/2014/02/partitioning-spa-resources-and-api-implementations-in-separate-war-components.html

在单独的WAR组件中对SPA资源和API实现进行分区相关推荐

  1. war3必须安装的游戏组件_在单独的WAR组件中对SPA资源和API实现进行分区

    war3必须安装的游戏组件 单页应用程序正Swift吸引人们的注意力,以实现基于Web的丰富,健壮和移动友好的应用程序. 从本质上讲,这需要更改应用程序体系结构,在该体系结构中,整个应用程序用户界面都 ...

  2. withRouter() 在非路由组件中使用路由库的api

    我们知道,在非路由组件中,是拿不到例如像  this.props.location.pathname 数据. 倘若我们想拿到类似这种路由数据,可以使用withRouter()将非路由组件包装成路由组件 ...

  3. jdeveloper_在JDeveloper 12.1.3中为WebSocket使用Java API

    jdeveloper 介绍 最新版本的JDeveloper 12c(12.1.3.0)和WebLogic Server 12.1.3一起提供了一些新的Java EE 7功能. 其中之一是对用于WebS ...

  4. .jdeveloper_在JDeveloper 12.1.3中为WebSocket使用Java API

    .jdeveloper 介绍 最新版本的JDeveloper 12c(12.1.3.0)和WebLogic Server 12.1.3一起提供了一些新的Java EE 7功能. 其中之一是对用于Web ...

  5. 单独使用elementui_Vue在单独引入js文件中使用ElementUI的组件

    Vue在单独引入js文件中使用ElementUI的组件 问题场景: 我想在vue中的js文件中使用elementUI中的组件,因为我在main.js中引入了element包和它的css,并挂载到了全局 ...

  6. nuxt 如何引入js_nuxtjs如何在单独的js文件中引入store和router

    nuxtjs里面集成vuex的创建方式改变了,并且官方不建议以导出Vuex实例的方式创建store,并且会在nuxt3里面删除.这样就会存在一个问题,我怎么像普通vue spa项目一样直接 impor ...

  7. java socket中属性详解_前端开发:关于Vue组件中的data属性值是函数而不是对象的详解...

    最近在搞关于前端开发的基础知识归纳,发现了不少经典知识点,那么本篇博文就来分享一个经典的知识点:Vue组件中的data属性值为什么是函数而不是对象.首先来了解一下Vue组件的使用理念:在Vue组件使用 ...

  8. 饿了么ui组件中分页获取当前选中的页码值_【Web技术】314 前端组件设计原则

    点击上方"前端自习课"关注,学习起来~ 译者:@没有好名字了译文:https://github.com/lightningminers/article/issues/36,http ...

  9. 在 vue 组件中查看 vuex 定义

    原文:在 vue 组件中查看 vuex 定义 在进行 vue 项目开发的时,如果项目中用到了 vuex 做状态管理,经常需要查看 store 里面定义的状态属性.但是在 vue 组件中引用这些 vue ...

最新文章

  1. [流媒体]实例解析MMS流媒体协议,下载LiveMediaVideo[4]
  2. 网站测试自动化系统—系统应该有的功能
  3. 基于keras的深度学习基本概念讲解——深度学习之从小白到入门
  4. linux查看基础硬件信息
  5. 如何使用jmeter进行并发登录测试
  6. PingCAP创始人刘奇:TiDB设计理念进化与大规模实践
  7. 晶体封装越小esr越大_二轮复习分子晶体与原子晶体
  8. Servlet转发forward和重定向response.sendRedirect()区别
  9. NVIDIA官方指南:libav编译支持Nvidia Codec(结果失败)
  10. Hadoop HA集群部署
  11. 猿创征文|工具在手,天下我有(初入职场必备的黑科技工具)
  12. 61php飞信发送类(phpfetion)v1.5,资源索引 L_PC6下载
  13. idea 一直不停的updating index
  14. 工作学习中word及电脑常备小知识(C盘清理、电脑上微信记录清理)
  15. 什么是企业邮箱,如何申请企业邮箱,企业邮箱一年多少钱?
  16. java redis 实现pv uv_redis实战-记录PV与UV
  17. element el-table 在IE浏览器 表头失效问题
  18. mysql 8 全文检索_MySQL 8中使用全文检索示例
  19. cv.bitwise_and用法
  20. 技术 | 有道CEO周枫:NVidia Volta GPU深度学习性能提升近10倍

热门文章

  1. mysql加索引快很多
  2. 关闭(杀死)8080端口
  3. 第12步 用户模块前端(客户)
  4. tomcat(13)Host和Engine容器
  5. 本地方法(JNI)——调用 java 方法
  6. java中的lombok_如何在Java中使用Lombok删除样板设置器吸气剂
  7. javafx 调用java_Java,JavaFX的流畅设计风格进度栏
  8. couchbase集群_使用CLI扩展和重新平衡Couchbase集群
  9. 绩效工作流_流绩效–您的想法
  10. hazelcast入门教程_Hazelcast入门指南第2部分