首页 > 解决方案 > LinkedMultiValueMap SpringFramework 未迭代(错误:无法转换为类)

问题描述

我尝试使用以下方法迭代 springframework.LinkedMultiValueMap:

但先后得到错误:不能强制转换为类

这是代码:

package com.br.aloi.planner.controller;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.br.aloi.planner.model.CSVModel;
import com.br.aloi.planner.model.CSVModelAttributes;
import com.br.aloi.planner.service.CSVService;
import com.br.aloi.planner.service.MapsApiService;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import com.google.maps.errors.ApiException;

@Controller
public class CustomerController {

  String query;
  @Autowired
  private CSVService CSVservice;

  @GetMapping("/planner")
  public ModelAndView getPlanner(
        @RequestParam(value = "sortBy", defaultValue = "id", required = false) String sortParam,
        @RequestParam(value = "action", required = false) Optional<String> action)
        throws ApiException, InterruptedException, IOException {
     ModelAndView mv = new ModelAndView("/planner");
     Optional<CSVModel> csvModel = CSVservice.findById(0); //0 is just for test the linkedvaluemap

     /* this is the linkedvaluemap. Created converting a 
     "json linkedvaluemap string" to a linkedvaluemap, with gson's help. */
     @SuppressWarnings("unchecked")
     final LinkedMultiValueMap<Integer, CSVModelAttributes> attrib = new Gson().fromJson(
          (csvModel.get().getAttributes()), LinkedMultiValueMap.class);

     /* HERE i create a collection only with the values of each entry
     of linkedvaluemap. the values are a list of CSVModelAttributes */
     Collection<List<CSVModelAttributes>> valuesOfAttrib = attrib.values();

     /* HERE i run each one collections values to get the list of 
     CSVModelAttribues and after get the attribute getValue() of each model */
     for (List<CSVModelAttributes> value : valuesOfAttrib) {
        int i = 0;
        while (i < value.size()) {
          query += value.get(i).getValue() + "+";
          i++;
        }
        System.out.println(query);
        System.out.println(MapsApiService.getLat(query));
     }
     mv.addObject("csvModels", CSVservice.sortBy(csvModels, sortParam));
     return mv;

  }
}

CSVModelAttributes 类

package com.br.aloi.planner.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import com.google.gson.Gson;

@SuppressWarnings("serial")
@Entity(name = "tbl_modelAttributes")
public class CSVModelAttributes implements Serializable {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer id;
  @Column
  private Integer modelId;
  @Column(columnDefinition = "TEXT")
  private String key;
  @Column(columnDefinition = "TEXT")
  private String value;

  public CSVModelAttributes() {
  }

  public CSVModelAttributes(String key, String value) {
     this.modelId = modelId;
     this.key = key;
     this.value = value;
  }

  public Integer getId() {
     return id;
  }

  public void setId(Integer id) {
     this.id = id;
  }

  public Integer getModelId() {
     return modelId;
  }

  public void setModelId(Integer modelId) {
     this.modelId = modelId;
  }

  public String getKey() {
     return key;
  }

  public void setKey(String key) {
     this.key = key;
  }

  public String getValue() {
     return value;
  }

  public void setValue(String value) {
     this.value = value;
  }

  @Override
  public String toString() {
     return new Gson().toJson(this);
  }

}

CSVModel 类

package com.br.aloi.planner.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.validation.constraints.Size;

import lombok.AllArgsConstructor;

@SuppressWarnings("serial")
@Entity(name = "tbl_csv")
@AllArgsConstructor
public class CSVModel implements Serializable {
  @Id
  private Integer id;
  @Column(length = 1024)
  @Size(max = 1024)
  private String attributes;

  public CSVModel() {

  }

  public Integer getId() {
     return id;
  }

  public Integer setId(Integer id) {
     return this.id = id;
  }

  public String getAttributes() {
     return attributes;
  }

  public void setAttributes(String attributes) {
     this.attributes = attributes;
  }

}

