JavaFX与后台交互

目前JavaFX相关的资料都是基本语法,以及界面相关。而JavaFX面向的是RIA,RIA就肯定需要和后台交互,个人研究了一下,遇到了不少问题,共享给大家 :D

首先先看看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操作吧 :D

运行界面如下:

[img]/upload/attachment/91110/42a911f7-0e9f-37e4-b837-56b016008072.jpg[/img]

这里有两个需要注意的地方。

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的支持,那么具体操作待续 :D

你可能感兴趣的:(RIA)