iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何分析简化的Java EE开发
  • 566
分享到

如何分析简化的Java EE开发

2023-06-17 21:06:40 566人浏览 安东尼
摘要

如何分析简化的Java EE开发,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java EE是个相当复杂的东西,被很多开发者们视为庞然大物。在下面的文章中,ja

如何分析简化的Java EE开发,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

Java EE是个相当复杂的东西,被很多开发者们视为庞然大物。在下面的文章中,javaonejcy探讨了如何简化Java EE开发中不必要的复杂,并给出一个不使用任何框架架构模型。

你可以说可爱的PHP ,可爱的ror ,可爱的python ,甚至可爱的.net ,但是Java EE ?他太复杂了。相比其他两种技术,Java EE 的技术体系更全面、更规整也更复杂,他的复杂性也让很多厂商望而止步,宁可选择简单甚至简陋的php ,这充分说明快速开发是这个时代最迫切的需求。

Java EE 的servlet 、javabean 、jdbc 规范给了我们组件和容器的唯一标准,而更高级的支持,jsf 、jdo 规范却没能给予我们唯一的框架级标准,他们被认可的程度远低于相同领域的开源框架。尽管开源社区给了我们最丰富的选择,但是相比.net 、php 、ror 的全栈式服务,Java EE 开发者必须DIY 。DIY 不但需要时间而且需要冒险,这种发烧友做的事情是企业所不愿意做的。一段时间以来,公司Java EE 方向的招聘几乎清一色的要求struts 、spring 、hibernate 这几种主流框架的能力就是一种证明。

Java EE 的开发往往避免不了配置之旅,尽管很多框架都有自动生成工具,但是,面对一个中型项目,仍然容易造成混乱。配置使你无论在开发、测试、集成还是维护的时都要配置代码两头看。配置给了框架一个注入服务的切入点,但是对人并无优雅可言。ror 给了我们启发,尽管企业开发是复杂的,但是大多数的需求都是通用的,事实证明,ror 把这部分通用性用约定的方式抽象得很好。其实Java EE 并不缺乏约定,因为他本身就是建立于一系列规范的基础之上,而规范就是约定。所以,Java EE 实际上有机会成为相对简洁的开发技术,只不过由于种种原因,这种规范并未出现。

在众多的Java EE 开发框架中,struts+spring+hibernate 有着黄金组合的美誉,用的人多,会的人多,就算是没出校门的学生,也知道学会ssh 的重要性。但是学会和学懂是两码事,对于一个中型项目,ssh 就成了一柄双刃剑,需要由高水平的设计师引路,才能披荆斩棘。spring+hibernate 给了设计者广阔的空间,而设计需要因项目的前进而演进,如果你的项目进度紧张,人手不足,设计质量就难以保障,给系统带来隐患。

“任何优秀的语言,都可以帮助开发者写出优秀的代码,但不能阻止开发者写出糟糕的代码”。在这一点上,无论是Java EE ,.net ,ror ,php 都不会例外。而开发框架就像是“一间有很多屋梁的房子”,“框架的强大之处不是他能让你做什么,而是他不能让你做什么”,其实如同语言一样,框架虽然可以给予开发一定程度的规范指导,但是这种指导仍然是有限的,这真应了那句老话:事在人为。

试图探讨如何简化Java EE 开发中不必要的复杂,并给出的是一个不使用任何框架的架构模型,让我们看看仅仅通过用编码约定,结构设计和使用方式的组合能不能满足项目开发的主要需求— 短期培训,降低隐患和快速开发。

问题的源头

应用软件开发是复杂的,但其基本模型至为简单,请求-处理-响应。对应于软件的层次结构就是:请求-Cortrol (C );处理-Model (M );响应-View (V )。在早期的Java EE 应用中,servlet 负责C ,javabean 和jdbc 在M ,jsp 是V 。这些就是Java EE 的基础设施,他们职责划分的方式被称为JSP Model2 ,已经可以满足WEB 开发的基本需要,Java EE 的开发始终都围绕着这几项主要技术,框架也不例外。以下的内容,将从这些技术的应用与不足说起,然后介绍主流框架的解决方案,之后再介绍我们不用框架的处理方式。

