Spring mvc Thymeleaf,Spring MVC缺少表单提交上的表单支持对象:null

Spring mvc Thymeleaf,Spring MVC缺少表单提交上的表单支持对象:null,spring-mvc,thymeleaf,Spring Mvc,Thymeleaf,基本上,表单提交的表单支持对象总是空的。有人知道为什么会这样吗 我有一个简单的控制器,可以显示设备列表。可以选择设备并对其应用功能。这是控制器: @Controller @RequestMapping public class DeviceListController { private static final Logger LOG = LoggerFactory.getLogger(DeviceListController.class); @Autowired

基本上,表单提交的表单支持对象总是空的。有人知道为什么会这样吗

我有一个简单的控制器,可以显示设备列表。可以选择设备并对其应用功能。这是控制器:

@Controller
@RequestMapping
public class DeviceListController {

    private static final Logger LOG = LoggerFactory.getLogger(DeviceListController.class);

    @Autowired
        DeviceService deviceService;

    @RequestMapping("/devices/list")
    public String getDevicesPage(ModelMap model) {
        int page = 0;
        int size = 10;

        if(model.get("deviceCommand") != null) {
            DeviceCommand cmd = (DeviceCommand) model.get("deviceCommand");
            page = cmd.getPage();
            size = cmd.getSize();
        }
        Pageable pageRequest = new PageRequest(page, size);
        Page<Device> devices = deviceService.findAllPaginated(pageRequest);

        model.addAttribute("devices", DeviceMapper.map(devices));
        model.addAttribute("deviceCommand", new DeviceCommand(page, size));
        return "devices";
    }

    @RequestMapping("/devices/modify")
    public String modifyDevices(ModelMap model) {

        LOG.debug("Trying to get the device command {}.", model.get("deviceCommand"));

        if(model.get("deviceCommand") != null) {
            DeviceCommand cmd = (DeviceCommand) model.get("deviceCommand");

            LOG.debug("Processing directives {} and {} for {}.", cmd.getNewVersion(),cmd.getNewCommand(),cmd.getDeviceModificationIds());

        }
        return getDevicesPage(model);
    }
}
以及设备标签:

public class DeviceMapper {

    public static DeviceViewModel map(Device device) {
        DeviceViewModel dto = new DeviceViewModel( );
        dto.setId( device.getDeviceId() );
        dto.setRetailerName( device.getRetailerName() );
        dto.setCurrentClientVersion( device.getCurrentClientVersion() );
        dto.setNextClientVersion( device.getNextClientVersion() );
        dto.setCommands( device.getCommands() );
        return dto;
    }

    public static List<DeviceViewModel> map(Page<Device> devices) {
        List<DeviceViewModel> dtos = new ArrayList<>();

        for(Device device : devices) {
            dtos.add( map( device ) );
        }

        return dtos;
    }
}
公共类设备标签{
公共静态设备视图模型映射(设备){
DeviceViewModel dto=新的DeviceViewModel();
setId(device.getDeviceId());
dto.setRetailerName(device.getRetailerName());
dto.setCurrentClientVersion(device.getCurrentClientVersion());
dto.setNextClientVersion(device.getNextClientVersion());
setCommands(device.getCommands());
返回dto;
}
公共静态列表映射(页面设备){
List dtos=new ArrayList();
用于(设备:设备){
添加(映射(设备));
}
返回DTO;
}
}
现在是DeviceCommand,它是我的表单支持对象:

public class DeviceCommand {

    private List<String> deviceModificationIds;
    private String newVersion;
    private String newCommand;
    private int page;
    private int size;

    public DeviceCommand() {}

    public DeviceCommand(int page, int size) {
        this.page = page;
        this.size = size;
    }

    public List<String> getDeviceModificationIds() {
        return deviceModificationIds;
    }

    public void setDeviceModificationIds(List<String> deviceModificationIds) {
        this.deviceModificationIds = deviceModificationIds;
    }

    public String getNewVersion() {
        return newVersion;
    }

    public void setNewVersion(String newVersion) {
        this.newVersion = newVersion;
    }

    public String getNewCommand() {
        return newCommand;
    }

    public void setNewCommand(String newCommand) {
        this.newCommand = newCommand;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }
}
公共类设备命令{
私有列表设备修改ID;
私有字符串新版本;
私有字符串newCommand;
私人网页;
私有整数大小;
公用设备命令(){}
公用设备命令(整数页,整数大小){
this.page=page;
这个。大小=大小;
}
公共列表GetDeviceModificationId(){
返回设备修改ID;
}
public void setDeviceModificationId(列出DeviceModificationId){
this.DeviceModificationId=DeviceModificationId;
}
公共字符串getNewVersion(){
返回新版本;
}
public void setNewVersion(字符串newVersion){
this.newVersion=newVersion;
}
公共字符串getNewCommand(){
返回新命令;
}
public void setNewCommand(字符串newCommand){
this.newCommand=newCommand;
}
公共int getPage(){
返回页面;
}
公共无效设置页(整版页){
this.page=page;
}
公共int getSize(){
返回大小;
}
公共无效设置大小(整型大小){
这个。大小=大小;
}
}
最后是devices.html页面的相关部分:

<form action="#" th:action="@{/devices/modify}" th:object="${deviceCommand}" method="post">
<table class="box-table-a">
    <h1 th:text="#{device.table.caption}">Site Users</h1>
    <thead>
        <tr>
            <th scope="col" th:text="#{device.check.label}">Select</th>
            <th scope="col" th:text="#{device.id.label}">(<span th:text="${device.retailer.name.label}"></span>)</th>
            <th scope="col" th:text="#{device.current.label}">Curr Version</th>
            <th scope="col" th:text="#{device.next.label}">Next Version</th>
            <th scope="col" th:text="#{device.commands.label}">Commands</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="d : ${devices}">
            <td><input type="checkbox" th:field="*{deviceModificationIds}" th:value="${d.id}"/></td>
            <td th:text="${d.id}">(<span th:text="${d.retailerName}"></span>)</td>
            <td th:text="${d.currentClientVersion}">Washington</td>
            <td th:text="${d.nextClientVersion}">gwash</td>
            <td th:text="${d.commands}">gwash</td>
        </tr>
        <tr>
        <td colspan="2">

            </td>
            <td th:text="#{device.change.version.label}"></td>
            <td th:text="#{device.add.command.label}"></td>
            <td></td>
        </tr>
        <tr>
        <td colspan="2">

            </td>
            <td><input type="text" th:field="*{newVersion}"/></td>
            <td><input type="text" th:field="*{newCommand}"/></td>
            <td><button type="submit" th:text="#{device.modify.action.button}">Action</button></td>
        </tr>
    </tbody>
</table>
</form>

网站用户
挑选
()
当前版本
下一版本
命令
()
华盛顿
格瓦什
格瓦什
行动
虽然表单操作确实到达控制器中的modifyDevices方法,但deviceCommand表单支持对象为null


为什么会这样?

只需将类型为
DeviceViewModel
的参数添加到您的
modifyDevices
方法
所以会是这样

@RequestMapping("/devices/modify")
public String modifyDevices(ModelMap model, DeviceViewModel deviceCommand ) {
/* access the submitted object as you want ....*/
}

你可能会发现这个问题很有用

很好——这就是答案。实际上,我刚刚发现了@modeldattribute注释的神奇之处
<form action="#" th:action="@{/devices/modify}" th:object="${deviceCommand}" method="post">
<table class="box-table-a">
    <h1 th:text="#{device.table.caption}">Site Users</h1>
    <thead>
        <tr>
            <th scope="col" th:text="#{device.check.label}">Select</th>
            <th scope="col" th:text="#{device.id.label}">(<span th:text="${device.retailer.name.label}"></span>)</th>
            <th scope="col" th:text="#{device.current.label}">Curr Version</th>
            <th scope="col" th:text="#{device.next.label}">Next Version</th>
            <th scope="col" th:text="#{device.commands.label}">Commands</th>
        </tr>
    </thead>
    <tbody>
        <tr th:each="d : ${devices}">
            <td><input type="checkbox" th:field="*{deviceModificationIds}" th:value="${d.id}"/></td>
            <td th:text="${d.id}">(<span th:text="${d.retailerName}"></span>)</td>
            <td th:text="${d.currentClientVersion}">Washington</td>
            <td th:text="${d.nextClientVersion}">gwash</td>
            <td th:text="${d.commands}">gwash</td>
        </tr>
        <tr>
        <td colspan="2">

            </td>
            <td th:text="#{device.change.version.label}"></td>
            <td th:text="#{device.add.command.label}"></td>
            <td></td>
        </tr>
        <tr>
        <td colspan="2">

            </td>
            <td><input type="text" th:field="*{newVersion}"/></td>
            <td><input type="text" th:field="*{newCommand}"/></td>
            <td><button type="submit" th:text="#{device.modify.action.button}">Action</button></td>
        </tr>
    </tbody>
</table>
</form>
@RequestMapping("/devices/modify")
public String modifyDevices(ModelMap model, DeviceViewModel deviceCommand ) {
/* access the submitted object as you want ....*/
}