【Java EE 学习第58-67天】【OA项目练习】【JBPM工作流的使用】

OA项目中有极大可能性使用到JBPM框架解决流程控制问题,比如请假流程、报销流程等等。

JBPM:JBoss Business Process Management,翻译过来就是业务流程管理。实际上就是一个java 框架。

学习JBPM最重要的就是学习数据库中的18张表,只要熟练掌握了这18张表,学习JBPM就大功告成了。

一、JBPM框架搭建

  1.到JBPM官方网站上下载需要的jar包、源代码、文档等等

      http://www.jbpm.org/

    比较流行的JBPM版本是JBPM4.4,本次使用该版本的JBPM为例。

      下载地址:http://sourceforge.net/projects/jbpm/files/jBPM%204/jbpm-4.4/

  2.暂时不整合SSH框架,但是实际上JBPM底层使用的是Hibernate,这点是需要特别注意的(不想注意也不行,学习JBPM必须能够熟练操作Hibernate)。

  3.下载jbpm4.4之后,解压文件,将/lib文件夹中的所有jar包和根目录下的jbpm.jar核心包都拷贝到/WEB-INF/lib文件夹中。

  4.使用到的三种配置文件

    (1)jbpm.cfg.xml,配置文件样例:

<?xml version="1.0" encoding="UTF-8"?>

<jbpm-configuration>

  <import resource="jbpm.default.cfg.xml" />
  <import resource="jbpm.businesscalendar.cfg.xml" />
  <import resource="jbpm.tx.hibernate.cfg.xml" />
  <import resource="jbpm.jpdl.cfg.xml" />
  <import resource="jbpm.bpmn.cfg.xml" />
  <import resource="jbpm.identity.cfg.xml" />

  <!-- Job executor is excluded for running the example test cases. -->
  <!-- To enable timers and messages in production use, this should be included. -->
  <!--
  <import resource="jbpm.jobexecutor.cfg.xml" />
  -->

</jbpm-configuration>

jbpm.cfg.xml

    (2)jbpm.hibernate.cfg.xml,该文件实际上就是hibernate.cfg.xml配置文件,可以将hibernate.cfg.xml配置文件中的内容和该文件整合到一起。配置文件样例:

 1 <?xml version="1.0" encoding="utf-8"?>
 2
 3 <!DOCTYPE hibernate-configuration PUBLIC
 4           "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 5           "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 6
 7 <hibernate-configuration>
 8   <session-factory>
 9       <!--
10           MySQLInnoDBDialect方式不能自动建表(忽略外键约束?)
11           MySQLDialect方式能够自动建表,但是在手动结束流程实例的时候会报错(外键约束不能删除)
12           使用MySQL5InnoDBDialect解决两方面的难题。
13        -->
14      <property name="dialect">
15         <!-- org.hibernate.dialect.MySQLDialect -->
16         org.hibernate.dialect.MySQL5InnoDBDialect
17     </property>
18     <property name="connection.url">
19         jdbc:mysql://localhost:3306/jbpm
20     </property>
21     <property name="connection.username">root</property>
22     <property name="connection.password">5a6f38</property>
23     <property name="connection.driver_class">
24         com.mysql.jdbc.Driver
25     </property>
26     <property name="myeclipse.connection.profile">mysql</property>
27     <property name="show_sql">true</property>
28     <property name="hbm2ddl.auto">update</property>
29
30      <mapping resource="jbpm.repository.hbm.xml" />
31      <mapping resource="jbpm.execution.hbm.xml" />
32      <mapping resource="jbpm.history.hbm.xml" />
33      <mapping resource="jbpm.task.hbm.xml" />
34      <mapping resource="jbpm.identity.hbm.xml" />
35
36   </session-factory>
37 </hibernate-configuration>

