GWT / GXT ClassCastException

问题描述 投票:0回答:1

这会很长。

免责声明:这具体是我从前任继承的工作代码,所以我不知道为什么某些部分是这样编码的,只是它们确实如此。这是我没有完全理解其意图以及所使用的一些语法,因此这篇文章。如果可能的话,我宁愿不编辑导致问题的主文件之外的任何内容。 (我已经收到足够多的回复询问为什么我的代码是这样编写的,但没有回答这个让我有点烦恼的问题)

该程序的基本功能是从 SQL 表中读取数据并将其填充到屏幕上。然后,用户可以编辑几个字段并更新它;将其保存到数据库以供将来参考,或在数据库中创建新条目。

据我了解:-

  • 创建:在表 A 中创建一个新条目。
  • 编辑:根据表 A 的数据在表 B 中创建一个新条目。
  • 保存编辑:表 B 中的数据将用于替换表 A 中的数据。

表 A 和表 B 虽然总体不同,但都有一些相似的列,可以相互引用(未明确定义)

该程序通常运行良好,但是当我将表 B 中特定列的数据类型从 int 更改为 bigint 并访问现有数据的编辑屏幕时,我开始收到异常消息和函数中断(尽管整个程序仍然有效)。

错误消息仅出现在浏览器控制台日志中,指向cache.html中的一行。此错误在 2 个不同的浏览器(Chrome 和(IE 模式)Edge)中持续存在。

表 A 也有一个类似的列,声明为 int 并且存储过程通常在查询中引用它,所以我认为可能存在一些转换问题,但即使在将两个表中两列的数据类型都转换为 bigint 之后,错误仍然存在。

经过进一步检查,问题发生在表B中列的数据类型从int更改为bigint时。当我尝试将表 A 中的相关列从 int 更改为 bigint 进行匹配(不更改表 B 中列的数据类型)时,没有任何问题。

在 Java 之上,代码库还使用 GWT (2.4) 来填充屏幕,(编辑过的)相关代码包括:

客户端:

private StackTraceElement[] newResult;
    protected void setNewStackTrace(StackTraceElement[] result){
        Log.debug("Ex setNewStackTrace! " + result);
        newResult = result;
    }
protected void buildScreen() {
    
    try {
        GWT.setUncaughtExceptionHandler(new
             GWT.UncaughtExceptionHandler() {
             public void onUncaughtException(Throwable e) {
                Log.debug("Ex caught!", e);
                Log.debug("Ex getCause: ", e.getCause());
                try {               <Service>.Util.getInstance().getDeobfuscateStackTrace(e.getStackTrace(), new AsyncCallback<StackTraceElement[]>() {
                        public void onSuccess(StackTraceElement[] result) {
                            setNewStackTrace(result);
                        }
                        public void onFailure(Throwable caught) {
                            WidgetUtils.handleError(caught);
                        }
                    });
                } catch (ApplicationException e1) {
                    // TODO Auto-generated catch block
                    Log.debug("Ex ApplicationException: ", e1);
                    e1.printStackTrace();
                }
                e.setStackTrace(newResult);
            }
         });

        prepareGrid();
        (...)
        prepareMainButtons();
        (...)
        prepareFormBinding();
        (...)
        });
        layout();
    } catch (Exception e) {
        AppsUtil.handleError(e);
    }
}

(...)
private DbQuery QUERY = new DbQuery();
private PagingGridHelper<BaseModel> grid;
private String SELECTED_REPORT;
private Boolean LOADED = false;

