尝试设置列表时键入typeMismatch.java.util.List

时间:2019-07-06 07:06:42

标签: java spring spring-boot

我正在尝试为Java对象设置List<Long>

设置功能为:

ResponseEntity<String> response = bcInsertService.addNewClip(new PrmBcClipInsert()
    .setTags(Arrays.asList(new Long[]{5L, 3L}))
);

对象是

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;
    }
}

这是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;
    }

}

它返回一个错误:

  

字段“标签”上的对象“ prmBcClipInsert”中的字段错误:已拒绝   值[[5,3]];码   [typeMismatch.prmBcClipInsert.tags,typeMismatch.tags,typeMismatch.java.util.List,typeMismatch];   论点   [org.springframework.context.support.DefaultMessageSourceResolvable:   代码[prmBcClipInsert.tags,tags];参数[];预设讯息   [标签]];默认消息[无法转换类型的属性值   'java.lang.String'为属性的必需类型'java.util.List'   “标签”;嵌套的异常是java.lang.NumberFormatException:用于输入   字符串:“ [5,3]”]

为什么该方法说即使它接受列表也不能接受列表?

2 个答案:

答案 0 :(得分:9)

我能够使用表单验证来重新创建您的错误案例。您正在可能尝试传递类型为[5, 3]的{​​{1}}变量的tags表单数据,但是用方括号传递会破坏该结构,该值应该成为List<Long> ...

所以我要做的是

  1. 使用您的输入创建虚拟控制器;

    5, 3
  2. 使用@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; } } 传递表单,并在tags=[5,3]中得到以下错误;

      

    org.springframework.validation.BeanPropertyBindingResult:1个错误   字段“标签”上的对象“ prmBcClipInsert”中的字段错误:已拒绝   值[[5,3]];码   [typeMismatch.prmBcClipInsert.tags,typeMismatch.tags,typeMismatch.java.util.List,typeMismatch];   论点   [org.springframework.context.support.DefaultMessageSourceResolvable:   代码[prmBcClipInsert.tags,tags];参数[];预设讯息   [标签]];默认消息[无法转换类型的属性值   'java.lang.String'为属性的必需类型'java.util.List'   “标签”;嵌套的异常是java.lang.NumberFormatException:用于输入   字符串:“ [5,3]”]

    这与您得到的错误相同...因此,我想您要么像我的示例一样将此BindingResult作为表单输入,要么正在尝试在其中的其他部分进行类似的绑定您的代码...

  3. 使用PrmBcClipInsert传递表单,没有错误 ...


可以有一个自定义转换器来支持在绑定逻辑中将带有括号的数组输入传递给类似的东西;

tags=5,3

这样,@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()); } } 5, 3都可以作为[5, 3]变量的值来提供。

答案 1 :(得分:1)

您需要的只是这里的转换器。创建一个List <> String转换器,如下所示(在代码中重构以下示例):

@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));
    }
}

尝试一下并分享结果。