jbpm.hibernate.cfg.xml

      我使用的MySQL版本是5.5,不支持使用MySQLInnoDBDialect方言自动建表(5.1以及以下版本可以),使用MySQLDialect方言能够实现自动建表,但是在结束流程实例的时候会报错。

      解决这个问题的关键就是使用MySQL5InnoDBDialect,使用该方言就能够实现既能够自动建表,也能够正常结束流程实例了。

    (3)logging.properties配置文件,该配置文件是针对log4j的配置文件,使用该配置文件能够精确控制输出日志信息,以方便查看详细的工作流程。

 1 handlers= java.util.logging.ConsoleHandler
 2 redirect.commons.logging = enabled
 3
 4 java.util.logging.ConsoleHandler.level = FINEST
 5 java.util.logging.ConsoleHandler.formatter = org.jbpm.internal.log.LogFormatter
 6
 7 org.jbpm.level=FINE
 8 # org.jbpm.pvm.internal.tx.level=FINE
 9 # org.jbpm.pvm.internal.wire.level=FINE
10 # org.jbpm.pvm.internal.util.level=FINE
11
12 org.hibernate.level=INFO
13 org.hibernate.cfg.SettingsFactory.level=SEVERE
14 org.hibernate.cfg.HbmBinder.level=SEVERE
15 org.hibernate.SQL.level=FINEST
16 org.hibernate.type.level=FINEST
17 # org.hibernate.tool.hbm2ddl.SchemaExport.level=FINEST
18 # org.hibernate.transaction.level=FINEST

logging.properties

    这三种配置文件最好都放置到classpath路径下,这样方便程序处理。

  5.至此,程序框架已经搭建完毕,下一步就是学习JBPM API了。

二、JBPM插件安装

  1.学习JBPM必须首先安装好JBPM插件,这样才能制作流程图以及部署流程。

  2.首先到下载好的jbpm4.4项目工程路径下的/install/src/gpd文件夹下找到jbpm-gpd-site.zip文件,然后使用该文件安装好插件

  3.安装插件的时候可能会出现的问题:

    我使用的版本是MyEclipse10,使用该版本的MyEclipse我没有找到Help0->install software菜单项,解决办法:

    http://kuangdaoyizhimei.blog.163.com/blog/static/220557211201510138346395/

  4.安装好插件之后在文件夹下右键new->JBPM 4 Process Definition即可,下面一张请假流程示例图

    

三、流程部署

  1.画最简单的一张请假流程图如上图所示(没有申请环节?不要在意这些细节)。

    首先,在空白处单击一下,然后在properties视图中修改流程名称,但是Key、Version、Description字段就不要填写了。特别是Description,写上之后就会报错,部署也不会成功,如果想要写Description的话,需要切换到XML视图,在Process根节点下添加<description></description>节点。没有properties视图的解决方法:百度。

    

    给每个任务节点添加执行人的方法:单击任务节点,在properties视图中修改

    

  2.添加完成之后一旦ctrl+s保存,就会生成一张.png图片,在查看流程图的时候一定会使用到该图片。

  3.三种流程部署的方法

    (1)classpath的方式部署

ProcessEngine processEngine=Configuration.getProcessEngine();
        RepositoryService repositoryService=processEngine.getRepositoryService();
        NewDeployment newDeployment = repositoryService.createDeployment();
        newDeployment = newDeployment.addResourceFromClasspath("qingjia.jpdl.xml");
        newDeployment = newDeployment.addResourceFromClasspath("qingjia.png");
        String deploymentId=newDeployment.deploy();
        System.out.println(deploymentId);

    (2)InputStream的方式部署(比(1)方式还麻烦)

InputStream xml=this.getClass().getClassLoader().getResourceAsStream("qingjia.jpdl.xml");
        InputStream png=this.getClass().getClassLoader().getResourceAsStream("qingjia.png");
        Configuration.getProcessEngine()
        .getRepositoryService()
        .createDeployment()
        .addResourceFromInputStream("qingjia.jpdl.xml", xml)
        .addResourceFromInputStream("qingjia.png", png)
        .deploy();

    (3)ZipInputStream的方式部署(最简单的方式,使用该种凡是需要将name.jpdl.xml和name.png打包成zip文件)