private void prepareGrid() {
    try {
        QUERY.set_auditDbTable("<SQL Table>");
        QUERY.setTableName("<Stored Procedure>");

        List<ColumnConfig> columns = getColumns();
        
        RpcProxy<PagingLoadResult<? extends ModelData>> proxy = new RpcProxy<PagingLoadResult<? extends ModelData>>() {
                protected void load(Object loadConfig, AsyncCallback<PagingLoadResult<? extends ModelData>> callback) {
                    
                    if (SELECTED_REPORT == null) {
                        if (LOADED)
                        callback.onSuccess(new BasePagingLoadResult<BaseModel>( new ArrayList<BaseModel>() ));
                    } else {
                        FilterPagingLoadConfig conf = (FilterPagingLoadConfig) loadConfig;
                        DbQueryService.Util.getInstance().selectPage(QUERY, conf, callback);
                    }
                }
        };

        (...)
        String columnData="";
        for (int x=0; x<columns.size();x++){
            columnData+=columns.get(x).getHeader() + ", ";
        }
        grid =  new PagingGridHelper<BaseModel>(QUERY, columns, proxy, DOWNLOAD, false);
        (...)
        });
    } catch (Exception e) {
        AppsUtil.handleError(e);
    }
}

private void prepareMainButtons() throws Exception {
    (...)
    EDIT = SWUtil.createButton(SWButton.EDIT);
    EDIT.addSelectionListener(new SelectionListener<ButtonEvent>() {
        public void componentSelected(ButtonEvent ce) {
            (...)
            if (grid.getSelectionModel().getSelection().size() == 1) {
                (...)
                switchMode(Mode.DataEdit, false);
                // related to issue
                formBinding.bind((BaseModel) grid.getSelectionModel().getSelection().get(0)); 
            }
        }
    });

    (...)
}


