我是一名应用程序程序员,正在开发我的第一个 JSF 2.0 网站,我承认我对 JSF 的了解并不多。几个月来我一直在研究文件,特别是感谢这些论坛,我还没有坚持到这一点。大部分网站已经完成并且可以正常工作,这里使用的支持 bean 在其他地方使用也没有问题。
我有一个序列化的搜索条件对象,需要通过 servlet 从小程序提交到支持 bean。支持 bean 方法然后处理搜索条件数据并将其应用于产品列表,保存在数据库中,然后在新的 JSF 页面中显示排名产品列表。
使用正确数据打开结果页面的所有尝试均失败。导航案例 "return "process_MainSearchResult";" 没有在支持 bean 中做任何事情(进一步参见支持 bean 代码和 faces-config 条目)。我尝试使用 appletContext.showDocument(见下文)从小程序打开结果页面,但新页面没有搜索条件对象传递到的支持 bean,因此没有正确的数据。
注意在小程序的setRequestMethod上设置POST是没有效果的;它总是使用服务。如果 setDoInput 和 setDoOutput 未设置为 true,并且从 servlet 向 applet 发送响应,则不会发送提交的对象,并且不会发生任何事情。我怀疑这是我问题的核心,但以任何方式更改它都会阻止序列化对象成功提交。
就目前而言,对象已成功发送到支持 bean,但新页面不会加载正确的数据(使用 applet 中的 showDocument 而不是 servlet 中的重定向)。有没有办法在新网页上设置原始支持 bean,还是我做错了?
Web 服务器是 Glassfish 3.x,IDE 是 Netbeans 7.0.1,系统是 WinXP。支持 bean 类是“ProductSelection”;servlet 类是“CriteriaServlet”。
小程序“提交搜索条件”按钮代码:
private void jButton8ActionPerformed(java.awt.event.ActionEvent evt)
{
criteriaModel.loadCodeBase();
int choice = JOptionPane.showConfirmDialog(this,
"Are you sure you want to submit your search criteria and exit the \"Customise Search Criteria\" web page?",
"Confirm Submit",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (choice == 0)
{
try
{
URL url;
url = new URL(criteriaModel.getCodeBase(), "CriteriaServlet");
System.out.println("Servlet address is: " + url);
// Get the search criteria object.
Object searchSubmitObject = criteriaModel.getObjectSlideData();
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type","application/x-java-serialized-object");
ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
out.writeObject(searchSubmitObject);
out.flush();
out.close();
out.close();
System.out.println("Object Written");
// If this and the corresponding servlet response code is removed
// then the searchSubmitObject fails to be sent.
ObjectInputStream in = new ObjectInputStream(connection.getInputStream());
String response = (String)in.readObject();
System.out.println(response);
in.close();
}
catch (MalformedURLException ex)
{
JOptionPane.showMessageDialog(jPanel8, "Submit criteria file Malformed URL."
+ ex.toString());
System.out.println("MalformedURLException occurred");
Logger.getLogger(CriteriaInterfaceView.class.getName()).log(Level.SEVERE, null, ex);
}
catch (Exception e)
{
System.out.println("Submit criteria file ERROR exception: " + e.toString());
JOptionPane.showMessageDialog(jPanel8, "Submit criteria file ERROR exception:"
+ e.toString());
}
}
// This opens a new page but with a new backing bean with the wrong data.
try
{
appletContext.showDocument(new URL(criteriaModel.getCodeBase()+"MainSearchResult.xhtml"),"_SELF");
}
catch (MalformedURLException ex)
{
Logger.getLogger(CriteriaInterfaceView.class.getName()).log(Level.SEVERE, null, ex);
}
}
我尝试使用 redirect(url) 在 servlet 中重定向但没有成功:
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
{
System.out.println("service(ServletRequest req, ServletResponse res)");
res.setContentType("application/x-java-serialized-object");
try
{
ObjectInputStream in = new ObjectInputStream(req.getInputStream());
slideData = (MultipleSlideDataObject2)in.readObject();
in.close();
if(slideData != null)
{
System.out.println("Serial number of submitted slide series is: " + slideData.getSerialNumber());
}
String temp = "Criteria file Recieved";
ObjectOutputStream outputToApplet = new ObjectOutputStream(res.getOutputStream());
outputToApplet.writeObject(temp);
outputToApplet.flush();
outputToApplet.close();
}
catch (ClassNotFoundException ex)
{
Logger.getLogger(CriteriaServlet.class.getName()).log(Level.SEVERE, null, ex);
}
FacesContext facesContext = FacesUtil.getFacesContext(req, res);
// Get the backing bean.
ProductSelection productSelection = (ProductSelection) facesContext.getApplication().evaluateExpressionGet(facesContext, "#{productSelection}", ProductSelection.class);
productSelection.submitSearchCriteriaFile(slideData);
// This throws an java.lang.IllegalStateException error.
try
{
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext extContext = context.getExternalContext();
String url = extContext.encodeActionURL(context.getApplication().getViewHandler().getActionURL(context, "/MainSearchResult.xhtml"));
extContext.redirect(url);
}
catch (IOException e)
{
throw new FacesException(e);
}
给出以下错误,因为我怀疑当前响应已经提交:
警告:StandardWrapperValve [CriteriaServlet]:PWC1406:Servlet CriteriaServlet 的 Servlet.service() 在 com.sun.faces 的 org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:522) 处抛出异常 java.lang.IllegalStateException。 context.ExternalContextImpl.redirect(ExternalContextImpl.java:572) 在 searchselection.CriteriaServlet.service(CriteriaServlet.java:217) 在 org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523) 在 org.apache.catalina .core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188) 在 org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641 ) 在 com.sun 的 com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)。Enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java: 325) 在 com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165) 在 com.sun.grizzly 的 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226) .http.ProcessorTask.invokeAdapter(ProcessorTask.java:791) 在 com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693) 在 com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954 ) 在 com.sun.grizzly.DefaultProtocolChain 的 com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)。executeProtocolFilter(DefaultProtocolChain.java:135) 在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102) 在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) 在 com.sun.grizzly.http .HttpProtocolChain.execute(HttpProtocolChain.java:76) 在 com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 在 com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 在 com.sun。 com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330) 在 com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool. java:309) 在 java.lang.Thread.run(Thread.java:619)在 com.sun.grizzly 执行(DefaultProtocolChain.java:102)在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) 在 com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) 在 com.sun.grizzly .ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 在 com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 在 com.sun.grizzly.ContextTask.run(ContextTask.java:69) 在 com.sun。 grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) at java.lang.Thread.run(Thread.java: 619)在 com.sun.grizzly 执行(DefaultProtocolChain.java:102)在 com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88) 在 com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76) 在 com.sun.grizzly .ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 在 com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 在 com.sun.grizzly.ContextTask.run(ContextTask.java:69) 在 com.sun。 grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330) at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) at java.lang.Thread.run(Thread.java: 619)76) 在 com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 在 com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 在 com.sun.grizzly.ContextTask.run(ContextTask.java :69) 在 com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) 在 java.lang 的 com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)。线程运行(线程.java:619)76) 在 com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53) 在 com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57) 在 com.sun.grizzly.ContextTask.run(ContextTask.java :69) 在 com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309) 在 java.lang 的 com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)。线程运行(线程.java:619)在 java.lang.Thread.run(Thread.java:619) 处运行(AbstractThreadPool.java:309)在 java.lang.Thread.run(Thread.java:619) 处运行(AbstractThreadPool.java:309)
返回“process_MainSearchResult”;在 backing bean 中不起作用:
public String submitSearchCriteriaFile(MultipleSlideDataObject2 slideData) throws IOException
{
System.out.println("Recieved slide series with serial number: " + slideData.getSerialNumber());
// If there is no slide data then...
if (slideData == null)
{
return "process_MainSearchResultFailed";
}
else
{
rankProducts(slideData);
}
rowStart = 0;
currentStartPage = 0;
currentPageIndex = 0;
calculateNumberPages();
SetupPaginationValues();
// Ignores this...
return "process_MainSearchResult";
}
Faces-config.xml 条目:
<navigation-rule>
<navigation-case>
<from-outcome>process_MainSearchResult</from-outcome>
<to-view-id>/MainSearchResult.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
我也在支持 bean 中尝试过这个来强制重定向:
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse)context.getExternalContext().getResponse();
try
{
response.sendRedirect("MainSearchResult.xhtml");
//response.redirect("http://localhost:8080/SearchEngineServer/faces/MainSearchResult.xhtml");
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
还有这个在backing bean中:
redirectToPage("/MainSearchResult.xhtml");
调用此方法:
private void redirectToPage(String toUrl)
{
try
{
FacesContext ctx = FacesContext.getCurrentInstance();
ExternalContext extContext = ctx.getExternalContext();
String url = extContext.encodeActionURL(ctx.getApplication().getViewHandler().getActionURL(ctx, toUrl));
extContext.redirect(url);
}
catch (IOException e)
{
throw new FacesException(e);
}
}
都给出与上面给出的 servlet 示例相同的 java.lang.IllegalStateException 错误。重定向的文档说明了这一点:
IllegalStateException - if, in a portlet environment, the current response object is a RenderResponse instead of an ActionResponse IllegalStateException - if, in a servlet environment, the current response has already been committed