InputStream is=this.getClass().getClassLoader().getResourceAsStream("qingjia.zip");
        ZipInputStream zipInputStream = new ZipInputStream(is);
        Configuration.getProcessEngine()
        .getRepositoryService()
        .createDeployment()
        .addResourcesFromZipInputStream(zipInputStream)
        .deploy();

  4.流程部署之后,会自动生成18张表

    

  流程部署影响到的表有:jbpm4_deployment、jbpm4_deployprop、jbpm4_lob、jbpm4_property四张表

    (1)jbpm4_deployment,每部署一个流程,该表都会添加一行数据,类似于流程定义一样,但实际上是不同流程定义的不同版本。

    

    DBID_代表主键,没有什么特别的含义,起到唯一标识的作用。需要注意的只有这一个字段,标志了流程定义的ID。

    注意,同一种流程可能会有不通过的版本,每一个版本都会在这张表中有相对应的一行记录。

    (2)jbpm4_deployprop,流程部署表,每部署一次,都会在这张表中添加四行新数据

    

    同样的DBID_也是主键,没有特别的含义,只是起到标识作用。

    DEPLOYMENT_是引用了jbpm4_deployment表DBID_的外键,这里都是1,表示是1这种类型的流程部署

    OBJNAME_是流程部署的名字,一般和KEY_字段的pdkey字段相同,除非特别的做了定义。

    KEY_,该字段是最重要的一个字段,四行数据的区分正是由该字段决定的。

      *  langid:流程定义语言字段,这里是jpdl-4.4表示使用的是jpdl-4.4版本的流程定义语言。

      *  pdid:流程部署标识ID,标识着本次部署,这是非常重要的字段。

      *  pdkey:流程定义标识ID,这里是qingjia,表示该字符串唯一标识了该种流程,实际上就是流程定义的名字。每一次新的部署中该值都会不同。

      *  pdversion:流程部署版本。

    (3)容易混淆的事项说明

      这张表是18张表中最核心的表之一。KEY_字段中的各个属性值之间的关系:

      每一次新的部署都会生成一个唯一的pdkey,version的值初始化成1,同时pdid的值就变成了pdkey-version,如果下一次不是新的部署,而是有着相同pdkey的部署,则本次部署的version值就会增加,同时pdid的值就会相应的变成pdkey-version形式的值。

      综上所述,每一次新的部署都会生成新的pdkey,如果是有相同的pdkey,则视为不同版本的流程定义,则版本号就会相应的增加,pdkey标志着唯一的流程定义,pdid唯一标志了相同流程定义下的不同版本。

    (4)jbpm4_lob,该表是存放数据的表,如果部署的时候使用了同时使用了xml配置文件和png图片文件,则这里就会相应的增加两行数据,分别代表着部署的xml配置文件和对应的png图片。

      该表每一次部署中都会增加一行或者两行新的数据。必不可少的是XML的配置文件所对应的行。

      字段DEPLOYMENT_是引用了jbpm4_deployment表的DBID_字段的外键。

  5.流程一旦部署完毕,就意味着至少已经有了一种流程定义极其下的至少一种流程定义版本。

四、流程定义(流程部署)管理

  无论是流程部署还是流程查询,有一个核心的接口:ProcessEngine,一切的一切都从该接口出发肯定没错。

  1.查询流程部署

    (1)查询所有流程部署

List<Deployment> deploymentList=processEngine.getRepositoryService().createDeploymentQuery().list();

    查询的表是jbpm4_deployment,通过该查询能够实现查找所有流程定义(不同类型流程定义的不同版本),使用Deployment接口的getId可以得到该流程定义的标识ID。注意getRepositoryService()方法。

    (2)根据部署id查询部署,该id是jbpm4_deployment的PDID_字段的值

Deployment deployment=processEngine
        .getRepositoryService()
        .createDeploymentQuery()
        .deploymentId("1")
        .uniqueResult();

  2.查询流程定义

    (1)查询所有流程定义

