Web应用程序定义及优势
应用程序可以分为两种模式:C/S、B/S。C/S是客户端/服务器端程序(Client/Server),也就是说这类程序一般独立运行。而B/S就是浏览器端/服务器端应用程序(Browser/Server),这类应用程序一般借助各种浏览器来运行。Web应用程序一般是B/S模式。

Web应用程序的优点主要有两大优点:一、访问Web应用程序更容易:访问Web网页的标准协议HTTP协议,被大多数操作系统支持,客户端仅需安装浏览器即可;二、维护和部署成本低:Web应用程序升级和维护一般只需在Web服务器上部署更新即可,客户端无需做任何更动。

目前业界主流的Web应用程序主要基于J2EE或者.Net,此外还有一些轻量级的平台如php,ruby,python等等。本文主要介绍基于J2EE的Web应用程序快速开发。

Appfuse快速开发模型及相关技术简介
进行Web应用程序开发,通常的步骤是先搭建框架,目前业界常用三层构架(Web层,Service层,以及DAO层),具体如下:
 表示层(Presentation Layer):位于最外层(最上层),离用户最近。用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。 目前可选的开源框架有Struts2,JSF,springMVC以及Tapestry等。
 业务逻辑层(Business Logic Layer):无疑是系统架构中体现核心价值的部分。它的关注点主要集中在业务规则的制定、业务流程的实现等与业务需求有关的系统设计。业务逻辑层在体系架构中的位置尤为关键,它处于数据访问层与表示层中间,起到了数据交换中承上启下的作用。层是一种弱耦合结构,层与层之间的依赖是向下的,底层对于上层而言是“无知”的,改变上层的设计对于其调用的底层而言没有任何影响。如果在分层设计时,遵循了面向接口设计的思想,那么这种向下的依赖也应该是一种弱依赖关系。因而在不改变接口定义的前提下,理想的分层式架构,应该是一个支持可抽取、可替换的“抽屉”式架构。正因为如此,业务逻辑层扮演了两个不同的角色。对于数据访问层而言,它是调用者;对于表示层而言,它却是被调用者。依赖与被依赖的关系都纠结在业务逻辑层上,如何实现依赖关系的解耦,则是除了实现业务逻辑之外留给设计师的任务。目前最为常用的逻辑层框架是springframework。
 数据访问层(Data Access Layer):有时候也称为是持久层,其功能主要是负责数据库的访问,可以访问数据库系统、二进制文件、文本文档或是XML文档。简单的说法就是实现对数据表的Select,Insert,Update,Delete的操作。如果要加入ORM的元素,那么就会包括对象和数据表之间的mapping,以及对象实体的持久化。目前可选的主流开源框架有Hibernate,ibatis以及JPA等。

在配置主体(三层)构架之后,还有其他很多繁复的配置项,例如项目的自动打包脚本(ant或者maven),自动化测试框架(JUNIT,DBUNIT等),代码自动检查配置(PMD,checkstyle,或者findbugs等)。逐一手动配置,并且测试,将是一件漫长而又痛苦的事情。因此一般项目开发初期会复制已有项目,在已有项目备份上进行开发,但这样也随之引入了很多不需要的代码以及bug等。如何快速的构建项目原始框架一直一来是项目初期搭建的困扰之一。

现在有了Appfuse,一个开放源码的项目和应用程序。它使用了在 Java 平台上构建的开放源码工具来帮助我们快速而高效地开发 Web 应用程序。为了减少在为客户构建新 Web 应用程序时所花费的那些不必要的时间。从核心上来说,Appfuse 是一个项目骨架,类似于通过向导创建新 Web 项目时 IDE 所创建的东西。当我们使用 Appfuse 创建一个项目时,它会提示我们将使用开放源码框架,然后才创建项目。它使用 maven来驱动测试、代码生成、编译和部署。它提供了目录和包结构,以及开发基于 Java 语言的 Web 应用程序所需要的库。

与大部分 “new project” 向导不同,Appfuse 创建的项目从最开始就包含很多类和文件。这些文件用来实现特性,不过它们同时也会在您开发应用程序时被用作示例。通过使用 Appfuse 启动新项目,我们通常可以减少一到两周的开发时间。我们不用担心如何将开放源码框架配置在一起,因为这都已经完成了。我们的项目都已提前配置来与数据库进行交互,它会部署到应用服务器上,并对用户进行认证。我们不必实现安全特性,因为这都早已集成了。

