我有很简单的JSF的bean如下所示:
import org.jboss.seam.annotations.Name;
@Name(Sample.NAME)
public class Sample {
public static final String NAME="df";
private String text = "text-test";
public void sampleM(){
System.out.println("Test: "+text);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
和JSF形式与该组件相连:
<h:form id="sampleForm">
<h:commandButton id="sampleButton" action="#{df.sampleM()}" value="ok" />
</h:form>
现在,我想以编程方式发送POST请求这种形式。
据笔者调查,这里的关键是POST参数。 正确选择恰当给出结果(字符串“测试:文本测试”打印serwer控制台上)。
所以,问题是: 我应该如何选择是正确的POST数据?
如上所示JSF形式产生该HTML形式:
<form id="sampleForm" name="sampleForm" method="post" action="/pages/main/main.smnet" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="sampleForm" value="sampleForm" />
<input id="sampleForm:sampleButton" type="submit" name="sampleForm:sampleButton" value="ok" />
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="j_id65" autocomplete="off" />
</form>
因此,这些参数是corrent。
但我怎么能找出什么参数(名称和值)将足以对任何其他组件?
例如:当我在所示HTML形式但具有不同的“javax.faces.ViewState”参数值发送POST数据相同的像,组件的方法将不被执行。
据我所知,你基本上是问如何以编程方式提交JSF表单使用的HTTP客户端,如java.net.URLConnection
或Apache HttpComponents客户,对不对?
您需要先发送一个GET请求,并确保你保持相同的HTTP会话(基本上, JSESSIONID
跨请求的cookie)。 让你的HTTP客户端提取Set-Cookie
从第一个GET请求的响应头,获得JSESSIONID
从它的cookie,并发送回作为Cookie
后续POST请求的报头。 这将保持在服务器端的HTTP会话,否则JSF将把它作为一个“查看过期”可能一个HTTP 500错误页面,在回报上一个体面的配置JSF的Web应用程序ViewExpiredException
,或错误配置JSF的Web应用程序的行为作为刷新页面。
作为JSF的状态自然的一部分,并暗示CSRF攻击防范,形式必须与有效提交javax.faces.ViewState
值作为客户端获取自己的初始GET请求。 你还需要确保您发送的name=value
对所有其他隐藏的领域和特别的提交按钮沿以及之一。
所以,如果您最初的GET请求给你这个HTML回
<form id="sampleForm" name="sampleForm" method="post" action="/pages/main/main.smnet" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="sampleForm" value="sampleForm" />
<input id="sampleForm:sampleButton" type="submit" name="sampleForm:sampleButton" value="ok" />
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="j_id65" autocomplete="off" />
</form>
那么你需要分析它( Jsoup可能在这个有用),并提取了以下请求参数:
-
sampleForm=sampleForm
-
sampleForm:sampleButton=ok
-
javax.faces.ViewState=j_id65
最后,在发送POST请求/pages/main/main.smnet
与这些人恰恰是请求参数(和JSESSIONID
cookie的!)。 不过要小心,它可能是一个(差)JSF开发者已经跳过如id="sampleButton"
从<h:commandButton>
,然后将JSF自动生成一个看起来像这种格式sampleForm:j_id42
。 你不能硬编码它们作为值可能取决于组件在服务器端树中的位置发生变化,那么你就真的需要解析它把获得的HTML。
然而,这是明智的联系网站所有者/管理员并询问是否有不适用于你心目中的任务Web服务API。 一个体面的Java EE的网站,使用JSF应用程序的HTML前端通常还采用了REST前端独立JAX-RS应用程序。
也可以看看:
- 我如何可以通过编程将文件上传到一个网站吗? (这还涉及JSF)
- 使用java.net.URLConnection中的火灾和处理HTTP请求
文章来源: How to programmatically send POST request to JSF page without using HTML form?