(C) 选择控制器

基础规范的不足

任何web 应用,处理请求之后返回响应是必须的环节,如果编码规范,传统的响应就是转向到某个页面,servlet 处理转向有两种方式,其中request 转向隐藏着重复提交的问题,response 重定向带来参数传递的编码解码的问题,同时众多的转向地址直接写在servlet 中也十分不雅,另外,jsp 和javabean 有一种出色的关联技术,就是在jsp 里可以把来自请求表单的数据自动拼装到javabean 中。糟糕的是,这么有用的技术却无法在servlet 中使用,所以Model2 缺乏对表单数据的自动转换处理。servlet 有这些不足很好理解,因为servlet 毕竟是较早出现的技术,他的职责只是将(Http )请求转化为面向对象的视图和输出响应而已,由于他是低阶组件,所以部分功能的缺失是正常的。不过这就让servlet 成为了Model2 最薄弱的一环。

开发框架的解决方案

由于以上需求是共性的,所以编写一个通用框架就成为了很多人努力的事情,struts 很快推出并且很快流行。我们先来看一看struts 的特性:

前端控制器: struts 使用一个servlet 作为前端控制器,所有请求先经过这里,再分派给配置指定的action (这里是指行为,而不是具体的Action ),意图是以一个中间层将视图层和控制层解耦,这种思路带来了三种可能的好处:1 视图和控制分离,所以可以选择不同的视图技术,比如视图模板既可以用jsp ,也可以用Volecity 、FreeMarker ;2 可以对所有请求预处理,和后处理(webwork );3 可以将响应的转向地址管理起来。前端控制器也存在一种直接的不足:配置繁琐。

ActionFORM : struts 主要是一个控制层框架,所以他并不意图深入到模型层,ActionForm 是一种无奈的选择,尽管提供了表单数据到javabean 的转换,但是遗憾的是这个javabean 并不能直接使用,还要手工的转换为模型javabean ,使得ActionForm 的位置有些尴尬。

国际化支持、标签库和全局异常: 国际化和标签库都是struts 的亮点,不过全局异常作用有限。

我们的选择

Java EE 的控制器必然是一个servlet ,我们也不能例外,因为我们必须要运行在servlet 容器之中。不过,我们选择的是servlet 的演进版本-jsp 。别误会,我们并不是要退回到JSP Model1 。一个典型的示例是,如果我有一个员工信息录入的功能点,那么为了实现这个功能,我可以建立下面两个文件:

worker_input.jsp

worker_inputOper.jsp

worker_input.jsp 里不写控制代码,worker_inuptOper.jsp 里也不写视图代码,这种用法实际是JSP Model1 和JSP Model2 的综合体。这样做最大的好处就是,免去配置的烦恼,但是等等.. 前端控制器呢?我们的中间层呢?

考虑一下,你有一个企业信息的表单,表单中有一个企业名称域,对这个域的要求是不能在已有企业中重名,域旁边有一个按钮,业务员可以通过点击这个按钮获得录入企业名称是否重复的提示。如果是传统方式,点击按钮将导致一个页面提交,如果用struts ,将要配置这个action 处理之后转向的URL 地址,这就是传统web 应用的响应方式- 基于URL 地址的页面导航。

web2.0 来了,ajax 来了,异步请求的出现彻底颠覆了传统的web 交互模型。对于ajax 应用而言,服务器端返回响应只需要out.print ,请求从哪来,回哪去,转向(如果需要)和更新视图的任务都交给了客户端脚本,也就是说,基于异步交互模式的web 应用,根本就没有需要配置的result URL 路径。这样,页面导航的问题就自动解决了。而对于预处理,我们可以用filter 替代。所以,我们完全可以和前端控制器说:再见。