最初版的 Appfuse ,只支持 Struts 和 Hibernate。经过几年的努力。现在,Appfuse 可以支持 Hibernate作为持久性框架。对于 Web 框架来说,我们可以使用 JavaServer Faces(JSF)、Spring MVC、Struts、Tapestry 。

Appfuse 提供了很多应用程序需要的一些特性,包括:
 与Maven 2 集成
 支持Spring的Annotation
 可选的Web 框架支持: JSF, Struts 2, Spring MVC, and Tapestry 5
 对于JDK 5, Annotations, JSP 2.0, Servlet 2.4, JPA的支持
 附带通用CRUD 的后台代码样例
 通过Maven,对于目前主流IDE,例如Eclipse, IDEA 和NetBeans的完美支持
 通过Maven Jetty Plugin快速启动
 通过 Cargo及相关配置,可以在多种应用服务器及数据库上部署测试
 基于最新的spring security认证和授权,完善的用户管理,密码提醒,登记和注册
 SSL转换,E-mail支持,URL重写,文件上传下载
 皮肤,页面修饰,模板化布局

Appfuse快速开发步骤简述
一、创建工程
1,安装JDK,推荐使用JDK6,可至oracle网站下载;
2,安装mysql,推荐使用5.x,可至oracle网站下载,默认用户名为sa,密码留空;
3,安装maven,推荐使用2.2.1,并配置本地repository,及相关外部源;
4,安装IDE,推荐使用eclipse(目前业界使用率最高),及相关插件,例如wtp,m2eclipse等
5,配置环境变量:maven_home;java_home;path;
6,下载Appfuse,可至官网(http://appfuse.org/display/APF/AppFuse+QuickStart)使用mvn archetype:generate 生成原始框架。

目前最新版为2.1.0-M2,如上图,可以更改包名,项目名,appfuse版本,主体的Web框架,此页面会更加选择生成命令行。生成例子如下:
 以struts2为主体的Web框架的项目名为struts2的原型项目生成命令行:
 mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-struts-archetype -DarchetypeVersion=2.1.0-M2 -DgroupId=com.mycompany -DartifactId=struts2
 以jsf为主体的Web框架的项目名为jsf的原型项目生成命令行:
 mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-jsf-archetype -DarchetypeVersion=2.1.0-M2 -DgroupId=com.mycompany -DartifactId=jsf
 以springmvc为主体的Web框架的项目名为springmvc的原型项目生成命令行:
 mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-spring-archetype -DarchetypeVersion=2.1.0-M2 -DgroupId=com.mycompany -DartifactId=springmvc
 以tapestry为主体的Web框架的项目名为tapestry的原型项目生成命令行:
 mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-tapestry-archetype -DarchetypeVersion=2.1.0-M2 -DgroupId=com.mycompany -DartifactId=tapestry
在这个例子中,我们将使用基于springmvc的2.1.0-M2原型框架,发布于(2010年11月15日);
7,进入生成完成的appfuse原型项目如(“D:/project/ appfuse”);
8,执行cmd -- “mvn install”,其间maven会自动下载本地库中所没有的类库源码及文档;并且运行所配置的默认测试用例,包括Junit,dbunit,jmocktest等;
9,执行成功将会有“build successful”的提示,如下:

10,进入文件夹“D:/project/ appfuse”使用“mvn jetty:run”运行原型项目,效果如下
Web服务器启动完成:

使用浏览器登入http://localhost:8080/,即可看到登入页面如下:

点击申请,即可注册用户,效果如下:

原型项目支持两种类型用户admin/admin和user/user,分别截图如下:
user 登入界面

admin登入界面

11,使用“mvn appfuse:full-source”可以将appfuse类库转换成源码放置于项目中;
12,使用“mvn eclipse: eclipse”可以将原型项目转换成eclipse项目,便于开发;
13,使用“mvn clean”可以将项目无用的target等部署测试用文件夹清除。

二、使用IDE修改相关配置
1、数据库相关配置
由于采用了Hiberante作为DAO层核心,凭借其众多的dialect实现,通过更改配置文件即可更改项目所用的数据库,涵盖主流的oracle,DB2,MS SQL Server以及一些轻量级数据库实现,如mysql,h2database,PostgreSQL,derby等。
更改jdbc.properties或者pom.xml都可以达到修改数据类型,用户名,密码的效果。

2、表现层修改
可以更改com.mycompany.webapp下的源文件,以及src\main\webapp的css,js,jsp文件,更改表现层的实现。

3、逻辑层修改
可以更改com.mycompany.service下的源文件更改逻辑层的实现。

4、数据库层修改
可以更改com.mycompany.dao下的源文件更改数据库层的实现。

5、测试用例修改
可以更改src\test下的源文件以及配置文件更改测试用例的实现。

以下给出三个更改实例,添加ajax,定时任务以及新增Web Services。
整合AjaxTags实现AJAX特性
AJAX = 异步 JavaScript 及 XML(Asynchronous JavaScript and XML)。AJAX 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术。

通过 AJAX,您的 JavaScript 可使用 JavaScript 的 XMLHttpRequest 对象来直接与服务器进行通信。通过这个对象,您的 JavaScript 可在不重载页面的情况与 Web 服务器交换数据。AJAX 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求),这样就可使网页从服务器请求少量的信息,而不是整个页面。AJAX 可使因特网应用程序更小、更快,更友好。

