首页 > 其他分享 >工作流引擎Activiti 专题

工作流引擎Activiti 专题

时间:2023-08-03 21:32:41浏览次数:47  
标签:INFO 专题 Activiti activiti jar 引擎 org main

https://github.com/Activiti/Activiti

Quick Start Guide

This quick start assumes:

  • Familiarity with Maven and Java
  • A development environment with Java

The following variables will be referenced in this tutorial

Variable

Description

$mvnProject

The root location of the maven project

$actUnzipedPack

The root location of the unzipped file downloaded from http://www.activiti.org/download.html.

$quickStartJavaProjectName

The name of the Quick Start Java Project. This is recommended to be “ActivitiDeveloperQuickStart”.

...

Refers to information being skipped, for brevity sake.

$actVer

The version of Activiti currently being run.

1. Introduction

This Quick Start shows the simplicity of embedding Business Process Management (BPM) into your application using Activiti. You will build a command-line application that embeds standards-based Business Process Modeling Notation (BPMN) logic into your application.

Activiti has advanced process design tools for embedding more sophisticated BPM logic into your application. These tools include an Eclipse-based and Web-Based BPMN Editor to name a few. For brevity, this Quick Start only uses Activiti’s Java APIs.

For an introduction to additional Activiti BPM tooling, see:

  • Sample Onboarding Quick Start
  • Activiti User’s Guide

This Quick Start

  • In general, stays away from IDE-specific illustrations (though, they are done sparingly). Activiti works with any Java-friendly IDE.
  • Uses Maven, but other build and dependencies management systems like Gradle and Ivy work too.

2. Create and Setup Maven Project

Create a Java project called “ActivitiDeveloperQuickStart” (onwards referred to as $quickStartJavaProjectName) with the following Maven dependencies:

File: $mvnProject/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>$quickStartJavaProjectName</groupId>
  <artifactId>$quickStartJavaProjectName</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <!-- ... other configurations may exist, such as a build stanza, depending your environment ... -->

  <dependencies>
      <dependency>
          <groupId>org.activiti</groupId>
          <artifactId>activiti-engine</artifactId>
          <version>$actVer</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.7.21</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>1.7.21</version>
      </dependency>
      <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
          <version>1.4.193</version>
      </dependency>
  </dependencies>
</project>

Of course, $actVer will be replaced with the downloaded Activiti version. For instance, if your downloaded Activiti package is “activiti-5.22.0” than the value of $actVer will be 5.22.0.

Notice the following dependencies:

  • Activiti (org.activiti) – Activiti’s BPM engine
  • Database (com.h2database) – the H2 database
  • Logging (org.slf4j) – Simple Logging Facade for Java

When referring to build directories, the tutorial assumes the standard Maven build paths for your maven project:

Path

Description

$mvnProject/src/main/java

Java source directory

$mvnProject/src/main/resources

Resource directory

$mvnProject/src/test/java

Java test directory

$mvnProject/src/test/resources

Resource test directory

 

You should be able to build the blank project. Please ensure that the overall state is “BUILD SUCCESS” before continuing.

Command: mvn compile

Base Path: $mvnProject

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building $quickStartJavaProjectName 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ $quickStartJavaProjectName ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.5.1:compile (default-compile) @ HelloProcess2 ---
[INFO] Nothing to compile - all classes are up to date
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.592s
[INFO] Finished at: Sun Nov 27 05:09:59 EST 2016
[INFO] Final Memory: 10M/309M
[INFO] ------------------------------------------------------------------------

Notes:

  • Your output may look different. Most notably, maven may need retrieve the project dependencies.

3. Create Process Engine

As suggested earlier in the summary of the maven dependencies, Activiti leverages Simple Logging Facade for Java (slf4j) for logging. In this example application we’ll use the log4j logging implementation. Add the log4j.properties file to your project.

File: $mvnProject/src/main/resources/log4j.properties

log4j.rootLogger=DEBUG, ACT

log4j.appender.ACT=org.apache.log4j.ConsoleAppender
log4j.appender.ACT.layout=org.apache.log4j.PatternLayout
log4j.appender.ACT.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

Create a new Java class with a blank main.

File: $mvnProject/src/main/java/com/example/OnboardingRequest.java

package com.example;

public class OnboardingRequest {
    public static void main(String[] args) {
        
    }
}

