在旧的业务流程加入一个“拦截”,原来从前端表单提交到后台的处理逻辑延后处理,本质上是一个异步化的处理过程。 此时将表单参数存储到数据库,在适当的时刻“拦截”结束通过时调用原来的处理逻辑。 F代表表单参数,A代表控制器参数,
F --> A --> F' --> A';
思考以上的流程, ①F --> A,从前端到controller方法 ②A --> F',将参数存储到数据库 ③F' --> A', 从数据库取出原来的参数对象,希望A'能够完全表达A, A' == A,包括参数类型与顺序。
数据库数据表的设计
table at_form{
id bigint,
name varchar
json varchar
type_token varchar?
}
Java的示例代码
public class AtFormApp {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person p = new Person();
p.name = "Honey";
p.age = 26;
controlMethod1(p);
controlMethod2();
}
static class Person {
String name;
int age;
}
static void controlMethod1(Person p) throws IOException {
saveService(p, "p");
}
static void controlMethod2() throws IOException, ClassNotFoundException {
AtForm atForm = query();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(atForm.typeToken.getBytes()));
Type type = (Type) ois.readObject();
//Person type here
Person p = new Gson().fromJson(atForm.json, type.getClass());
realService(p);
}
static void saveService(Person p, String name) throws IOException {
Type type = new TypeToken<Person>() {}.getType();
String json = new Gson().toJson(p);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(type);
oos.close();
String typeToken = baos.toString();
AtForm atForm = new AtForm();
atForm.name = name;
atForm.json = json;
atForm.typeToken = typeToken;
insert(atForm);
}
static void realService(Person p) {
//good
}
static AtForm query() throws IOException {
AtForm atForm = new AtForm();
atForm.name = "p";
atForm.json = "{\"name\":\"Honey\",\"age\":26}";
Type type = new TypeToken<Person>() {}.getType();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(type);
oos.close();
String typeToken = baos.toString();
atForm.typeToken = typeToken;
return atForm;
}
//imitate insert behavior
static int insert(AtForm atForm) {
return 1;
}
static class AtForm {
Long id;
String typeToken;
String name;
String json;
}
}
实际上在异步的处理过程中很难做到,
这里的Person类型无法确定,调用realService方法也无法做到,需要反射? PHP的示例代码
<?php
class AtFormApp {
public function main() {
$p = new Person();
$p->name = 'Honey';
$p->age = 26;
$this->controlMethod1($p);
$this->controlMethod2();
}
public function controlMethod1(Person $p) {
$this->saveService($p, 'p');
}
public function controlMethod2() {
$atForm = AtForm::findOne(['name' => 'p']);
$p = unserialize($atForm->data);
$this->realService($p);
}
public function saveService(Person $p, $name) {
$atForm = new AtForm();
$atForm->name = $name;
$atForm->data = serialize($p);
$atForm.save();
}
public function realService(Person $p) {
// good
}
}
class Person {
public $name;
public $age;
}
class AtForm() {
public $id;
public $name;
public $data;
public static findOne($condition) {}
public save() {}
}
弱类型语言就没有这样的麻烦, $p = unserialize($atForm->data);就能得到原来的Person实例对象。 后面调用realService($p)也很自然。虽然这里讨论的示例中只有一个参数,但是多个参数的情况下,PHP也能支持。
感谢@Tranch提供的PHP示例代码