I am trying to set a List<Long>
to an Java object.
The set function is:
ResponseEntity<String> response = bcInsertService.addNewClip(new PrmBcClipInsert()
.setTags(Arrays.asList(new Long[]{5L, 3L}))
);
And the object is
public class PrmBcClipInsert implements Serializable {
@ApiModelProperty(required = true)
private List<Long> tags;
public List<Long> getTags() {
return tags;
}
public PrmBcClipInsert setTags(List<Long> tags) {
this.tags = tags;
return this;
}
}
This is BcInsertService:
public class BcInsertService extends RestTemplate {
private static final Logger log = LoggerFactory.getLogger(BcInsertService.class);
public ResponseEntity<String> addNewClip(PrmBcClipInsert prmBcClipInsert) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> map= new LinkedMultiValueMap<String, Object>();
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<MultiValueMap<String, Object>>(prmBcClipInsert.getParameters(), headers);
ParameterizedTypeReference<StandardResponse> typeRef = new ParameterizedTypeReference<StandardResponse>() {};
ResponseEntity<String> response = this.postForEntity( "http://localhost:8080/bc/add-clip", request , String.class );
log.info(response.toString());
return response;
}
}
And it returns an error:
Field error in object 'prmBcClipInsert' on field 'tags': rejected value [[5,3]]; codes [typeMismatch.prmBcClipInsert.tags,typeMismatch.tags,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [prmBcClipInsert.tags,tags]; arguments []; default message [tags]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.List' for property 'tags'; nested exception is java.lang.NumberFormatException: For input string: "[5,3]"]
Why the method doesn't accept a list even though it says that it accepts a list?
ArrayList extends java.util.AbstractList and it does not implement add or remove method. Thus when this method is called on the list object, it calls to add or remove method of AbstractList class which throws this exception.
A list in Java is an interface and there are many list types that implement this interface. I will use ArrayList in the first few examples, because it is the most commonly used type of list.
List to Set in Java. Given a list (ArrayList or LinkedList), convert it into a set (HashSet or TreeSet) of strings in Java. Method 1 (Simple) We simply create an list. We traverse the given set and one by one add elements to the list. // Java program to demonstrate conversion of.
If we use Stream to convert Set to List, first, we will convert Set to stream and then convert the stream to list. It works only in Java 8 or later versions. List<String> list = set.stream ().collect (Collectors.toList ()); stream (): The method stream () returns a regular object stream of a set or list.
I was able to recreate your error case using a form validation. You are probably trying to pass a form data that is [5, 3]
for the tags
variable with type List<Long>
, but passing with brackets break that structure, the value ought to be 5, 3
...
So what I've done is;
Create a dummy controller using your input;
@Controller
public class TestController {
@PostMapping
public ModelAndView test(@Validated @ModelAttribute final PrmBcClipInsert prmBcClipInsert, final BindingResult bindingResult) {
final ModelAndView modelAndView = new ModelAndView();
System.out.println(prmBcClipInsert.getTags());
modelAndView.setViewName("test");
return modelAndView;
}
}
Pass the form with tags=[5,3]
, and get the following error in BindingResult
;
org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'prmBcClipInsert' on field 'tags': rejected value [[5, 3]]; codes [typeMismatch.prmBcClipInsert.tags,typeMismatch.tags,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [prmBcClipInsert.tags,tags]; arguments []; default message [tags]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.List' for property 'tags'; nested exception is java.lang.NumberFormatException: For input string: "[5,3]"]
Which is the identical error that you were getting... So I presume either you get this PrmBcClipInsert
as a form input like in my example, or you are trying to do a similar binding in some other part of your code...
Pass the form with tags=5,3
, no error...
There can be a custom converter to support for passing said array input with brackets in binding logic with something like;
@Component
public class LongListConverter implements Converter<String, List<Long>> {
@Override
public List<Long> convert(String source) {
return Arrays.stream(StringUtils.strip(source, "[]").split(","))
.map(StringUtils::strip)
.map(Long::new)
.collect(Collectors.toList());
}
}
With this, both 5, 3
& [5, 3]
can be supplied as value of tags
variable.
All you need is a converter here. Create a List<>String converter like below (refactor the below example in your code):
@Converter
public class StringListConverter implements AttributeConverter<List<String>, String> {
private static final String SPLIT_CHAR = ";";
// Go nuts on List to string here...
@Override
public String convertToDatabaseColumn(List<String> stringList) {
return String.join(SPLIT_CHAR, stringList.toString());
}
@Override
public List<String> convertToEntityAttribute(String string) {
return Arrays.asList(string.split(SPLIT_CHAR));
}
}
Try it and share the outcome.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With