Spring boot and thymeleaf: Can not evaluate size() of an ArrayList - spring-boot

I have an ArrayList in my mvc controller class:
List<Market> markets = loadMarkets();
I add this list to Model object:
model.addAttribute("markets", markets);
In my template, when I want to get size() of this array:
<span>Top <strong th:text="${markets.size}"></strong>assets.</span>
I got this error:
Cannot evaluate because of compilation error(s): The method size() is undefined for the type Object.
Snapshot of the VSCode debugging tools:
I am using Spring Boot version 2.2.6.RELEASE with Thymeleaf template engine.

When you use property notation th:text="${markets.size}", then Thymeleaf will search for a method getSize() on the markets attribute in the model. But there is no getSize() method, only size() method.
So use the method itself instead of using the property notation:
th:text="${markets.size()}"

Related

How to decide a type of GetMapping method in Spring boot?

I'm spring boot learner and trying to clone-code a website. Below is a code to get a data of the specific content.
#GetMapping("/api/articles/{id}")
public List<Article> takeArticle() { return articleRepository.findAllByOrderByModifiedAtDesc();}
Then the ARC shows whole data of contents which I've already posted, but I want a specific data according to the id value. I think the problem is the type of takeArticle() method. So which type should be used for the method above to fulfill my purpose?
#GetMapping("/api/articles/{id}")
public Article takeArticle(#PathVariable Integer id) {
return articleRepository.findById(id).orElseThrow(() -> {
// throw Not found exception if article doesn't exists with given id
});
}
By the way you shouldn't use repository interfaces directly in your controller layer. Use service layer between repository and controllers.

Why does #GetMapping method return request param while sending response?

I get request params as POJO and do nothing in method but in jsp shows parameter which I get from request.Why does method return my object?
Additionally, when I use primitive type or String, It doesn't return object and works perfectly
Controller
#GetMapping("/ULD_details")
public String ULD_detailGet(ActionError ID){
return "ULD_detail";
JSP
<tr>
<td >ULD id</td>
<td>${actionError.ID}</td>
</tr>
Link
http://localhost:8080/UCM-controller/ULD_details?ID=1145
It doesn't return your object. It returns the String "ULD_detail", which is the name of the view to execute.
This view is executed, and finds an actionError bean in the request attributes (i.e. in the model), because the Spring documentation about handler methods arguments says:
Any other argument
If a method argument is not matched to any of the above, by default it is resolved as an #RequestParam if it is a simple type, as determined by BeanUtils#isSimpleProperty, or as an #ModelAttribute otherwise.
And the documentation of ModelAttribute says:
The default model attribute name is inferred from the declared attribute type (i.e. the method parameter type or method return type), based on the non-qualified class name: e.g. "orderAddress" for class "mypackage.OrderAddress"

Access enum.valueof() from apache camel route

I am comparatively newbie to apache camel. I am working on route called 'Upgrade' using Java DSL. I have java bean called 'Action' which has an enum,
public enum bundle{
AAA("Monthly AAA Bundle"),
BBB("Monthly BBB Bundle");
private String upbundle;
private bundle(String upBundle) {this.upbundle = upBundle;}
private getBundle() {return upbundle;}
}
From route I want to call 'valueOf()' on enum to get BundleName. I have enum value 'AAA' in exchange header. Using 'AAA' i want to retrieve enum value i.e. 'Monthly AAA Bundle' and store it in exchange header name 'destBundleName'
I used
.setHeader("destBundleName", simple(Action.bundle.valueOf(header("bm").toString()).getBundle()))
is given me runtime error "No enum constant Action.bundle.header{bm} at java.lang.Enum.valueOf
but if i use
.setHeader("destBundleName", simple(Action.bundle.valueOf("AAA")).getBundle())) it works fine.
It means in 1st e.g. header("bm").toString() is not replacing it with String.
I can write process() or bean method which calls enum valueof & from my route i can use that bean method but Is there any way to access enum valueOf() directly from route using value from camel header as a valueOf() param.
Thank you so much for help.

In JSP, Field Path Uses HashMap<String,ArrayList<String>> (SpringMVC Form)

Suppose my model field is a HashMap of Strings to ArrayList's of Strings.
HashMap<String,ArrayList<String>> map = new HashMap<String,ArrayList<String>>();
For field binding, I need to point to an i-th item of the ArrayList of a specific key in my JSP. How do I do it? Will this double-bracket notation work? Assume that 'key' and 'index' are known JSTL variables in my JSP.
<form:checkbox path="map[${key}][${index}]" />
What I'm essentially doing is, for a field value, store its path e.g.
map['testkey'][4]
which would point to
map.get("testkey").get(4);
That doesn't work:
org.springframework.beans.NullValueInNestedPathException: Invalid property 'map[TestKey][0]'
NOTE According to this (Binding a map of lists in Spring MVC), this will be a problem because sub-objects are not auto-growable, and I need to implement a LazyList or a growable list? An ArrayList by itself is growable for Spring MVC's forms, but when used as a sub-collection, it's not? Very tricky.
I solved this problem by following the LazyList/LazySet implementation in the link above,
Binding a map of lists in Spring MVC
From their example,
public class PrsData {
private Map<String, List<PrsCDData>> prsCDData;
public PrsData() {
this.prsCDData = MapUtils.lazyMap(new HashMap<String,List<Object>>(), new Factory() {
public Object create() {
return LazyList.decorate(new ArrayList<PrsCDData>(),
FactoryUtils.instantiateFactory(PrsCDData.class));
}
});
}
}
Once I had a data structure like that mapped to my JSP Path, the field binding magically started working and I could then make my path e.g. map["key"][index] in the JSP.
As they replied, SpringMVC auto-converts simple lists and maps to Lazy collections, but does not do it when the collection is a subobject.

Extending Laravel's Validator Class

I am using the Laravel's validator class, and when validation fails I print out the errors with this method:
$validator->messages();
The method returns a multi dimensional array, I need a single dimensional array.
$validator->net_method();
How will I go about extending a new method to return the errors in a different format?

Resources