传统的web应用模型工作起来就象这样:大部分界面上的用户动作触发一个连接到Web服务器的 HTTP请求。服务器完成一些处理---接收数据,处理计算,再访问其它的数据库系统,最后返回一个HTML页面到客户端。

图1: 传统Web应用模型(左)与Ajax模型的比较(右).

通过在用户和服务器之间引入一个Ajax引擎,可以消除Web的开始-停止-开始-停止这样的交互过程. 它就像增加了一层机制到程序中,使它响应更灵敏,而它的确做到了这一点。

  不像加载一个页面一样,在会话的开始,浏览器加载了一个Ajax引擎---采用JavaScript编写并且通常在一个隐藏frame中。这个引擎负责绘制用户界面以及与服务器端通讯。Ajax引擎允许用异步的方式实现用户与程序的交互--不用等待服务器的通讯。所以用户再不不用打开一个空白窗口,看到等待光标不断的转,等待服务器完成后再响应。

图 2: 传统Web应用的同步交互过程(上)和Ajax应用的异步交互过程的比较(下).

  通常要产生一个HTTP请求的用户动作现在通过JavaScript调用Ajax引擎来代替. 任何用户动作的响应不再要求直接传到服务器---例如简单的数据校验,内存中的数据编辑,甚至一些页面导航---引擎自己就可以处理它. 如果引擎需要从服务器取数据来响应用户动作---假设它提交需要处理的数据,载入另外的界面代码,或者接收新的数据---引擎让这些工作异步进行,通常使用XML, 不用再担误用户界面的交互。

1. 更改POM加入AjaxTags(1.3-beta-rc7)依赖,如下:
<dependency>
<groupId>org.ajaxtags</groupId>
<artifactId>ajaxtags</artifactId>
<version>1.3-beta-rc7</version>
</dependency>

2. 代码更改,如下:
在UserDao.java中加入
public List getUsersBySearchString(String searchString);
在UserDaoHibernate.java中加入
public List getUsersBySearchString(String searchString) {
return getHibernateTemplate().find("from User u where u.username like '%"+searchString+"%'");
}
在UserManager.java中加入
public List getUsersBySearchString(String searchString);
在UserManagerImpl.java中加入
public List getUsersBySearchString(String searchString) {
return userDao.getUsersBySearchString(searchString);
}
在所有的theme.css中加入@import url(../ajaxtags.css);
在web/scripts中加入ajaxtags.js
在web/ styles中加入ajaxtags-sample.css

3. 在com.mycompany.webapp.controller中新增AjaxFrontController
package com.mycompany.webapp.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import com.mycompany.service.UserManager;

@Controller
@RequestMapping("/ajaxFront*.*")
public class AjaxFrontController extends MultiActionController {
private transient final Log log = LogFactory
.getLog(AjaxFrontController.class);

private UserManager userManager = null;
@Autowired
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}

/**
* Only used for testing this tutorial !
*/
public ModelAndView ajaxFrontDemo(HttpServletRequest request,
HttpServletResponse response) {

return new ModelAndView("demoUser", "dummy", null);
}

public ModelAndView ajaxFrontGetUsers(HttpServletRequest request,
HttpServletResponse response) {
if (log.isDebugEnabled()) {
log.debug("Entering method...");
}
String userz = request.getParameter("user");
log.debug("AJAX - Fetching %" + userz + "%");
return new ModelAndView("autocompleteUsersXML", "users",
userManager.getUsersBySearchString(userz));
}
}
4. 在com.mycompany.webapp.view中新增AutocompleteUsersView
package com.mycompany.webapp.view;

