简体   繁体   English

错误SessionMap无法转换为java.util.HashMap

[英]error SessionMap cannot be cast to java.util.HashMap

I am trying to store my HashMap value in session and then I am retrieving it using JSP but I am receiving an error saying 我试图将我的HashMap值存储在会话中,然后使用JSP检索它,但收到一条错误消息:

HTTP Status 500 - org.apache.struts2.dispatcher.SessionMap cannot be cast to java.util.HashMap HTTP状态500-org.apache.struts2.dispatcher.SessionMap无法转换为java.util.HashMap

Any idea why I am getting that error? 知道为什么我会收到该错误吗?

package com.action;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.BreakIterator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.action.GetCon;




public class JanuaryAction implements SessionAware{
private String name;
Map abc = new HashMap();


public Map getAbc() {
return abc;
}

public void setAbc(Map abc) {
this.abc = abc;
}


public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

@Override
public void setSession(Map abc) {
this.abc = (HashMap) abc;

}
public String execute() throws Exception{

String time=getName();
 /*   System.out.println(time);*/
if(time.equals("January 2013")){

abc.put(time,"'2013-01-01' AND OrderDate <= '2013-01-31'" );
}
else if(time.equals("February 2013")){
abc.put(time,"'2013-02-01' AND OrderDate <='2013-02-31'" );
}
else if(time.equals("March 2013")){
abc.put(time,"'2013-03-01' AND OrderDate <='2013-03-31'" );
}
else if(time.equals("April 2013")){
abc.put(time,"'2013-04-01' AND OrderDate <='2013-04-31'" );
}
else if(time.equals("May 2013")){
abc.put(time,"'2013-05-01' AND OrderDate <='2013-05-31'" );
}
else if(time.equals("June 2013")){
abc.put(time,"'2013-06-01' AND OrderDate <='2013-06-05'" );
}
String newtime=(String)abc.get(time);
   /* System.out.println(newtime);*/

Connection con = GetCon.getCon();
Statement statement = con.createStatement();
ResultSet resultset = statement.executeQuery("SELECT MarketPlace,OrderDate, ROUND(SUM(Total),2),  COUNT(*) , ROUND(ROUND(SUM(Total),2)/ COUNT(*),2) FROM vend_printed WHERE OrderDate >=" +newtime+ " GROUP BY OrderDate,MarketPlace") ;
Object value = abc.remove(time);

while(resultset.next()){

String marketplace = resultset.getString(1);

String orderdate = resultset.getString(2);

Double datamount = resultset.getDouble(3);
Integer count= resultset.getInt(4);

Double result=resultset.getDouble(5);

abc.put(0, marketplace);
abc.put(1, orderdate);
abc.put(2, datamount);
abc.put(3, count);
abc.put(4, result);}

return "success";
}}

In my JSP, I wanted to display the loop values one by one. 在我的JSP中,我想一一显示循环值。 so i am using this code now, but it is not displaying anything. 所以我现在正在使用此代码,但未显示任何内容。

<s:property value="#session.0" /><br><br><br>
<s:property value="#session.1" /><br><br><br>
<s:property value="#session.2" /><br><br><br>
<s:property value="#session.3" /><br><br><br>
<s:property value="#session.4" /><br><br><br>   

Problem is here: 问题在这里:

@Override
public void setSession(Map abc) {
  //abc is actually a SessionMap, which is not a HashMap !
  this.abc = (HashMap) abc;
}