由于客户端技术的趋势,在webappdemo 中我们将全面使用ajax 。也许你会说,如果客户端浏览器禁用脚本呢?这个担心在如今已经没有必要,你可以访问开心或者当当,看看禁用脚本他们能不能工作。时代在进步,富客户RIA 是必然的选择。

使用jsp 作为控制器,还使我们得到了另一个关键的特性,那就是从form 表单数据到javabean 的自动创建和输入,使javabean 本身既是模型也是DTO ,再也不必象ActionForm 那样还要手工转换。这里还有一个隐含的好处,就是强制统一了表单域名和模型属性名,不然,有可能出现这样的情况:表单域:child_center ;模型属性:branch 。以下是worker_inputOper.jsp 的写法:

Jsp代码

< jsp:useBean id="worker" class="webappdemo.worker.entity.Worker" scope="page"/>    < jsp:setProperty name="worker" property="*"/>        < %            response.setContentType("text/x-JSON;charset=UTF-8");        response.setHeader("Cache-Control", "no-cache");            String method = request.getParameter("method");            if("save".equals(method)){            EntityService es = new EntityService();            Message m = es.add(worker);            out.print(new JSONObject().put(m.isSucceed()?"succeed":"error", m.getMessage()));            return;        }        %>

可以看出,只需将实体类名引入标签,我们就可以获得自动拼装的Worker 对象。对于复杂对象或复合对象,由于request 里同样有我们需要的所有请求参数,所以你可以在自动创建的javabean 基础上修改部分属性,以符合业务需要。

代码还展示了基于“method ”的用法,这只是一个字符串,用来告诉oper jsp 要用哪个方法来处理请求,这类似于ror 控制器内部定义的方法以及struts 的DispatchAction 但比他更灵活,变通的解决了jsp 的请求不能直接面向方法的不足。

在调用服务处理请求之后,worker_inputOper.jsp 将处理结果out.print 回客户端,这句代码的意思是新建一个JSON 对象,将处理结果添加进去,然后输出这个对象,方便客户端js 脚本解析。JSON 对象可以增加多个处理结果,只要他们的key 不同就可以。在实际应用中,往往返回处理消息,或者html 视图的字符串。最后别忘了return; 否则程序仍然会向下进行。

如果你的项目需要国际化,我们可以使用fmt 标签,而对于反馈消息的国际化,我们也许就需要建立一个全局MessageSource 对象了,这个问题在webappdemo 中没有涉及,因为笔者认为这不是普遍需求。

对于异常处理,其实jsp 已经提供了简单的机制,我们可以在web.xml 中配置:

Xml代码

< error-page>        < error-code>404< /error-code>        < location>/404.jsp< /location>    < /error-page>    < error-page>        < error-code>500< /error-code>        < location>/500.jsp< /location>    < /error-page>

这种简单的处理其实正是我们需要的全部,因为笔者认为,web 应用的系统错误和java 的异常没有区别,即检测错误和运行时错误。在web2.0 时代,所有的错误都应该被捕获,并且把内容经处理后在用户输入位置反馈给用户,而不应该重新定向。运行时错误属于系统bug ,是需要修复的代码级错误,这种错误是真正的“意外”,所以我们用定制的错误页面反馈给用户就可以了。

综上所述,我们用ajax+jsp+ 控制jsp 的方式代替了servlet 或者action ,摆脱了前端控制器,用模型javabean 代替了过程javabean ActionForm ,这些使用方式使我们不需要配置即可以开发应用程序,除了ajax 是相对新概念外不需要额外学习框架技术也是他的优点。

(M)ORM 可以做什么

基础规范的不足

jdbc 是java 应用程序数据持久化的基础,也是众多数据库厂商与java 的接口。直接使用jdbc 编写代码非常繁琐,比如数据库资源的获得和释放,异常捕获和事务处理等等,重复代码多是他的一个特点。另外,不同的数据库,在数据类型,主键类型还是sql 语句都和SQL 标准小有出入,所以如何使应用程序可以在不同数据库平台方便的迁移,也是个问题。

开发框架的解决方案

