Dynamic content in Thymeleaf has to be defined only as th:attributes inside standard html tags. Html rendering engines just ignore unknown attributes unlike unknown tags or expressions within page content.
This is the main idea behind Thymeleaf's natural templating design, so there is no clutter of third party tags and expressions when statically displaying the page. Unlike jsp, the template processor resolves th:attributes only, not expressions elsewhere in the page so that's why your ${cdata} does not work outside th:text.
I believe (and I have used it successfully in production) that the cleanest way to pass back-end data to javascript in non-ajax way, is to use html5 data attributes. Html5 allows arbitrary attributes prefixed with data- without complaining.
So you can use a container div for example to pass the data like so :
<div id="Some-Container" th:attr="data-someDescription=${cdataJson}"></div>
then if you use jQuery you can retrieve easily all html5 data attributes as jQuery data:
$("#Some-Container").data("someDescription");
If not using jQuery but some other js framework, there is probably some similar way. In plain js you just have to write more code.
Now, in order to export your data as a json formatted text, for being easily consumable by javascript, you have first of all add an object mapper in your application context :
<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
declare an dependency in your controller:
@Autowired
private ObjectMapper jsonMapper;
and then, when you add the model attribute, use the object mapper to convert data to json:
String cDataJson = jsonMapper.writeValueAsString(custServe.listAllCustomers());
model.addAttribute("cdataJson", cDataJson);
thymeleaf, it totally changes the scope of the issue. Take a look at: thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html