Getting a NumberFormatException with thymeleaf on th:field but not on others th:*

151 views Asked by At

I'm rather new to Thymeleaf, so this maybe a newbie mistake. And I've been looking everywhere online for an answer and haven't found one. So sorry if this is really basic.

Basically I'm using Thymeleaf with SpringBoot 2.6.7 and I want to populate a object using a form. Something I've been able to do in the past, but this time for the first time the object I want to populate contains a list of other objects. And it's getting quite tricky.

My html looks like this :

<form action="#" th:action="@{/character}" th:object="${input}" method="post">
    
        <div th:each="i : ${#numbers.sequence(0, input.attributes.size - 1)}">
            <div th:object="${input.attributes[i]}">
                <input type="range" min="1" th:max="*{maxValue}" th:field="*{value}">  <!-- this doesn't work -->
                <p th:text="*{name} + ' = ' + *{value}"></p> <!-- this works -->
            </div>
        </div>
    
</form>

The error I get is java.lang.NumberFormatException: For input string: "i". So I'm guessing there's an issue with the parsing of attributes[i] when processing th:field.

I've tried to change the loop to <div th:each="attribute : ${input.attributes}"> (and the associated th:object) but that just made it worse, got the Neither BindingResult nor plain target object for bean name 'attribute' available as request attribute error message.

If it's any help, here is my controller :

@GetMapping("character")
public String startingForm(Model model) {
    model.addAttribute("input", new FormInput());
    return "character";
}

@PostMapping("character")
public String processingForm(@ModelAttribute FormInput input, BindingResult bindingResult, Model model)
        throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException {

    if(bindingResult.hasErrors()){
        log.error("something went wrong");
    }

    // Other stuff
    return "character";
}

My input class

@Getter
public class FormInput{
    protected List<Attribute> attributes;

    public FormInput(){
        attributes= new ArrayList<>();
        for (AttributeEnum ae : AttributeEnum.values()) {
            attributes.add(new Attribute(ae.getName(), ae));
        }
    }
}

And the Attribute class

@Getter
public class Attribute {
    protected String name;
    protected AttributeEnum typeAttribute;
    protected Integer value = 1;
    protected Integer maxValue = 5;

    public Attribute(String n, AttributeEnum ta){
        name = n;
        typeAttribute = ta;
    }

    public boolean setValue(Integer v){
        if (v > maxValue ) return false;
        value = v;
        return true;
    }
}

Does someone know a fix to this issue?

1

There are 1 answers

0
Bertolen On

Just found the solution. So I'm posting the answer is anyone has the same issue.

<div th:each="i : ${#numbers.sequence(0, input.attributes.size - 1)}">
    <input type="range" min="0" th:max="${input.attributes[i].maxValue}" th:field="${input.attributes[__${i}__].value}">   <!-- this works -->
</div>

Just had to replace attributes[i] with attributes[__${i}__].