because you suppose that abc is an HashMap , which is wrong. 因为您认为abcHashMap ,所以这是错误的。 It is actually a SessionMap (that's what the error message says). 它实际上是一个SessionMap (这就是错误消息所显示的内容)。 SessionMap does not extends HashMap , it extends AbstractMap which directly extends Object . SessionMap没有扩展HashMap ,而是扩展了AbstractMap ,后者直接扩展了Object

See : http://struts.apache.org/release/2.0.x/struts2-core/apidocs/org/apache/struts2/dispatcher/SessionMap.html 参见: http : //struts.apache.org/release/2.0.x/struts2-core/apidocs/org/apache/struts2/dispatcher/SessionMap.html

Basically, when you implements SessionAware you suppose that the Map will be an HashMap , which is absolutely not guaranteed and is indeed not the case. 基本上,当您implements SessionAware您假设Map将是HashMap ,这是绝对不能保证的,实际上并非如此。

I suggest you to replace the attribute definition : 我建议您替换属性定义:

HashMap abc = new HashMap();

With: 附:

private Map abc; //Don't initialize it as it is done by the setter.

The problem lies here: 问题出在这里:

@Override
public void setSession(Map abc) {
    this.abc = (HashMap) abc;
}

You are casting a Map which is an interface to HashMap , a concrete implementation. 您正在投射一个Map ,它是HashMap的接口, HashMap是一个具体的实现。 This cast is unsafe since you don't know for sure which type the abc is. 这种转换是不安全的,因为您不确定abc是哪种类型。 It can be any of SessionMap , TreeMap , LinkedHashMap , etc. 它可以是SessionMapTreeMapLinkedHashMap等中的任何一个。

Since the setSession has been defined to take a Map , so you should either use that Map or create a new one. 由于setSession已定义为采用Map ,因此您应该使用该Map或创建一个新Map

public class JanuaryAction implements SessionAware{
    private String name;
    Map abc = new HashMap(); // Use the interface Map instead of a concrete implementation

    @Override
    public void setSession(Map abc) {
        // this.abc = abc; // you can do this
        this.abc = new HashMap(abc); // prefer to do this
    }
}

This is a SessionAware implementation, use it 这是一个SessionAware实现,请使用它

private Map<String, Object> session;

@Override
public void setSession(Map<String, Object> session) {
 this.session = session;
}

in the execute create a new collection with values and put into the session map. execute创建一个带有值的新集合,并将其放入会话映射。 The problem with your code you are reusing the same variable abc that initially used to build the query. 您的代码存在问题,您正在重新使用最初用于构建查询的变量abc You should create another one and use the List instead of Map to keep the order of the items you want to iterate and display in JSP. 您应该创建另一个对象,并使用List而不是Map来保留要迭​​代并在JSP中显示的项目的顺序。 Better to create and use the class that you should populate from the ResultSet and populate it into the list. 最好创建并使用应从ResultSet填充的类,并将其填充到列表中。

public class Market {
  private String marketplace;  
  private String orderdate;  
  private Double datamount;
  private Integer count;  
  private Double result;

  public String getMarketplace() {
    return marketplace;
  }

  public void setMarketplace(String marketplace) {
    this.marketplace = marketplace;
  }

  public String getOrderdate() {
    return orderdate;
  }

  public void setOrderdate(String orderdate) {
    this.orderdate = orderdate;
  }

  public Double getDatamount() {
    return datamount;
  }

  public void setDatamount(Double datamount) {
    this.datamount = datamount;
  }

  public Integer getCount() {
    return count;
  }

  public void setCount(Integer count) {
    this.count = count;
  }

  public Double getResult() {
    return result;
  }

  public void setResult(Double result) {
    this.result = result;
  }

  public Market(String marketplace, String orderdate, Double datamount, Integer count, Double result) {
    this.marketplace = marketplace;
    this.orderdate = orderdate;
    this.datamount = datamount;
    this.count = count;
    this.result = result;
  }

}   

create the property to hold the results 创建属性以保存结果

@Element(value = Market.class)
private List<Market> markets = new ArrayList<>();

public List<Market> getMarkets() {
  return markets;
}

public void setMarkets(List<Market> markets) {
  this.markets = markets;
}

to populate the list you should use this block, I don't know how do you use the connection, so I didn't close it. 要填充您应该使用此块的列表,我不知道您如何使用该连接,因此没有关闭它。

Connection con = GetCon.getCon();
Statement statement = con.createStatement();
try {
  ResultSet resultset = statement.executeQuery("SELECT MarketPlace,OrderDate, ROUND(SUM(Total),2),  COUNT(*) , ROUND(ROUND(SUM(Total),2)/ COUNT(*),2) FROM vend_printed WHERE OrderDate >=" +newtime+ " GROUP BY OrderDate,MarketPlace") ;
  while(resultset.next()){
  markets.add(new Market(
    resultset.getString(1),
    resultset.getString(2),
    resultset.getDouble(3),
    resultset.getInt(4),
    resultset.getDouble(5)
  ));
  }
} finally {
  try {
    statement.close();
  } catch (SQLException e) {}
}

} }

now to keep the results in session 现在将结果保持在会话中

session.put("markets", markets);

in the JSP use the iterator tag, and you are not required to iterate the session object, just get it from action. 在JSP中,使用iterator标记,您不需要迭代会话对象,只需从操作中获取它即可。

<s:iterator value="markets">
  Marketplace: <s:property value="marketplace" /><br> 
  Orderdate: <s:property value="orderdate" /><br>  
  Datamount: <s:property value="datamount" /><br>
  Count: <s:property value="count" /><br>  
  Result: <s:property value="result" /><br>
  <hr>
</s:iterator>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 FlexJson 错误:ClassCastException:java.util.HashMap 无法转换为类 - FlexJson Error : ClassCastException: java.util.HashMap cannot be cast to class 无法将java.util.HashMap强制转换为java.util.ArrayList - java.util.HashMap cannot be cast to java.util.ArrayList java.util.hashmap无法转换为java.util.list - java.util.hashmap cannot be cast to java.util.list SDN4:ClassCastException:无法将java.util.HashMap强制转换为[EntityNode] - SDN4: ClassCastException: java.util.HashMap cannot be cast to [EntityNode] java.util.HashMap 不能投(android studio, firebase,java) - java.util.HashMap cannot be cast (android studio, firebase,java) java.lang.ClassCastException: java.util.HashMap$EntrySet 不能转换为 java.util.Map$Entry - java.lang.ClassCastException: java.util.HashMap$EntrySet cannot be cast to java.util.Map$Entry java.lang.ClassCastException:java.util.HashMap $ EntrySet无法转换为java.util.HashSet - java.lang.ClassCastException: java.util.HashMap$EntrySet cannot be cast to java.util.HashSet Android java.util.hashmap无法转换为java.util.list - Android java.util.hashmap cannot be cast to java.util.list Rest Assured java.util.HashMap cannot be cast to class java.util.List - Rest Assured java.util.HashMap cannot be cast to class java.util.List java.lang.ClassCastException:无法将java.util.HashMap强制转换为java.lang.String - java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM