目前JavaFX相关的资料都是基本语法,以及界面相关。而JavaFX面向的是RIA,RIA就肯定需要和后台交互,个人研究了一下,遇到了不少问题,共享给大家
首先先看看JavaFX的api,一眼就能看到javafx.io.http包,包里面有三个类,HttpHeaders,HttpRequest,HttpStatus三个类。具体用法,呵呵,看API吧。主要使用的就是HttpRequest类了。API里也有比较详细的例子。
这里有修改此例来实现Http的get和post提交,分别和后台交互。
先写个servlet
public class MooServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {
String name = request.getParameter("name");
PrintWriter writer = response.getWriter();
writer.write("Hello "+ name);
writer.flush();
writer.close();
}
}
配置文件自己配吧。
接着编写JavaFX文件。首先以get方式提交,这个很简单。只需要一个onInput方法就够了。
import javafx.io.http.*;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.ext.swing.SwingButton;
import java.io.DataInputStream;
import javafx.scene.layout.HBox;
import javafx.ext.swing.SwingTextField;
def label:SwingTextField = SwingTextField {
columns: 10
text: "Ivan"
editable: true
}
function sendHttp(){
HttpRequest {
location:bind "http://localhost:8080/JavaScriptWeb/moo?name={label.text}";
onInput: function(is: java.io.InputStream) {
try {
def data:DataInputStream = new DataInputStream(is);
label.text = data.readLine();
} finally {
is.close();
}
}
}.enqueue();
}
Stage {
title : "Http"
scene: Scene {
width: 200
height: 200
content: [HBox{
content:[label,
SwingButton {
text: "Click"
action: function() {
sendHttp();
}
}
]
}
]
}
}
很像AJAX操作吧
运行界面如下:
这里有两个需要注意的地方。
1.location那里使用了bind关键字,如果不使用此关键字,那么name值始终是TextField的初始值,不信试试。
2.我把实例化HttpRequest以及发送包装为一个方法,因为每次发送请求都必须要重新实例化一个HttpRequest,否则报错,不信也可以试试。
其他关于onInput回调方法,自行查看API.
下面是Post提交,这个比较郁闷,如果照API上的例子,你找半天都可能不知道怎么提交,网上也没有例子。我摸索了半天才搞定。代码如下。
import javafx.io.http.*;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.ext.swing.SwingButton;
import java.io.DataInputStream;
import javafx.scene.layout.HBox;
import javafx.ext.swing.SwingTextField;
def label:SwingTextField = SwingTextField {
columns: 10
text: "Ivan"
editable: true
}
var t:String= bind "name={label.text}";
function sendHttp(){
HttpRequest {
method:HttpRequest.POST;
location:"http://localhost:8080/JavaScriptWeb/moo";
onOutput: function(os: java.io.OutputStream) {
try {
os.write(t.getBytes());
os.flush();
} finally {
os.close();
}
}
onInput: function(is: java.io.InputStream) {
try {
def data:DataInputStream = new DataInputStream(is);
label.text = data.readLine();
} finally {
is.close();
}
}
}.enqueue();
}
Stage {
title : "Http"
scene: Scene {
width: 200
height: 200
content: [HBox{
content:[label,
SwingButton {
text: "Click"
action: function() {
sendHttp();
}
}
]
}
]
}
}
看似简单。真摸索我还是摸索了半天,原因是,在API里面的例子是继承了HttpRequest,里面设置了两个header,就其中一个header害死人。如果你要post提交,将setHeader("Content-Type", "somecontent/type");这句删除,或者将其修改为setHeader("Content-Type", "application/x-www-form-urlencoded");否则后台getParameter无法取到值。
与上面相比,有三处改变。
1.location直接写地址,无须跟参数。(get和post之间的区别)
2.method:HttpRequest.POST;提交方法改为Post。
3.添加了一个onOutput方法,在其内写入参数。此处的流一定要关闭。如果不关闭,后续方法将不会执行。且此方法必须要覆盖,如果不覆盖同样的程序没有响应。
OK。现在看来JavaFX和后台交互还是很简单的吧!同时也看到了不足。类似AJAX的请求和响应,那么响应流就需要自己的组装,这个就比较麻烦了。查了些资料,JavaFX有对xml和json的支持,那么具体操作待续