#model #wicket #string-conversion
#Модель #калитка #преобразование строки
Вопрос:
Я изучаю Wicket по книге «Наслаждаюсь веб-разработкой с помощью Wicket».Это написано для Wicket 1.4.7
И в примере:
int weight = ((Integer) weightModel.getObject()).intValue();
используется. Когда я нажимаю кнопку Отправки, она выдает неожиданное исключение RuntimeException в первых строках:
Wicket Message: метод onFormSubmitted интерфейса org.apache.калитка.разметка.html.форма.IFormSubmitListener, предназначенный для компонента [MarkupContainer [Идентификатор компонента = форма]], выдал исключение
Основная причина:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer*
Вероятно, weightModel.GetObject() не удалось преобразовать в строку.
Полное сообщение об исключении находится внизу.
Но после изменения кода на:
int weight=Integer.parseInt( (String) weightModel.getObject());
Это работает нормально. Предполагается, что все работает нормально. В чем причина возникновения исключения?
Полный код:
GetRequest.java
package myapp.postage;
import java.util.HashMap;
import java.util.Map;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.Model;
@SuppressWarnings("unchecked")
public class GetRequest extends WebPage {
private Model weightModel=new Model();
private Model patronCodeModel=new Model();
private Map patronCodeToDiscount;
public GetRequest(){
patronCodeToDiscount=new HashMap();
patronCodeToDiscount.put("p1", new Integer(90));
patronCodeToDiscount.put("p2", new Integer(95));
Form form=new Form("form"){
@Override
protected void onSubmit(){
int weight = ((Integer) weightModel.getObject()).intValue();
Integer discount=(Integer)patronCodeToDiscount.get(patronCodeModel.getObject());
int postagePerKg=10;
int postage=weight*postagePerKg;
if(discount!=null){
postage=postage*discount.intValue()/100;
}
ShowPostage showPostage=new ShowPostage(postage);
setResponsePage(showPostage);
}
};
TextField weight=new TextField("weight",weightModel);
form.add(weight);
TextField patronCode=new TextField("patronCode",patronCodeModel);
form.add(patronCode);
add(form);
}
}
HTML-файл GetRequest.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<form wicket:id="form">
<table>
<tr>
<td>Weight</td>
<td><input type="text" wicket:id="weight"/></td>
</tr>
<tr>
<td>Patron code:</td>
<td><input type="text" wicket:id="patronCode"/></td>
</tr>
<tr>
<td></td>
<td><input type="submit"/></td>
</tr>
</table>
</form>
</html>
Сообщение об исключении:
Wicket Message: метод onFormSubmitted интерфейса org.apache.калитка.разметка.html.форма.IFormSubmitListener, предназначенный для компонента [MarkupContainer [Идентификатор компонента = форма]], выдал исключение
Основная причина:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at myapp.postage.GetRequest$1.onSubmit(GetRequest.java:26)
at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1538)
at org.apache.wicket.markup.html.form.Form.process(Form.java:934)
at org.apache.wicket.markup.html.form.Form.onFormSubmitted(Form.java:896)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:182)
at org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents(ListenerInterfaceRequestTarget.java:73)
at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92)
at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479)
at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:312)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at com.springsource.insight.collection.tcserver.request.HttpRequestOperationCollectionValve.invoke(HttpRequestOperationCollectionValve.java:60)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:379)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Complete stack:
org.apache.wicket.WicketRuntimeException: Method onFormSubmitted of interface org.apache.wicket.markup.html.form.IFormSubmitListener targeted at component [MarkupContainer [Component id = form]] threw an exception
at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:193)
at org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents(ListenerInterfaceRequestTarget.java:73)
at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92)
at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479)
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:182)
at org.apache.wicket.request.target.component.listener.ListenerInterfaceRequestTarget.processEvents(ListenerInterfaceRequestTarget.java:73)
at org.apache.wicket.request.AbstractRequestCycleProcessor.processEvents(AbstractRequestCycleProcessor.java:92)
at org.apache.wicket.RequestCycle.processEventsAndRespond(RequestCycle.java:1250)
at org.apache.wicket.RequestCycle.step(RequestCycle.java:1329)
at org.apache.wicket.RequestCycle.steps(RequestCycle.java:1428)
at org.apache.wicket.RequestCycle.request(RequestCycle.java:545)
at org.apache.wicket.protocol.http.WicketFilter.doGet(WicketFilter.java:479)
Комментарии:
1. Какую версию Wicket вы используете? Начиная с версии 1.4, вы можете и должны использовать обобщения. Кроме того, можете ли вы показать код, который вы используете для добавления полей формы?
2. Ах, я вижу код, извините. я размещал со своего телефона и не мог прокручивать.
Ответ №1:
Если вы используете Wicket 1.4 и выше, вам следует использовать обобщенные файлы и использовать их, чтобы указать wicket, какой тип вы ожидаете. Затем Wicket выполнит преобразование за вас.
Я бы предложил следующие изменения (для веса другое поле оставлено в качестве упражнения ;)):
Добавьте на свою страницу поле, которое будет содержать ввод пользователя:
private Integer weight;
Добавьте средство получения и установки для этого поля:
public Integer getWeight() {return weight;}
public void SetWeight(Integer weight) {this.weight = weight;}
Затем замените код для добавления текстового поля для weight на:
form.add(new TextField<Integer>("weight"
, new PropertyModel<Integer>(this, "weight"));
С помощью этого Wicket преобразует пользовательский ввод в целое число и сохранит его в поле weight . PropertyModel использует саму страницу для доступа к полю.
Надеюсь, это поможет.
Подсказка: в случае, если пользователь вводит что-то, что не может быть преобразовано, Wicket добавит ошибку в текстовое поле. Вы должны добавить панель обратной связи на свою страницу, чтобы увидеть это.
Наслаждайтесь
Комментарии:
1. вы уверены, что вам понадобится setter getter?
2. Не полностью. но я помню, что получал исключения без
3. Я переписал код, и он отлично сработал. Я действительно не знаю, почему это не сработало.
4. Wicket не будет выполнять преобразование только с угловыми скобками, потому что это невозможно. В общих файлах Java используются удаления, и эта информация общего типа сохраняется во время выполнения. Вы должны предоставить правильно типизированный «серверную часть» модели (например, свойство, как в вашем примере) для правильной работы преобразования, явно предоставить компоненту конвертер или указать компоненту, в какой тип преобразовать, если конкретный компонент поддерживает это (TextField поддерживает передачу его в конструкторе).
Ответ №2:
Какое целое число возвращает функция, которая работает? И какое исключение выдает?
Если оно равно нулю, возможно, GetObject() вообще не возвращает целое число.
Комментарии:
1. в процессе: int weight = ((целое число) weightModel.GetObject()).intValue();
2. и GetObject обязательно возвращает целое число
Ответ №3:
Вероятно, weightModel.GetObject() не удалось преобразовать в строку.
нет. возвращаемый объект представляет собой строку, а не целое число, как вы хотите, с приведением целого числа.
одним из решений было бы проанализировать возвращаемую строку Integer.parseInt(str) (но я думаю, что wicket может сделать это за вас …)
Комментарии:
1. Я переписал код, и он отлично сработал. Я действительно не знаю, почему это не сработало