import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ajaxtags.helpers.AjaxXmlBuilder;
import org.springframework.web.servlet.view.AbstractView;

public class AutocompleteUsersView extends AbstractView {

protected void renderMergedOutputModel(Map model,
HttpServletRequest httpServletRequest, HttpServletResponse response)
throws Exception {
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
List users = (List) model.get("users");

String xml = new AjaxXmlBuilder().addItems(users, "username",
"username").toString();

ServletOutputStream out = response.getOutputStream();
out.print(xml);
out.close();
}
}
5. 在web/pages中加入demoUser.jsp
<%@ include file="/common/taglibs.jsp" %>
<%@ taglib uri="http://ajaxtags.org/tags/ajax" prefix="ajax" %>

<!-- ajaxtags stuff -->
<script type="text/javascript" src="<c:url value='/scripts/ajaxtags.js'/>"></script>

<head>
</head>
<form method="post" action="">
<input type="text" id="user_name" name="user_name" size="40" value=""/>
<span id="indicator" style="display:none;"><img src="<c:url value="/images/indicator.gif"/>"/></span>
</form>

<ajax:autocomplete
baseUrl="${pageContext.request.contextPath}/ajaxFrontGetUsers.html"
source="user_name"
target="user_name"
className="autocomplete"
indicator="indicator"
minimumCharacters="1"
parameters="user={user_name}"
parser="new ResponseXmlToHtmlListParser()"/>

6. 在src\main\webapp\WEB-INF\dispatcher-servlet.xml中加入
<bean id="xmlViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views"/>
<property name="order" value="1"/>
</bean>
7. 在src\main\resources\views.properties中加入
autocompleteUsersXML.(class)=com.mycompany.webapp.view.AutocompleteUsersView
8. 测试,如下

整合Quartz实现定时任务操作
开源Quartz项目是一个专用的任务调度引擎,它可以在Java EE和Java SE中使用。Quartz提供了极其全面的特性,例如持久化任务、集群和分布式事务。Spring对Quartz的集成与Spring对Timer的集成在任务的声明式配置、触发器和调度上都非常相似。除此之外,Spring还提供额外的任务持久化特性,可以让Quartz的调度加入到Spring事务管理机制中。

Quartz的核心由两个接口和两个类组成:Job和Scheduler接口,JobDetail和Trigger类。从它们的名字可以了解它们的主要用途。只有JobDetail类的角色不太清晰。不同于基于Timer的任务调度,任务并不是从一个实现Job接口的类的实例开始的。实际上,Quartz将在它需要时再创建Job类的实例。你可以使用JobDetail类封装任务状态,并传递信息给一个任务或在任务的连续执行中间保存信息。使用基于Timer的任务调度,并没有关于自己封装触发器逻辑的触发器概念。Quartz支持一种可插拔触发器的架构,这可以让你在合适的时机创建你自己的实现。但是,你很少会需要创建你自己的Trigger实现,因为Quartz已经提供了极其强大的CronTrigger类,可以让你使用Cron 表达式来对任务执行进行细粒度的控制。

1. 更改POM加入quartz(1.5.2)依赖,如下:
<dependency>
<groupId>opensymphony</groupId>
<artifactId>quartz</artifactId>
<version>1.5.2</version>
</dependency>

2. 代码更改,如下:
在UserManager.java中加入
public void checkLastLogin();
在UserManagerImpl.java中加入
public void checkLastLogin() {
log.info("Congratulations! Quartz called the dummy method!");
}
在applicationContext-service.xml中加入定时任务配置:
dummyJobDetail为所定义的将被任务,即输出"Congratulations! Quartz called the dummy method!"; dummyTrigger定义了一个定时器使用了Quzrtz中的两个属性startDelay启动时延,这里设置为30000毫秒,即30秒,repeatInterval重复执行频度为45秒;SchedulerFactoryBean定义了项目中运行的所有任务队列,目前配置了两种普通定时任务SimpleTriggerBean以及Cron表达式配置的任务CronTriggerBean;在最后的dummyCronTrigger中配置了一个带有Cron表达式配置的任务,通过Cron表达式,任何复杂的定时情况都可以用一个字符串表示,例如每天的下午两点到三点之间每分钟运行一次的任务可以用“0 * 14 * * ?”表达。