List<ProcessDefinition> processDefinitionlist=
        processEngine.getRepositoryService()
        .createProcessDefinitionQuery()
        .list();

    (2)根据部署id查询流程定义

ProcessDefinition processDefinition=processEngine.getRepositoryService()
        .createProcessDefinitionQuery()
        .deploymentId("1")
        .uniqueResult();

  3.查询流程定义和查询流程部署之间的区别

    一个流程定义可以有多个流程部署,但是一个流程部署只能属于一个流程定义,流程定义和流程部署之间是一对多的关系。

    在jbpm4_deployprop表中的KEY_字段的pdkey值唯一的标识了一种流程定义,查询流程定义查询的就是jbpm4_deployprop表。

  4.根据pdkey查询流程定义

List<ProcessDefinition> processDefinitions=processEngine.getRepositoryService()
        .createProcessDefinitionQuery()
        .processDefinitionKey("qingjia")
        .list();

    能够想象的出,如果一种流程定义部署了多次,那么通过pdkey查询出来的流程定义一定是多种流程定义。

  5.流程定义和流程部署之间的关系

    流程定义实际上就是流程类型+版本号,每一种流程定义都对应着一次流程部署。部署的过程也就是定义的过程。

  6.删除流程部署

processEngine.getRepositoryService().deleteDeploymentCascade("20001");

    删除流程部署的时候需要提供一个部署id,该id实际上就是jbpm4_deployment表中的DBID_字段的值。

  *  疑问:有没有删除流程定义的方法?实际上删除流程部署的同时,也就是删除了流程定义了,所以只需要提供一种方法就行了。这是个人理解。

  7.获取流程图的方法,每一种流程定义(流程部署)都会有相应的流程图,怎么获取该流程图呢?

processEngine.getRepositoryService().getResourceAsStream(deploymentId, resourceName);

五、流程实例-任务

  任务节点是流程图中最重要的一种节点类型,它代表了一种需要处理的任务。它有节点名称、处理人的属性。

  实际上对任务的执行动作是推动流程前进的动力。

  1.启动流程实例

    (1)根据pdid启动流程实例:根据pdid启动流程实例实际上就是指定了一种类型(具体到版本)的流程定义,如qingjia-1,指的是qingjia流程定义的第一种版本的定义。

ProcessInstance pi=processEngine.getExecutionService()
        .startProcessInstanceById("qingjia-1");

    (2)根据pdkey启动流程实例:根据pdkey启动流程实例并不会具体到版本,所以默认采用了最高版本的流程定义,如存在qingjia-1、qingjia-2两种流程定义,那么使用qingjia的pdkey启动流程的时候,就会采用qingjia-2的流程定义。

ProcessInstance pi=processEngine.getExecutionService()
        .startProcessInstanceByKey("qingjia");

  2.完成任务:完成任务需要提供任务的编号,即id属性值

processEngine.getTaskService().completeTask("30002");

  3.查询所有的流程实例

List<ProcessInstance> processInstanceList=processEngine.getExecutionService()
        .createProcessInstanceQuery()//后面可以接上多个过滤条件,如piid,pdid,pdkey
        .list();

  注意,一种流程定义可以有多个流程实例。如一个请假流程可以同时又多个流程实例在运行,如张三在请假对应一个流程实例,李四请假也对应一个流程实例,两个流程实例可以对应一个流程定义。

  4.查询当前正在执行的所有任务

List<Task> taskList=processEngine
        .getTaskService()
        .createTaskQuery()
        .list();

  5.多条件查询任务

        List<Task> taskList=processEngine
        .getTaskService()
        .createTaskQuery()
//        .assignee("张三")        //根据执行人查询任务
//        .processDefinitionId("qingjia-3")        //根据pdid查询任务,可以有一个或者多个
//        .processInstanceId("qingjia.40001")     //根据piid查询任务,有唯一的一个或者多个(多个的情况是fork/join的情况)
        .list();

  6.根据任务id查询任务

Task task=processEngine.getTaskService().getTask("50001");

    可能会对此产生疑问,为什么不能在5中的代码中直接类似于

