关于 MVC 参数注入，主要尊守以下规则：

* 参数名与请求数据名一一对应。
* 当对映不上时，会采用整体数据注入（如果接收的是实体）
* 参数名与请求数据同名时，又想整体注入（如果接收的是实体），可使用 `@Body` 注解强制标注

### 1、编译引起的参数变名问题

 java 编译默认会把参数名变掉（变成 arg0, arg1 之类的）。处理参考： [《问题：编译保持参数名不变-parameters》](/article/260)

### 2、表单参数注入

请求样本数据：

```
GET http://localhost:8080/demo?select=1&select=2&user=noear
```

支持单字段注入（要求参数名，与请求数据名一一对应）

```java
@Controller
public class DemoController{
    @Mapping("demo")
    public void demo(String[] select, String user){
    }
}
```


支持整体注入（要求参数名，不能与请求数据名对应）

```java
public class PostDo{
    public String[] select;
    public String user;
}

@Controller
public class DemoController{
    @Mapping("demo")
    public void demo(PostDo postDo){ //参数名，不能是 select 或 user
    }
    
    @Mapping("demo")
    public void demo(@Body PostDo user){ //参数名如果与数据名相同。需要使用 @Body 来标明它是接收所有请求数据
    }
}
```

### 3、结构型参数注入（类似 properties 格式参数）

请求样本数据：

* ?user.id=1&user.name=noear&user.type[0]=a&user.type[1]=b
* ?type[]=a&type[]=b
* ?order[id]=a

此特性，需要引入序列化插件：[solon-serialization-properties](/article/753)。规则细节参考“序列化数据注入”。

### 4、序列化数据注入（比如 json, hessian, protostuff, fury）

请求样本数据：

```
POST http://localhost:8080/demo
{user:'noear',select:[1,2],data:{code:1,label:'b'}}
```

支持单字段注入（要求参数名，与请求数据的一级字段名对应）

```java
@Controller
public class DemoController{
    @Mapping("demo")
    public void demo(String[] select, String user){
    }
}
```


支持整体注入（要求参数名，不能与请求数据的一级字段名对应）

```java
public class PostDo{
    public String[] select;
    public String user;
}

@Controller
public class DemoController{
    @Mapping("demo")
    public void demo(PostDo postDo){ //参数名，不能是 select 或 user
    }
    
    @Mapping("demo")
    public void demo(@Body PostDo user){ //参数名如果与数据名相同。需要使用 @Body 来标明它是接收所有请求数据
    }
}
```

支持局部注入（要求参数名，不能与请求数据名对应）

```java
public class PostDo{
    public String[] select;
    public String user;
}

public class DataDo{
    public int code;
    public String label;
}

@Controller
public class DemoController{
    @Mapping("demo")
    public void demo(PostDo postDo, String user, DataDo data){ //postDo 接收整体数据，user,data 接收局部数据
    }
}
```

### 5、关于枚举注入

* 基本结构的，传入 name 可自动转换
* 定制结构的，参考下面的“特殊类型” 

### 6、特殊类型的注入转换

* 表单数据注入时

借助"转换器"，比如请求 `?demo=1` 要转换成实体 Demo。示例：


```java
@Component
public class DemoConverter implements Converter<String, Demo> {
    @Override
    public Demo convert(String value) throws ConvertException {
        return Demo.parse(value);
    }
}

//应用示例（http://....?demo=1。 通过转换器把 1 转为 Demo 实体）
@Controller
public class DemoController {
    @Mapping("test")
    public void test(Demo demo){
    
    }
}
```


* 序列化数据注入

这个需要，给序列化组件添加对应的解码器，或者使用其特定的注解或特性。

### 7、扩展参数注入分析器定制（v3.6.1 后支持）

通过参数特征匹配（比如类型或注解），然后实现参数分析。可替换上面的“特殊类型的注入转换”，且更自由，示例：

```java
@Component
public class MethodArgumentResolverImpl implements MethodArgumentResolver{
    @Override
    public boolean matched(Context ctx, ParamWrap pWrap) {
        return pWrap.getType() == Demo.class;
    }

    @Override
    public Object resolveArgument(Context ctx, Object target, MethodWrap mWrap, ParamWrap pWrap, int pIndex, LazyReference bodyRef) throws Throwable {
        return Demo.parse(ctx.param("demo"));
    }
}
```

