Search code examples
javaspringthymeleaf

How to find out which properties are callable for a template variable


I have the following controller:

public class MyErrorController implements ErrorController {

  @RequestMapping("/error")
  public String handleError(HttpServletRequest request, Model model) {
     model.addAttribute("request", request);

   }
}

And in my template, I can do:

Method: <span th:text="${request.method}">method</span><br/>

And it will give me html of:

Method: POST

Is there a simple way to know all of the properties that the request method has in Thymeleaf? For example, doing something like %{request.toDict} (made up for demonstration purposes). HttpServletRequest methods are listed here, but I'm not sure which can be used as properties and furthermore, how it can be (hopefully) easily shown from the template.


Solution

  • With the current version of Thymeleaf (3.0.9), there is no specific utility method to print out the properties of an object. So no, there is not a simple way.

    However, one way to do this would be to construct your own method and print them using reflection. My running assumption, of course, is that methods available to Java should be available to Thymeleaf as well. You can modify this method if this is not exactly what you're seeking (inspiration).

    public static List<Method> toDict(Class aClass) {
        List<Method> methods = new ArrayList<>();
        do {
            Collections.addAll(methods, aClass.getDeclaredMethods()); //using just this would return the declared methods for the class and not any parent classes
            aClass = aClass.getSuperclass();
        } while (aClass != null);
        return methods;
    }
    

    Then call the static method in your HTML:

    <div th:each="field : ${T(com.somedomain.util.SomeUtil).toDict(#request.class)}">
        <span th:text="${field}" th:remove="tag">[field]</span><br>
    </div>
    

    Also be aware of the usual caveats to unit testing and static methods. Lastly, you can look at #vars in case you're looking to access model variables.

    No controller method needed.