List<Task> taskList=processEngine
        .getTaskService()
        .createTaskQuery()
        .taskId("50001")
        .unique();

    的方式查询。这是jbpm4.4版本的一个小瑕疵,但是并没有错,知道就好。

  7.查询已经完成的所有任务

List<HistoryTask> historyTaskList=
        processEngine
        .getHistoryService()
        .createHistoryTaskQuery()
        .state(HistoryTask.STATE_COMPLETED)
        .list();

  8.直接结束流程实例,表示拒绝请求

processEngine.getExecutionService()
        .endProcessInstance("qingjia.30001", "拒绝请假");

    注意,这里数据库方言的设置会影响执行的结果,如果数据库方言设置成为MySQLDialect,则会抛出异常;必须使用MySQLInnoDBDialect数据库方言,mysql5.5极其之上的版本强烈推荐使用MySQL5InnoDBDialect,这样既能够自动建表而且在完成任务或者拒绝任务请求的时候不会报错。

  9.怎么判断一个流程实例是否已经结束:根据piid查询流程实例,如果查询到的结果是NULL,则表示流程实例已经结束。

processEngine.getExecutionService().createProcessInstanceQuery().processInstanceId("qingjia.30001").uniqueResult()

六、流程变量

  什么是流程变量:流程变量是随着随着流程当中任务的执行和结束而产生的数据。比如领导批准或者不批准的理由等等。

  1.流程变量的生命周期

    从流程实例开始到流程实例结束,流程变量依附于流程实例。

  2.流程变量的保存位置:jbpm4_variable表。表中有几个重要字段

    *  EXECUTION_:是应用了`jbpm4_execution`表id的外键。

    *  `TASK_`:是引用了`jbpm4_task`表id的外键

    *  KEY_:由于保存流程变量的时候必须使用Map,所以该KEY是对应着该Map对象的KEY值。

    *  由于可以保存的对象可以任意,所以对象的值的类型也是多种多样。该表的多个字段提供了多种数据类型的保存。

        如LONG_VALUE_、STRING_VALUE_等。

  3.流程变量放入到流程实例中的时机

    (1)启动实例的时候

    (2)完成任务的时候

    (3)流程实开始之后,结束之前

  4.启动流程实例的时候放入流程变量

Person p=new Person();
        p.setId(1L);
        p.setName("person-zhangsan");
        Map<String,Person> variables=new HashMap<String,Person>();
        variables.put("person", p);
        processEngine.getExecutionService()
        .startProcessInstanceById("qingjia-1", variables);

    运行完成该段代码之后,查看表中的数据

    

    特别一个字段CONVERTER_,该字段中的值是ser-bytes,为什么是该值呢,实际上该值是seriable-bytes,在上面的程序中,保存的值是Person对象,在保存到数据库的时候,会将该对象序列化成二进制数据(瞧,这名字起得多好~)。

  5.完成任务的时候放入流程变量

Map<String,Object> variables=new HashMap<String,Object>();
        variables.put("请假人", "小张");
        variables.put("请假天数", 4);
        processEngine.getTaskService()
        .setVariables("30001", variables);
        processEngine.getTaskService()
//        .completeTask("30001",variables);//提供了该API,但是并不能使用,结结实实的一个bug
        .completeTask("30001");

    这里,很明显的和启动流程实例的时候放入流程变量的方法不同,是先放入流程变量,后完成任务,为什么不完成任务的同时放入流程变量呢(使用completeTask方法同时完成任务和将流程变量放入流程实例),实际上completeTask方法有一个重载方法,completeTask(taskId,variables),本来根据官方提供的API解释可以使用该方法类完成任务的同时将流程变量放入到流程实例中,然而实际上调用该方法的时候就会报错。必须在完成方法之前先将流程变量放入到流程实例中。这实际上是JBPM4.4中的一个BUG

  6.直接放入到流程实例中,不管是什么阶段(只要流程实例没有结束)