spring 和hibernate 的出现使情况大为好转,spring 面向切面管理事务, hibernate 自动ORM 可以大大简化开发,spring 和hibernate 都有.net 的版本,这证明了他们的成功。但是“用好hibernate ,需要扎实的掌握关系模型和SQL ”,同时对面向对象设计和hibernate 自身的运行机制也要有非常清晰的认识,只有这种水平才能发挥hibernate 的威力,降低hibernate 带来的风险。所以,在合适的层面上配置好spring 的事务管理,设计好对象模型,把对hibernate 的直接使用控制在一定范围内是设计者要解决的基本问题。如果设计不佳,或者直接交给初出校门的开发者去用,那这种组合就会变成洪水猛兽,同时也不利于团队成员的成长。

我们的选择

如果只有jdbc ,我们的系统也可以工作,只不过要写很多重复和机械的代码,通过框架的ORM 的映射,可以将数据库表的数据自动填入javabean ,这节省了劳动力,也使系统结构自然清晰。如果不用ORM 工具,我们能不能通过某种形式来模拟他的行为呢?我们可以创建这样一个接口:

Java代码

public interface IOper {            boolean load(Connection connect) throws SQLException;            boolean add(Connection connect) throws SQLException;            boolean update(Connection connect) throws SQLException;            boolean delete(Connection connect) throws SQLException;        }

在接口中定义 CRUD 方法。返回类型为 boolean 而非影响的行数,意图是对象内部的操作可能是复杂的多步骤的,所以对他的上层应用来说,知道结果成功与否就可以了。接下来在他的实现类里可以这么写:

Java代码