<bean id="dummyJobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<ref bean="userManager" />
</property>
<property name="targetMethod">
<value>checkLastLogin</value>
</property>
</bean>

<bean id="dummyTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail">
<ref bean="dummyJobDetail" />
</property>
<property name="startDelay">
<value>30000</value>
</property>
<property name="repeatInterval">
<value>45000</value>
</property>
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="dummyTrigger" />
<ref local="dummyCronTrigger" />
</list>
</property>
</bean>

<!-- Fire every minute starting at 2pm and ending at 2:59pm, every day -->
<bean id="dummyCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="dummyJobDetail" />
</property>
<property name="cronExpression">
<value>0 * 14 * * ?</value>
</property>
</bean>

3. 测试效果,如下:

整合CXF添加新的Web Services应用
Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,现在已经正式更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。目前它仍只是 Apache 的一个孵化项目。

Apache CXF 是一个开源的 Services 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。CXF简化了构造,集成,面向服务架构(SOA)业务组件与技术的灵活复用。在CXF中,Service使用WSDL标准定义并能够使用各种不同的消息格式(或binding)和网络协议(transports)包括SOAP、XML(通过HTTP或JMS)进行访问。CXF同样支持多种model 如:JAX-WS,JBI,SCA和CORBA service。CXF设计成可灵活部署到各种容器中包括Spring-based,JBI,SCA, Servlet和J2EE容器。

CXF 包含了大量的功能特性,但是主要集中在以下几个方面:
1. 支持 Web Services 标准:CXF 支持多种 Web Services 标准,包含 SOAP、Basic Profile、WS-Addressing、WS-Policy、WS-ReliableMessaging 和 WS-Security。
2. Frontends:CXF 支持多种“Frontend”编程模型,CXF 实现了 JAX-WS API (遵循 JAX-WS 2.0 TCK 版本),它也包含一个“simple frontend”允许客户端和 EndPoint 的创建,而不需要 Annotation 注解。CXF 既支持 WSDL 优先开发,也支持从 Java 的代码优先开发模式。
3. 容易使用: CXF 设计得更加直观与容易使用。有大量简单的 API 用来快速地构建代码优先的 Services,各种 Maven 的插件也使集成更加容易,支持 JAX-WS API ,支持 Spring 2.0 更加简化的 XML 配置方式,等等。
4. 支持二进制和遗留协议:CXF 的设计是一种可插拨的架构,既可以支持 XML ,也可以支持非 XML 的类型绑定,比如:JSON 和 CORBA。

1. 代码更改,如下:
新增TimeManager.java,这是项目内部使用的service入口
package com.mycompany.service;

public interface TimeManager {
String getCurrentDate();
}
新增TimeService.java,这是对外暴露的WebService,并使用@ WebService标注
package com.mycompany.service;

import javax.jws.WebService;

@WebService
public interface TimeService {
String getCurrentDate();
}
新增TimeManagerImpl.java,对应以上两接口的实现类
package com.mycompany.service.impl;

import java.util.Date;

import javax.jws.WebService;

import org.springframework.stereotype.Service;

import com.mycompany.service.TimeManager;
import com.mycompany.service.TimeService;

@Service("timeManager")
@WebService(serviceName = "TimeService", endpointInterface = "com.mycompany.service.TimeService")
public class TimeManagerImpl implements TimeService,TimeManager {
public String getCurrentDate() {
return (new Date()).toString();
}
}
最后分别在applicationContext-test.xml和cxf-servlet.xml中加入接口的引用
applicationContext-test.xml中
<bean id="timeManager" class="com.mycompany.service.impl.TimeManagerImpl" />
cxf-servlet.xml中
<jaxws:endpoint id="timeService" implementor="#timeManager" address="/TimeService"/>
2. 测试
访问http://localhost:8080/services,可得如下页面

访问http://localhost:8080/services/TimeService?wsdl,可以得到需要的WSDL供client使用

使用XMLSpy调用,测试接口