processEngine.getExecutionService()
        .setVariable("qingjia.10001","请假理由","踢足球");

  7.获取流程变量的方法

    (1)根据taskId获取流程变量,使用该方法获取到的流程变量是所有的流程变量;另外需要注意,在使用该种方法获取流程变量的时候必须保证该任务在任务表中

Set<String> variableNames=processEngine.getTaskService()
        .getVariableNames("40003");
        for(String variableName:variableNames){
            Object obj=processEngine.getTaskService().getVariable("40003", variableName);
            if(obj instanceof Person){
                Person person=(Person) obj;
                System.out.println(variableName+":"+person.getName());
            }else{
                System.out.println(variableName+":"+obj);
            }
        }

    (2)根据流程实例获取流程变量,个人比较偏向使用这种方法,只要流程实例不结束,都可以根据该方法获取流程实例。

Set<String> variableNames=processEngine.getExecutionService()
        .getVariableNames("qingjia.10001");
        for(String variableName:variableNames){
            Object obj=processEngine.getTaskService().getVariable("40003", variableName);
            if(obj instanceof Person){
                Person person=(Person) obj;
                System.out.println(variableName+":"+person.getName());
            }else{
                System.out.println(variableName+":"+obj);
            }
        }

七、任务动态赋值执行人

  之前的示例中,无论是申请人还是执行审批的人,都是固定的,这是不符合实际的。比如申请人,申请人如果固定了,则表示只能一个人发起申请。必须有一种方法能够动态赋值申请人和审批人。动态赋值执行人的方法就是在构建流程图的时候使用EL表达式#{name},这样程序中就可以相应的方法动态赋值了。

    

  1.使用标签指定给执行人赋值的动态方法

    切换到XML模式,在相应的任务中添加下面的数据,如图所示:      

      

    根据标签中的内容,需要在指定的位置新建类,该类必须实现AssignmentHandler接口。

 1 import org.jbpm.api.model.OpenExecution;
 2 import org.jbpm.api.task.Assignable;
 3 import org.jbpm.api.task.AssignmentHandler;
 4
 5 public class MyAssignmentHandler implements AssignmentHandler{
 6     private static final long serialVersionUID = 4278893247283956881L;
 7
 8     @Override
 9     public void assign(Assignable assignable, OpenExecution execution)
10             throws Exception {
11         String assignableId=execution.getVariable("组长").toString();
12         assignable.setAssignee(assignableId);
13     }
14
15 }

org.jbpm.api.task.AssignmentHandler.java

    其中,execution参数提供了获取流程变量的方法;assignable提供了设置执行人的方法。

    比如在启动流程实例的时候:

Map<String,String> variables=new HashMap<String,String>();
        variables.put("组长", "王二麻子");            //通过MyAssignmentHandler类获取到参数并赋值给组长执行人
        processEngine.getExecutionService()
        .startProcessInstanceById("dynamictAssignment-3", variables);

    

    

    

    

时间: 2024-12-24 09:48:19

【Java EE 学习第58-67天】【OA项目练习】【JBPM工作流的使用】的相关文章

【Java EE 学习第16天】【dbcp数据库连接池】【c3p0数据库连接池】

零.回顾之前使用的动态代理的方式实现的数据库连接池: 代码: 1 package day16.utils; 2 3 import java.io.IOException; 4 import java.lang.reflect.InvocationHandler; 5 import java.lang.reflect.Method; 6 import java.lang.reflect.Proxy; 7 import java.sql.Connection; 8 import java.sql.D

Java EE学习--Quartz基本用法

新浪博客完全不适合写技术类文章.本来是想找一个技术性的博客发发自己最近学的东西,发现博客园起源于咱江苏,一个非常质朴的网站,行,咱要养成好习惯,以后没事多总结总结经验吧.很多时候都在网上搜索别人的总结,我自己也总结些东西,或许多多少少能帮得上别人. 首先提到的是Quartz,一个开源的定期执行计划任务的框架.其实我内心好奇这个框架很久了,像那些能定时修改数据库数据,定时分配任务的功能一直觉得很神奇.心动不如行动,今天我就小小的学习了一下用法,力求言简意赅,大家都懂的我就不说了. 第一步:下载Qu

Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库