Adding to the main entry point is the creation of the Process Engine. Add to OnboardingRequest.java as illustrated below:

Adding to the main entry point is the creation of the Process Engine. Add to OnboardingRequest.java as illustrated below:

package com.example;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;

public class OnboardingRequest {
  public static void main(String[] args) {
    ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
      .setJdbcUrl("jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000")
      .setJdbcUsername("sa")
      .setJdbcPassword("")
      .setJdbcDriver("org.h2.Driver")
      .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    ProcessEngine processEngine = cfg.buildProcessEngine();
    String pName = processEngine.getName();
    String ver = ProcessEngine.VERSION;
    System.out.println("ProcessEngine [" + pName + "] Version: [" + ver + "]");
  }
}

File: $mvnProject/src/main/java/com/example/OnboardingRequest.java

Add Lines

Explanation

3-4

Activiti Process Engine and Configuration.

5,9

Configuration helper for standalone environments (e.g. not using a dependency manager).

9-15

Creates the Process Engine using a memory-based h2 embedded database.

16-18

Displays the Process Engine configuration and Activiti version.

Activiti Supports Dependency Injection

  • Activiti is built for and can easily leverage dependency injection. Check the Activiti User’s Guide for more information.

Activiti Ships with a number of Database Providers

  • Database scripts at “$actUnzipedPack/database/create”
  • Activiti User’s Guide (various development and administration sections)

Supporting IDE and platform independent as well as simplicity for this Quick Start, add a “fat jar”configuration as illustrated below in lines 1-28 to the pom.xml.

File: $mvnProject/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
  <build>
...
    <plugins>
...
      <!-- Maven Assembly Plugin -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.4.1</version>
        <configuration>
          <!-- get all project dependencies -->
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <!-- MainClass in mainfest make a executable jar -->
          <archive>
            <manifest>
              <mainClass>com.example.OnboardingRequest</mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <!-- bind to the packaging phase -->
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
...
    </plugins>
...
  </build>
...
</project>

Package up your code by running “mvn package”.

Command: mvn package

Base Path: $mvnProject