基于Appfuse的Web应用快速开发相关推荐

  1. openjweb1.8 java web应用快速开发平台产品白皮书

    因图片较多,需要图片请到资源中下载,不需要资源分.           OpenJWeb(1.8) Java Web应用快速开发平台   产品白皮书               编者:OpenJWeb ...

  2. OpenJWeb(1.6) Java Web应用快速开发平台技术白皮书

    OpenJWeb中国开源组织(http://blog.csdn.net/baozhengw) 苏州创智科技有限公司(http://www.cmissoft.com) QQ:29803446 Msn:b ...

  3. OpenJWeb2.61 Java Web应用快速开发平台全部开源公告

    OpenJWeb2.61版全部开源公告 OpenJWeb2.61版Java Web应用快速开发平台已向全社会开放所有源代码.OpenJWeb是国内商用级Java Web应用快速开发平台唯一全部开放源代 ...

  4. Web应用快速开发平台 WebBuilder 8.6 企业版发布

    WebBuilder是一款强大的企业级Web应用快速开发平台,使用WebBuilder可以快速开发出强大而高效的跨平台的常规应用和移动应用系统. WebBuilder官网:http://www.gee ...

  5. web系统快速开发_开发一个快速销售系统

    web系统快速开发 http://www.internationalnewsandviews.com/wp-content/uploads/2017/03/flash-sale-banner.png ...

  6. JEECG V3.0 版本(jbpm5 工作流自定义+WEB UI快速开发库+代码生成器) spring mvc +hibernate

    简要说明 JEECG V3.0版本推翻了原有SSH2架构,采用SpringMVC+Hibernate+Spring jdbc基础架构, 采用面向声明的开发模式,基于泛型方式编写极少代码即可实现复杂的数 ...

  7. Web前端快速开发 Bootstrap 响应式UI框架

    文章目录 前言 Bootstrap介绍 Bootstrap3 Bootstrap 响应式UI框架 使用 布局容器 栅格系统 响应式工具类 bootstrap4 bootstrap5 变化的内容 前言 ...

  8. 基于React和SpringBoot的快速开发模板QuickAdmin

    经过一段时间的总结和完善,我的管理系统快速开发模板已经基本成型,现在GitHub上开源啦: QuickAdmin QuickAdmin是基于Spring Boot和React.js实现的管理系统开发框 ...

  9. Jeecg-Boot 1.1 发布,基于 SpringBoot+Ant Design 的快速开发平台

    Jeecg-Boot 1.1 版本发布,初成长稳定版本 导读                                ⊙平台首页UI升级,精美的首页支持多模式                   ...

最新文章

  1. 破局:自动驾驶人才断层困境
  2. 五大风口产业全景手绘图(新能源汽车、人工智能等)
  3. 剪切粘贴时总是上次的内容_自学PS:拷贝与粘贴都有哪些方法?编辑信息时错误了怎样恢复?...
  4. DIV层+CSS实现锁屏
  5. Java之SPI机制
  6. node --- 创建一个Socket客户端连接到服务器
  7. Asp.Net Core Blazor之容器部署
  8. consulAPI服务的注册源码
  9. java负数用什么类型定义_(转) Java中的负数及基本类型的转型详解
  10. AD18的PCB开槽方法
  11. 用Java开发数独游戏,源程序与源代码全部开放
  12. java web象棋教程_【Java学习笔记】实战——网络象棋
  13. Ubuntu18.04 打不开系统蓝牙适配器,也连接不上任何蓝牙设备Bug解决方案
  14. Revit中如何绘制轴线?CAD图纸转轴网操作
  15. 两条命令彻底修复动态链接库
  16. c语言中字母与allse,六年级小学英语_所有字母组合的发音__(音标归类总结)
  17. 工信部首次发声:培育一批进军元宇宙等新兴领域的创新型中小企业
  18. 海康威视2019年校园招聘内推码(2019届春招、2020届实习/秋招)
  19. 【转】windows下使用netstat统计tcp、ip、端口的数量统计
  20. Echarts实现横轴数据节点不一致的绘制

热门文章

  1. [windows]修改本机host配置
  2. 【安全科普】揭秘IPS之网络攻击的“字典”
  3. 新车查询价格流量主小程序开发
  4. JSP基础教程:熟悉JSP服务器
  5. 爬取 bilibili 纪录片数据数据可视化
  6. Matlab实现——严格对角占优三对角方程组求解(高斯赛尔德Gauss-Seidel迭代、超松弛)
  7. 图神经网络 | (8)图注意力网络(GAT)
  8. 用Matlab绘彩色图像的直方图
  9. aix oracle汇文,oracle_FOR_AIX维护手册.doc
  10. 如何用计算机截部分屏,部分截图,教您电脑怎么局部截图