参考: https://my.oschina.net/gaussik/blog/513444 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Java EE 学习(6):IDEA + maven + spring 搭建 web(2) 5 数据库配置 下面,就要通过一个简单的例子,来介绍 SpringMVC 如何集成 Spring Data JPA(由 Hibernate JPA 提供),来进行强大的数据库访问,并通过本章节

JAVA EE 学习笔记[V1 jsp编程]

在三月初学校开设了javaee的课程,也就此展开了对javaee基础的学习.然后老师也对这次的课程有一定要求.前面的基础就为最终的作业做准备啦~ 在上学期我们学习了java相关知识,也对java se 的安装使用有了一定的认知,而java ee则是构建于java se 平台之上的一套多层的,可扩展的的网络应用. 学习java ee我们首先进行环境的搭建.无非就是使用 tomcat进行服务器的搭建和jdk环境变量配置.而IDE这方面我们选择myeclipse 2016 CI(这个编译器自带tomc

Java EE 学习(5):IDEA + maven + spring 搭建 web(1)

参考:http://www.cnblogs.com/lonelyxmas/p/5397422.html http://www.ctolib.com/docs-IntelliJ-IDEA-c--159047.html 孔老师的<SpringMVC视频教程> 记录: 本节主要完成 使用 maven 管理 spring + 项目 包,搭建 maven+spring 的 web 项目平台. 前提: 已安装并配置好 - Intellij IDEA 16.3.5 Ultimate - JDK 1.8.0_

Java EE 学习(8):IDEA + maven + spring 搭建 web(4)- 用户管理

转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) ava EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库 记录: 通过对用户表的管理,更加深入地讲解SpringMVC的操作. 6 用户管理 既然我们

Java EE 学习(9):IDEA + maven + spring 搭建 web(5)- 博客文章管理

转载:Gaussic(一个致力于AI研究却不得不兼顾项目的研究生) . 注:在阅读本文前,请先阅读: Java EE 学习(5):IDEA + maven + spring 搭建 web(1) Java EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring Java EE 学习(7):IDEA + maven + spring 搭建 web(3)- 配置数据库 Java EE 学习(8):IDEA + maven + spring 搭建 web(

Java EE学习之旅1——HeadFirstJavaEE

因为找到的实习是用Java开发的公司,所以来学习一下Java EE的知识. 首先找来了书<轻量级Java EE企业应用实战>. 啊不得不说学了Java之后直接看这个还是完全不行呢,好多名词看都没有看过啊哈哈. 首先来看看都些啥看不懂的词... 1.JSP.Servlet和JavaBean JSP和Servlet都是用在表现层的东西,而实质上JSP编译成Servlet才运行. 但Servlet开发成本太大,所以用JSP. JavaBean用来通信交换表现层和底层数据. 2.MVC和Struts

Java EE学习——Quartz的Cron表达式

经历过低谷后,还是要好好学习,越失落会越来越落后. 今天写一下Cron表达式的用法,虽然是之前自己写的,也过了挺长一段时间,这次就拿出来作为回顾吧. Cron表达式是Quartz的精髓(个人觉得),比如我们想设定淘宝“秒杀”的那一秒时间,完全可以用下面的方法设置执行时间. Calendar cal = Calendar.getInstance(); //设置将要发生的时间... cal.set(Calendar.DATE, xxx); //.......常规的生成scheduler和job //

Java EE学习之旅2——Ant

上次也了解了一下Ant是啥了,就是管理Java生成的工具嘛. 然后今天来学习一下如何使用Ant. 首先是指令: -find和-s Ant会一直到上级目录搜索build.xml,直到到达文件系统根目录: -buildfile.-file和-f 使用其他生成文件,例如a.xml: -quiet和-q 运行时只输出少数提示信息: -verbose和-v 输出多一点的提示信息. 2014-07-12 22:17:14 Java EE学习之旅2--Ant