private void prepareFormBinding() {
    try{
    formBinding = new FormBinding(EditorForm, true);
    formBinding.setStore(new ListStore<BaseModel>());

    formBinding.addListener(Events.BeforeBind, new Listener<BindingEvent>() {
        public void handleEvent(BindingEvent be) {
            forceReset();
            deselectAllCurrency();
            EditorForm.reset();
            (...)
        }
    });

    formBinding.addListener(Events.Bind, new Listener<BindingEvent>() {
        (...)
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    formBinding.addListener(Events.UnBind, new Listener<BindingEvent>() {
        (...)
    }
    catch(Exception e){
        e.printStackTrace();
    }
    
}


public PagingGridHelper(DbQuery dquery, List<ColumnConfig> uColumns, RpcProxy<PagingLoadResult<? extends ModelData>> uproxy, final BaseDownload download, boolean checkable) {
        this.query = dquery;
        this.columns = uColumns;
        this.proxy = uproxy;
        this.checkable = checkable;
        
        try {
            if (query == null)
                query = new DbQuery();
            
            (...)
            columnModel = new ColumnModel(columns);


            if (proxy == null) {
                proxy = new RpcProxy<PagingLoadResult<? extends ModelData>>() {
                    protected void load(Object loadConfig, AsyncCallback<PagingLoadResult<? extends ModelData>> callback) {
                        FilterPagingLoadConfig conf = (FilterPagingLoadConfig) loadConfig;
                        DbQueryService.Util.getInstance().selectAsPage(query, conf, callback);
                    }
                };
            }
            
            loadConfig = new BaseFilterPagingLoadConfig(0, pageSize);
            loader = new BasePagingLoader<PagingLoadResult<D>>(proxy) {
                protected Object newLoadConfig() {
                    return loadConfig;
                }
            };

            loader.setRemoteSort(true);
            loader.setReuseLoadConfig(true);

            store = new ListStore<D>(loader);
            store.addListener(Store.DataChanged, new Listener<StoreEvent<? extends ModelData>>() {
                public void handleEvent(StoreEvent<? extends ModelData> be) {
                    for (ModelData d : store.getModels()) {
                        (...)
                    }
                }
            });

            (...)
            
            grid = new Grid<D>(store, columnModel);
            (...)
            grid.setLoadMask(true);
            grid.setBorders(true);
            
            (...)
            
            grid.addListener(Events.Attach, new Listener<BaseEvent>() {
                public void handleEvent(BaseEvent be) {
                    loader.load(0, pageSize);
                }
            });
            
        } catch (Exception e) {
            GWT.log(e.getMessage(), e);
        }
    }

服务器端:

@Override
    public StackTraceElement[] getDeobfuscateStackTrace(StackTraceElement[] e) throws ApplicationException {
        // TODO Auto-generated method stub
        StackTraceDeobfuscator testDeobfuscator = new StackTraceDeobfuscator("war/WEB-INF/deploy/<project>/symbolMaps/");
        String strongName = request.getHeader(RpcRequestBuilder.STRONG_NAME_HEADER);
        return testDeobfuscator.deobfuscateStackTrace(e, strongName);
    }

过了很长一段时间,我想我终于找到了问题的在哪里

formBinding.bind((BaseModel) grid.getSelectionModel().getSelection().get(0));

好像和这个有关(准确的说,这部分没有命中)

formBinding.addListener(Events.Bind, new Listener<BindingEvent>() {
    @SuppressWarnings("rawtypes")
    public void handleEvent(BindingEvent be) {
        (...)
        } catch (Exception e) {
        e.printStackTrace();
        }
    }

但我仍然不知道为什么,以及如何解决它。有什么想法吗?

如前所述,唯一改变的是表 B 中特定列的数据类型。此外,整个程序在 Chrome 和(IE 模式)Edge 中都按预期工作。

编辑2023年7月28日

通读 GWT 文档,并尝试理解抛出的异常。

我得到这个是由于添加了上面的

GWT.setUncaughtExceptionHandler

编辑 4/8/2023

<style>PRETTY</style> 中实施

pom.xml
后更新异常图像。

编辑 7/8/2023

<style>DETAILED</style> 中实施

pom.xml
后更新异常图像。

以及在我的 .gwt.xml 文件中添加以下内容:

以及我的 web.xml 中的以下内容

<servlet> <servlet-name>remoteLogging</servlet-name> <servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl</servlet-class> </servlet> <servlet-mapping> <servlet-name>remoteLogging</servlet-name> <url-pattern>/<project>/remote_logging</url-pattern> </servlet-mapping>


java mysql gwt gxt
1个回答
0
投票
selectAsPage

功能。

浏览其中的代码后,发现问题与实用程序函数之一有关,该函数处理从数据库查询读取的结果并将其转换为更标准化的 java 数据。

public static <D extends BaseModel> void processRow(ResultSet rs, List<D> rows, D model) throws SQLException { StringBuffer sb = new StringBuffer(); if (model == null) model = (D) new BaseModel(); for (int i = 1 ; i <= rs.getMetaData().getColumnCount() ; i++) { String column = rs.getMetaData().getColumnName(i); if (rs.getMetaData().getColumnType(i) == Types.INTEGER) { model.set(column, rs.getInt(i) ); } else if (rs.getMetaData().getColumnType(i) == Types.BIGINT) { model.set(column, rs.getBigDecimal(i).toBigInteger() ); } else if(rs.getMetaData().getColumnType(i) == Types.NVARCHAR) { model.set(column, rs.getString(i)); } else if (rs.getMetaData().getColumnType(i) == Types.TIMESTAMP) { model.set(column, Misc.getTimestamp(rs, i) ); } else if (rs.getMetaData().getColumnType(i) == Types.FLOAT) { model.set(column, new Double( rs.getFloat(i)) ); } else if (rs.getMetaData().getColumnType(i) == Types.DOUBLE) { model.set(column, new Double( rs.getFloat(i)) ); } else if (rs.getMetaData().getColumnType(i) == Types.DECIMAL) { Double d = new Double( rs.getDouble(i) ); model.set(column, d.doubleValue() ); } else if (rs.getMetaData().getColumnType(i) == Types.BIT) { model.set(column, rs.getInt(i) ); } else { model.set(column, rs.getString(i) ); } sb.append(column + "=" + rs.getString(i) + "; type=" + rs.getMetaData().getColumnType(i)); } rows.add( model );

具体来说,这个部分原本并不存在。

else if (rs.getMetaData().getColumnType(i) == Types.BIGINT) { model.set(column, rs.getBigDecimal(i).toBigInteger() ); }

因此代码无法正确处理 
BigInt

值;结果默认值为

String
,最终会导致前面提到的
ClassCastException
问题。
一旦我添加了这个代码块(并修改了一些东西来适应它),问题或多或少就消失了。

这令人沮丧地花了我太长时间才确定。

© www.soinside.com 2019 - 2024. All rights reserved.