错误:

java.lang.ClassCastException: class com.google.gson.internal.LinkedTreeMap cannot be cast to class com.br.aloi.planner.model.CSVModelAttributes (com.google.gson.internal.LinkedTreeMap and com.br.aloi.planner.model.CSVModelAttributes are in unnamed module of loader 'app')
    at com.br.aloi.planner.controller.CustomerController.getPlanner(CustomerController.java:63) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
    at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]

JSON 字符串

{0=[{"key":"customerId","value":"4891"}, {"key":"companyName","value":"GIOVANE FERREIRA"}, {"key":"place","value":"AV  AV TEPEQUEM                   SN"}, {"key":"neighborhood","value":"CENTRO"}, {"key":"city","value":"AMAJARI"}, {"key":"a","value":"RR"}, {"key":"postalCode","value":"69300000"}, {"key":"c","value":"ISENTO"}, {"key":"tradeName","value":"CIA DO GELO"}, {"key":"sectorId","value":"301"}, {"key":"region","value":"RR"}]}

2 天没有解决方案,我几乎要摆脱这个库并放置 apache commons 集合。

标签: javaspringweb

解决方案


@SuppressWarnings("unchecked")
     final LinkedMultiValueMap<Integer, CSVModelAttributes> attrib = new Gson().fromJson(
          (csvModel.get().getAttributes()), LinkedMultiValueMap.class);

这条线有问题。

{0=[{"key":"customerId","value":"4891"}, {"key":"companyName","value":"GIOVANE FERREIRA"}, {"key":"place","value":"AV  AV TEPEQUEM                   SN"}, {"key":"neighborhood","value":"CENTRO"}, {"key":"city","value":"AMAJARI"}, {"key":"a","value":"RR"}, {"key":"postalCode","value":"69300000"}, {"key":"c","value":"ISENTO"}, {"key":"tradeName","value":"CIA DO GELO"}, {"key":"sectorId","value":"301"}, {"key":"region","value":"RR"}]}

反序列化的消息具有不同的数据类型,然后您尝试进行类型转换。

LinkedMultiValueMap<Integer, Object> linkedHashMap = (LinkedMultiValueMap<Integer, Object>)(new Gson().fromJson(json,LinkedMultiValueMap.class));
    for(Entry<Integer, List<Object>> entry: linkedHashMap.entrySet()){
      System.out.println(entry.getValue().get(0).getClass());
    }

这段代码会打印class com.google.gson.internal.LinkedTreeMap,这清楚地表明列表中的数据类型是别的东西,那不是 CSVModelAttributes,实际上,它是TreeMap.

你应该定义一个这样的模型

public class CsvModels extends LinkedMultiValueMap<Integer, CSVModelAttributes> {}

用法:

 String json =
        "{0=[{\"key\":\"customerId\",\"value\":\"4891\"}, {\"key\":\"companyName\",\"value\":\"GIOVANE FERREIRA\"}, {\"key\":\"place\",\"value\":\"AV  AV TEPEQUEM                   SN\"}, {\"key\":\"neighborhood\",\"value\":\"CENTRO\"}, {\"key\":\"city\",\"value\":\"AMAJARI\"}, {\"key\":\"a\",\"value\":\"RR\"}, {\"key\":\"postalCode\",\"value\":\"69300000\"}, {\"key\":\"c\",\"value\":\"ISENTO\"}, {\"key\":\"tradeName\",\"value\":\"CIA DO GELO\"}, {\"key\":\"sectorId\",\"value\":\"301\"}, {\"key\":\"region\",\"value\":\"RR\"}]}";
    CsvModels models = (new Gson().fromJson(json, CsvModels.class));
    for (Entry<Integer, List<CSVModelAttributes>> entry : models.entrySet()) {
      System.out.println(entry.getKey());
      for (CSVModelAttributes attributes : entry.getValue()) {
        System.out.println("\t" + attributes);
      }
    }

推荐阅读