[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building $quickStartJavaProjectName 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ $quickStartJavaProjectName ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.5.1:compile (default-compile) @ HelloProcess2 ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ HelloProcess2 ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.5.1:testCompile (default-testCompile) @ HelloProcess2 ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ HelloProcess2 ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ HelloProcess2 ---
[INFO] Building jar: $mvnProject/target/$quickStartJavaProjectName-0.0.1-SNAPSHOT.jar
[INFO] META-INF/maven/$quickStartJavaProjectName/HelloProcess2/pom.xml already added, skipping
[INFO] META-INF/maven/$quickStartJavaProjectName/$quickStartJavaProjectName/pom.properties already added, skipping
[INFO] 
[INFO] --- maven-assembly-plugin:2.4.1:single (make-assembly) @ $quickStartJavaProjectName ---
[INFO] Building jar: $mvnProject/target/$quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.029s
[INFO] Finished at: Sun Nov 27 07:23:43 EST 2016
[INFO] Final Memory: 33M/702M
[INFO] ------------------------------------------------------------------------

Notes:

  • Your output may look different. The important output here is the line just above “BUILD SUCCESS” showing success of the jar with dependencies: 
  • “[INFO] Building jar: $mvnProject/target/$quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar”

Supporting IDE and platform independent as well as simplicity for this Quick Start, run your Java program from the command line as illustrated below.

Command: java -jar target/ActivitiDeveloperQuickStart-0.0.1-SNAPSHOT-jar-with-dependencies.jar

-or-

java -jar target/$quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar

11:45:32,849 [main] DEBUG org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl  - initializing datasource to db: jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000
11:45:32,856 [main] DEBUG org.apache.ibatis.logging.LogFactory  - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.

...

11:45:33,777 [main] DEBUG org.activiti.engine.impl.db.DbSqlSession  - SQL: create table ACT_PROCDEF_INFO ( 
ID_ varchar(64) not null, 
PROC_DEF_ID_ varchar(64) not null, 
REV_ integer, 
INFO_JSON_ID_ varchar(64), 
primary key (ID_) 
)

...

11:45:33,835 [main] DEBUG org.activiti.engine.impl.db.DbSqlSession  - activiti db schema create for component identity successful
11:45:33,835 [main] DEBUG org.activiti.engine.impl.db.DbSqlSession  - flush summary: 0 insert, 0 update, 0 delete.
11:45:33,835 [main] DEBUG org.activiti.engine.impl.db.DbSqlSession  - now executing flush...
11:45:33,835 [main] DEBUG org.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext  - firing event committing...
11:45:33,835 [main] DEBUG org.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext  - committing the ibatis sql session...
11:45:33,835 [main] DEBUG org.activiti.engine.impl.cfg.standalone.StandaloneMybatisTransactionContext  - firing event committed...
11:45:33,836 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction  - Resetting autocommit to true on JDBC Connection [conn0: url=jdbc:h2:mem:activiti user=SA]
11:45:33,836 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction  - Closing JDBC Connection [conn0: url=jdbc:h2:mem:activiti user=SA]
11:45:33,836 [main] DEBUG org.apache.ibatis.datasource.pooled.PooledDataSource  - Returned connection 667346055 to pool.
11:45:33,836 [main] DEBUG org.activiti.engine.impl.interceptor.LogInterceptor  - --- SchemaOperationsProcessEngineBuild finished --------------------------------------------------------
11:45:33,836 [main] DEBUG org.activiti.engine.impl.interceptor.LogInterceptor  - 

11:45:33,836 [main] INFO  org.activiti.engine.impl.ProcessEngineImpl  - ProcessEngine default created
ProcessEngine [default] Version: [$actVer]

Notes:

  • The key output of interest is the printing of your Activiti version: $actVer It should match the version configured in
  • “[INFO] Building jar: $mvnProject/target/$quickStartJavaProjectName-0.0.1-SNAPSHOT-jar-with-dependencies.jar”

Or, of course, you can run the same program can be run from within your IDE. For instance, from within Eclipse, choose the OnboardingRequest.java file, then right mouse clicking for “Run As > Java Application”. Should you run the program from within your IDE, the result should be the same (usually displayed in the IDE’s console view).

You’ve successfully embedded Activiti’s BPM Engine within this simple Java program.
4. Deploy Process Definition

We’re now ready to add additional BPM logic to our Activiti Engine.

For this, as suggested by the name of our OnboardingRequest Java class, we’ll use a simple Onboarding process. In this example, we’ll enter data. Then, if the years of experience are above 3, a task for a personalized onboarding welcome message will be issued. In that task, the user will manually enter data into a faux backend system. If the years of experience are 3 years or below, then simply, generically, and automatically integrate data with a faux backend system.

Activiti’s Process Engine is a BPMN 2.0 compliant. Visually, the process above can be modeled like so:

 

This example is purposely simple. And, depending on the requirements, it can be modeled a few different ways. While it can orchestrate simple process too, note that Activiti can handle very sophisticated processes with dozens, hundreds, or even thousands of steps.

Underlying the visual process model above is the XML structure of BPMN. The XML document in this case is onboarding.bpmn20.xml. This quick start will not go into the depths of the underlying XML BPMN structure to focus on the mechanics of developing against the Activiti APIs and embedding Activiti into your application. Yet, to support the logic that follows, here is a summary of the relevant BPMN shapes and the defined logic codified in the underlying XML:

 

 

 

BPMN Shapes

Onboarding.bpmn20.xml Lines

Comments





8

Start Event





9-15

User Task collecting 2 form properties: “fullName” and “yearsOfExperience”. Note the candidate groups on line 9 are set to “managers”.





21-27

User Task collecting 1 form property: “personalWelcomeTime”. Note the candidate groups on line 22 are set to “managers”.





31-35

Script Task representing Automated Data Entry to a faux backend. Notice while simple, there is a simple script that sets a process variable autoWelcomeTime (line 34-35):var dateAsString = new Date().toString(); execution.setVariable("autoWelcomeTime", dateAsString);





18

Defines the “Years of Experience” exclusive gateway. (A decision will yield one path or the other.)

37-39

Represents the “>3” logic using the yearsOfExperience variable:${yearsOfExperience > 3}

18,36

On the exclusive gateway (line 18), note the default stanza pointing to “automatedIntroPath (line 36) representing a logical “else” to the condition “>3”.





298

End Event

File: $mvnProject/src/main/java/com/example/OnboardingRequest.java

Add Lines

Explanation

25-27

Loads the supplied BPMN model and deploys it to Activiti Process Engine.

28-33

Retrieves the deployed model, proving that it is in the Activiti repository.

See various sections in the Activiti User’s Guide for more information on BPMN and its use in Activiti.

Download the onboarding.bpmn20.xml file, the entire XML structure below, and copy the onboarding.bpmn20.xml file to the path $mvnProject/src/main/resources/.
 

File: $mvnProject/src/main/resources/onboarding.bpmn20.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="onboarding" name="Onboarding" isExecutable="true">
    <startEvent id="startOnboarding" name="Start" activiti:initiator="initiator"></startEvent>
    <userTask id="enterOnboardingData" name="Enter Data" activiti:assignee="${initiator}" activiti:candidateGroups="managers">
      <extensionElements>
        <activiti:formProperty id="fullName" name="Full Name" type="string"></activiti:formProperty>
        <activiti:formProperty id="yearsOfExperience" name="Years of Experience" type="long" required="true"></activiti:formProperty>
      </extensionElements>
    </userTask>
    <sequenceFlow id="sid-1337EA98-7364-4198-B5D9-30F5341D6918" sourceRef="startOnboarding" targetRef="enterOnboardingData"></sequenceFlow>
    <exclusiveGateway id="decision" name="Years of Experience" default="automatedIntroPath"></exclusiveGateway>
    <sequenceFlow id="sid-42BE5661-C3D5-4DE6-96F5-73D34822727A" sourceRef="enterOnboardingData" targetRef="decision"></sequenceFlow>
    <userTask id="personalizedIntro" name="Personalized Introduction and Data Entry" activiti:assignee="${initiator}" activiti:candidateGroups="managers">
      <extensionElements>
        <activiti:formProperty id="personalWelcomeTime" name="Personal Welcome Time" type="date" datePattern="MM-dd-yyyy hh:mm"></activiti:formProperty>
      </extensionElements>
    </userTask>
    <endEvent id="endOnboarding" name="End"></endEvent>
    <sequenceFlow id="sid-37A73ACA-2E23-400B-96F3-71F77738DAFA" sourceRef="automatedIntro" targetRef="endOnboarding"></sequenceFlow>
    <scriptTask id="automatedIntro" name="Generic and Automated Data Entry" scriptFormat="javascript" activiti:autoStoreVariables="false">
      <script><![CDATA[var dateAsString = new Date().toString();
execution.setVariable("autoWelcomeTime", dateAsString);]]></script>
    </scriptTask>
    <sequenceFlow id="automatedIntroPath" sourceRef="decision" targetRef="automatedIntro"></sequenceFlow>
    <sequenceFlow id="personalizedIntroPath" name=">3" sourceRef="decision" targetRef="personalizedIntro">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${yearsOfExperience > 3}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-BA6F061B-47B6-428B-8CE6-739244B14BD6" sourceRef="personalizedIntro" targetRef="endOnboarding"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id=

标签:INFO,专题,Activiti,activiti,jar,引擎,org,main
From: https://blog.51cto.com/u_15147537/6953476

相关文章

  • 【专题】2022互联网母婴行业用户洞察报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • 【专题】2022年中国母婴群体消费决策趋势研究报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • 【专题】2022母婴行业洞察报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • 【专题】2022年中国母婴新消费白皮书报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • 【专题】2021-2022年中国母婴行业新媒体营销价值研究报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • 【专题】2022母婴行业发展趋势洞察报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • 【专题】2022年·母婴行业用户洞察报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • 【专题】2022年中国母婴用品行业分析报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • 【专题】2022母婴行业发展趋势研究报告PDF合集分享(附原数据表)
    报告链接:http://tecdat.cn/?p=31424人口出生红利消失,以及后疫情时代的冲击,但消费升级将负面因素拉平,母婴消费市场总量持续稳步上升。"精致妈妈"的营销价值日益凸显。阅读原文,获取专题报告合集全文,解锁文末56份母婴行业相关报告。当母婴人群成为众多母婴及家庭消费品的重要入口群......
  • CTFer成长记录——CTF之Web专题·极客大挑战—BabySQL
    一、题目链接https://buuoj.cn/challenges#[%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98%202019]BabySQL二、解法步骤  本题是SQL注入,那么先尝试万能密码:1'or1=1#  发现or后面的东西都失效了,猜测对or进行了过滤,这里用双写绕过试试:1'oorr1=1#:  登陆成功。接......