public class Worker implements IOper {            // Fields        private Integer workerId;            private String workerName;            private String loGonName;            private String logonPwd;                    private String mobile = "";            private String email = "";            private String remark = "";            private String isFreeze = "0";            // Constructors                        // Property accessors             public boolean add(Connection connect) throws SQLException {            SQLBuffer sql = new SQLBuffer();            sql.segment("insert into worker (worker_name,logon_name,logon_pwd,");            sql.segment("mobile,email,remark,is_freeze) values (");            sql.value(this.workerName);            sql.comma();            sql.value(this.logonName);            sql.comma();            sql.value(this.logonPwd);            sql.comma();            sql.value(this.mobile);            sql.comma();            sql.value(this.email);            sql.comma();            sql.value(this.remark);            sql.comma();            sql.value(this.isFreeze);            sql.segment(")");            return Proxy.update(connect, sql) == 1;        }            public boolean delete(Connection connect) throws SQLException {            // 冻结用户            SQLBuffer sql = new SQLBuffer();            sql.segment("update worker set is_isfreeze = ");            this.isFreeze = "1";            sql.value(this.isFreeze);            sql.segment(" where worker_id = ");            sql.value(this.workerId);            return Proxy.update(connect, sql) == 1;        }            public boolean load(Connection connect) throws SQLException {            SQLBuffer sql = new SQLBuffer(                    "select worker_name,logon_name,logon_pwd,mobile,email,remark,is_freeze from worker");            sql.segment(" where worker_id = ");            sql.value(this.workerId);            MapRow mr = Proxy.getMapRow(connect, sql);            if (mr == null) {                return false;            }            this.workerName = mr.getString("worker_name");            this.logonName = mr.getString("logon_name");            this.logonPwd = mr.getString("logon_pwd");            this.mobile = mr.getString("mobile");            this.email = mr.getString("email");            this.remark = mr.getString("remark");            this.isFreeze = mr.getString("is_freeze");            return true;        }            public boolean update(Connection connect) throws SQLException {            SQLBuffer sql = new SQLBuffer();            sql.segment("update worker set worker_name = ");            sql.value(this.workerName);            sql.segment(", logon_name = ");            sql.value(this.logonName);            sql.segment(", logon_pwd = ");            sql.value(this.logonPwd);            sql.segment(", mobile = ");            sql.value(this.mobile);            sql.segment(", email = ");            sql.value(this.email);            sql.segment(", remark = ");            sql.value(this.remark);            sql.segment(", is_freeze = ");            sql.value(this.isFreeze);            sql.segment(" where worker_id = ");            sql.value(this.workerId);            return Proxy.update(connect, sql) == 1;        }    }

实体 javabean 通过实现 IOper 接口,负责对自身数据的操作。尽管这种实现方式等于是使模型成为了富血模型,但其实我们仍然可以把这种模型认为是贫血的,因为他没有业务逻辑,只是模拟了 ORM 的行为。 如果对象关系有包含和聚合,我们同样也可以通过类似 hibernate 的行为方式来实现,比如懒加载。以上的代码使用了笔者所用的 api ,由于操作都在内部,所以换成直接用 jdbc 也是一样的。在实际应用中, load 方法有些单薄,因为有的查询需要一些附加条件,我们可以通过增加一个类属性来达到这个目的:

String condition;

如果设置了条件,我们就拼接给定的查询条件取得结果,不过结果只能是一条,这是模型结构所决定的。另外Connection 对象是每个方法的必须的参数,意图是在实际业务操作中,单一的操作往往是不存在的,所以,总是由外部传递资源和释放资源。但是,在每个调用的地方都要写重复的try catch 以及获得和释放 连接的代码岂不是很无聊?那么,我们可以用一个服务类包装他,这就体现了IOper 接口的用处了:

Java代码

public class EntityService {            public Message add(IOper io) {                try {                Connection connect = Proxy.getConnect();                connect.setAutoCommit(false);                    // 增加                if (!io.add(connect)) {                    throw new Exception("增加操作失败");                }                    // 其他操作                    connect.commit();                return new Message(true);                } catch (Exception e) {                Proxy.rollbackConnect();                e.printStackTrace();                return new Message(e);            } finally {                Proxy.closeConnect();            }            }            public Message update(IOper io) {                try {                Connection connect = Proxy.getConnect();                connect.setAutoCommit(false);                    // 修改                if (!io.update(connect)) {                    throw new Exception("修改操作失败");                }                    // 其他操作                    connect.commit();                return new Message(true);                } catch (Exception e) {                Proxy.rollbackConnect();                e.printStackTrace();                return new Message(e);            } finally {                Proxy.closeConnect();            }        }            public Message delete(IOper io) {                try {                Connection connect = Proxy.getConnect();                connect.setAutoCommit(false);                    // 删除                if (!io.delete(connect)) {                    throw new Exception("删除操作失败");                }                    // 其他操作                    connect.commit();                return new Message(true);                } catch (Exception e) {                Proxy.rollbackConnect();                e.printStackTrace();                return new Message(e);            } finally {                Proxy.closeConnect();            }        }            public Message load(IOper io) {                try {                Connection connect = Proxy.getConnect();                connect.setAutoCommit(false);                    // 载入                if (!io.load(connect)) {                    throw new Exception("载入操作失败");                }                    // 其他操作                connect.commit();                return new Message(true);                } catch (Exception e) {                Proxy.rollbackConnect();                e.printStackTrace();                return new Message(e);            } finally {                Proxy.closeConnect();            }        }    }

从EntityService 的代码中看到,try catch 应该总是出现在服务层,只有一个独立的服务才有必要保证一个完整的事务。如果你要在CUD 操作后记录业务日志,那么你可以写在“其他操作”的位置。由于对外界信息的依赖,比如用户信息,功能ID 等等,在实际应用中需要更复杂的设计。至此,我们完成了对ORM 行为的模拟,在调用的地方,我们只需要:

Java代码

EntityService es = new EntityService();    Message m = es.add(worker);

尽管方法内部的代码仍然是繁琐的,但是我们由于把这些代码的位置聚焦于较少的地方而降低了繁琐程度,同时也获得了良好的结构。对数据库的操作更为直观是“手写”代码的优点,当然,我们还可以选择ibatis ,不过结构就不会是这样的了。同时笔者认为sql 代码总是和程序内部息息相关,配置在外部看起来并不一定方便吧。

对于数据库迁移问题,hibernate 很大程度的解决了这个问题,不过企业开发中迁移数据的需求并不多,而且数据库迁移不是使用某个工具或者规范(jdbc ,jdo )就可以完全解决的,对于大型复杂应用,迁移数据库需要付出巨大的努力,所以实际上也没有人这么做。

(V) 客户端MVC

关于客户端应用的说明没有内部分段,因为Java EE 技术(暂不谈javafx )本身就和客户端没有太大关系,所以也不存在不足的问题,这里只是意图纠正一些系统中不良的编码习惯。

jsf 是Java EE UI 框架规范,前端控制器、事件模型和UI 组件是他的主要组成部分,但是实际开发中jsf 标签非常繁琐,并且只有客户端明确禁用脚本或者其他组件(flex-flash ,javafx 甚至silverlight )时,jsf 才是最有价值的,糟糕(幸运)的是目前几乎没有客户端浏览器不支持以上脚本或插件,所以jsf 的价值大大降低了。

jsp 是Java EE 视图组件,也是jsf UI 框架的基础之一,他实际上就是一个环境宽松的视图模板,尽管这种宽松貌似不利于软件分层,但是比起其他模板技术,他至少有一个优点,就是非常象asp ,这使他更容易为开发者所接受。在web2.0 的时代,如果你的项目不打算用flex-flash 或者javafx ,那么jsp 就是你最佳的视图载体,你可以把javacript 、CSS 、html 、xml 、json 还有java 代码都放在这里,为了实现ajax 的交互逻辑,你可能要写大段的javascript ,没关系,jsp 都能承受,尽管,这些东西放在一起看上去就像是一个老鼠窝。

Ajax in action 的作者提出了客户端mvc 的概念,不过别误会,这并不是ext 或者flex 的开发模式,而只是一种观念。html 是由dom 树建立的视图结构,所以是M ,css 给html 结构添加效果,所以是V ,javascript 控制显示逻辑,所是C ,这里指的客户端MVC 就是把这三种语言代码分别建立单独的文件,在html 页面中引用外部的css 和js 。同样拿员工信息录入举例,我们可以建立如下几个文件:

worker_input.jsp

worker_inptu.js

style.css

可以看到,css 文件我们并没有用功能方式命名,因为样式表往往可以被整个系统共用,也就是说,我们只要记得不在html 里写css ,js 代码,并单独建立js 文件就可以了。不同种类代码分开建立文件是提高代码可读性的关键步骤,尤其是在客户端程序愈发复杂的今天。worker_input.js 是这样写的:

Js代码

// 保存    function save(){        if(check()){            AjaxUtil.sendForm(document.forms[0], "method=save", function () {                if (this.result.succeed) {                    document.forms[0].reset();                    messageapp.printMessage(this.result.succeed);                } else if (this.result.error) {                    messageapp.printMessage(this.result.error);                }            }, true);        }    }

这个文件只定义了一个save 方法,这个方法内部发起了ajax 方式的异步请求,如果返回成功,则重置表单,并更新输出信息到指定位置,反之则仅更新输出信息。你会注意到,我们返回的JSON 对象起到了作用。

问题:如果我的jsp 代码里出现了这样的情况,算是违背客户端MVC 的原则吗?

Html代码

< tr>    < td colspan="2">    < input type="button" value="保    存" onclick="save();"/>                      < input type="reset" value="重    置" />                          < input type="button" value="返    回" onclick="window.history.go(-1);" />        < /td>    < /tr>

以上代码片段中有简短的 js 代码和方法引用,这种情况,笔者认为是可以的,项目开发没必要追去绝对的完美,只要达到结构清晰的目的就行了,我们要的是高质量的产品,而不是高质量的理论。

问题:如果我使用了类似 ror 的 JavaScriptHelper 那样的脚本标签库,生成的脚本与 html 代码混在一起,这样算不算违背客户端 MVC 原则呢?很显然,也不算,因为对于输出前的 jsp 代码模板,程序结构是清晰的。

(F) 结构和细节

关于MVC 各部分的介绍,再让我们来看看整体结构,假设我们是在一个eclipse 工程中,打开WebRoot 目录,如果忽略META-INF 和WEB-INF 目录的话,我们的示例目录是这样的:

module

404.jsp

500.jsp

index.htm

其中module 就是我们应用所有的视图,由于我们对于jsp 的使用方式,还包括所有的控制器。将应用程序都放在一个目录下是为了方便今后使用filter 对目录进行保护,或者进行某些其他预处理。打开module 目录,展现的结构是这样的:

common  worker

一个common 目录,存放所有共用程序文件,一个worker 目录存放关于员工这个实体的功能文件。实际上你的结构也可能是sys/worker 或者center/sys/worker 等等,就要看实际的应用需求了,总之,通过目录划分功能模块,以正确的树形结构描述他是没错的。我们再来打开common 目录:

css  img  js  import_page.def

前三个目录分别存放的是常用文件,而最后一个是文件,这个文件将用这种方式添加到每个视图jsp 头,在< head>< /head> 间加入:

Jsp代码

< %@ include file=”../common/import_page.def”%>

这里使用了相对路径,增加这个文件是为了方便的引用其他css 和js 库文件。使用这种方式可以避免在部署的阶段因合并js 或进行css 、js 库文件的版本变更而带来的麻烦。

再来看看java src 的目录结构:

webappdeom      common      worker  datasource.xml  log4j.properties

除了根目录,与WebRoot 下的结构是一致的。两个文件:datasource.xml 是数据源配置文件,也是笔者demo 中使用的API 所需要的,log4j.properties 是log4j 的属性文件。另外,系统默认使用hsql 数据库,如果要正常启动,需要改动web.xml 中的一个配置项,具体位置有注释说明。

再具体的结构和代码这里就不多讲了,如果感兴趣,可以下载webappdemo 看看,里面的注释比较完整。不过在demo 里还有一些隐藏问题,以及可以扩展的思路,不知道你能不能找出来。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程网精选频道,感谢您对编程网的支持。

--结束END--

本文标题: 如何分析简化的Java EE开发

本文链接: https://www.lsjlt.com/news/292936.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何分析简化的Java EE开发
    如何分析简化的Java EE开发,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java EE是个相当复杂的东西,被很多开发者们视为庞然大物。在下面的文章中,ja...
    99+
    2023-06-17
  • Java EE开发四大常用框架分别是什么
    这篇文章主要为大家分析了Java EE开发四大常用框架分别是什么的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习“Java EE开发四大常用框架分别是什么”的知...
    99+
    2023-06-03
  • 如何进行Java和Python的Web开发分析
    今天就跟大家聊聊有关如何进行Java和Python的Web开发分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在Java里面有一种服务端的软件组件技术,叫做Servlet,其实它的...
    99+
    2023-06-04
  • 如何使用jQuery简化Ajax开发
    这篇文章主要为大家展示了“如何使用jQuery简化Ajax开发”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用jQuery简化Ajax开发”这篇文章吧。j...
    99+
    2024-04-02
  • 如何优化PHP开发中的性能监控和分析
    概述:在PHP开发过程中,性能监控和分析是非常重要的,它可以帮助我们发现代码中的瓶颈,从而进行针对性的优化,提高系统的响应速度和运行效率。本文将介绍如何使用一些常见的性能监控工具和技术,以及如何应用具体的代码示例进行优化。一、使用PHP的内...
    99+
    2023-10-21
    性能分析 性能监控 优化PHP开发
  • 如何分析Python自动化运维开发中的变量
    本篇文章给大家分享的是有关如何分析Python自动化运维开发中的变量,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。好程序员分享Python自动化运维开发实战四-变量导语:1.什...
    99+
    2023-06-04
  • Python如何简化区块链应用的开发?
    1. 简化的合约开发 Python提供了合约开发框架,例如Web3.py和Truffle,使开发人员能够轻松创建和部署智能合约。这些框架通过抽象底层复杂性,使用户可以专注于合约逻辑。Python的简洁语法和可读性也使编写和维护智能合约变得...
    99+
    2024-03-13
    Python与区块链
  • Java低代码开发简化软件开发流程的利器
    Java作为一种流行的编程语言,已经成为许多企业和组织开发软件的重要工具之一。然而,传统的Java开发模式需要大量的代码编写和调试,这不仅耗时费力,而且还容易出现错误和漏洞。为了解决这些问题,一种新的开发方式——Java低代码开发应运而生...
    99+
    2024-01-21
    利器 流程 代码
  • java多线程开发ScheduledExecutorService简化方式
    目录前言java多线程的应用场景应用场景一:应用场景二:ScheduledExecutorService方法简介实例实例结果 前言 java开发,多多少少会接触到多线程的应用开发场景...
    99+
    2024-04-02
  • 如何解决Java EE的乱码问题
    今天就跟大家聊聊有关如何解决Java EE的乱码问题,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。51CTO曾经给大家介绍过很多乱码的问题,如“深度剖析Python 中文乱码说明”、...
    99+
    2023-06-17
  • 详解如何使用MyBatis简化JDBC开发
    目录1. 前言2. JDBC 存在的缺点3. MyBatis 优化4. MyBatis 快速入门5. 总结1. 前言 JavaEE 企业级 Java 项目中的经典三层架构为表现层,业...
    99+
    2023-01-29
    MyBatis简化JDBC开发 MyBatis简化JDBC MyBatis JDBC
  • Node.js的模块化开发实例分析
    这篇文章主要讲解了“Node.js的模块化开发实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Node.js的模块化开发实例分析”吧!1.Node.j...
    99+
    2024-04-02
  • 分析web前端模块化开发
    这篇文章主要介绍“分析web前端模块化开发”,在日常操作中,相信很多人在分析web前端模块化开发问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”分析web前端模块化开发”的疑惑...
    99+
    2024-04-02
  • 如何分析VSTS 2010可管理虚拟化开发环境
    今天就跟大家聊聊有关如何分析VSTS 2010可管理虚拟化开发环境,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在VSTS 2010中,微软增加了虚拟化技术的客户端机制Test an...
    99+
    2023-06-17
  • 组件化的前端开发流程分析
    这篇文章将为大家详细讲解有关组件化的前端开发流程分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。背景 做前端的同学都知道,做的页面多了,东西就会乱,因此我们需要统一一个开发流程。开发流程的好坏,直接影响...
    99+
    2023-06-08
  • PHP 函数的新特性如何简化开发过程?
    php 函数的新特性极大地简化了开发流程,包括:箭头函数:提供简洁的匿名函数语法,减少代码冗余。属性类型声明:为类属性指定类型,增强代码可读性和可靠性,并在运行时自动进行类型检查。nul...
    99+
    2024-05-04
    开发 php 代码可读性
  • 为什么Java开发人员应该考虑使用容器?NPM如何简化开发流程?
    随着互联网的快速发展,软件开发也越来越迅猛。Java作为一种广泛使用的编程语言,开发人员们需要不断地适应新的技术和工具。其中,容器和NPM是两个非常流行的工具,它们可以极大地简化Java开发的流程,提高开发人员的效率和代码的质量。 一、为...
    99+
    2023-10-02
    ide npm 容器
  • 简化Django开发的八个Python包分别是哪些
    简化Django开发的八个Python包分别是哪些,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。这个月的 Python 专栏将介绍一些 Django 包,它们有...
    99+
    2023-06-17
  • 如何使用 PHP 函数库简化开发任务?
    php 函数库提供了预定义的函数,简化开发任务,包括:字符串操作(如替换)数组操作(如合并)日期处理(如获取当前日期时间)文件操作(如读取文件内容)其他函数(如检查变量是否已设置)这些函...
    99+
    2024-04-27
    开发任务 php 函数库 composer
  • 如何分析Java的Fork/Join并发框架
    这篇文章将为大家详细讲解有关如何分析Java的Fork/Join并发框架,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。今天我就把自己对Fork/Join一些浅显的理解记录下来。1. Fork...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作