把GWT和SPRING结合使用,其中参考了yongyuan.jiang的例子,也参考网上其他人的例子,代码如下:
/**
*
*/
package org.fungchoi.server;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.WebApplicationContext;
import com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException;
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RPC;
import com.google.gwt.user.server.rpc.RPCRequest;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.google.gwt.user.server.rpc.SerializationPolicy;
import com.google.gwt.user.server.rpc.SerializationPolicyLoader;
/**
* @author dolang
*
*/
public class MyGWTServer extends RemoteServiceServlet {
private final String ACCEPT_ENCODING = "Accept-Encoding";
private final String CHARSET_UTF8 = "UTF-8";
private final String CONTENT_ENCODING = "Content-Encoding";
private final String CONTENT_ENCODING_GZIP = "gzip";
private final String CONTENT_TYPE_TEXT_PLAIN_UTF8 = "text/plain; charset=utf-8";
private final String GENERIC_FAILURE_MSG = "The call failed on the server; see server log for details";
private final ThreadLocal perThreadRequest = new ThreadLocal();
private final ThreadLocal perThreadResponse = new ThreadLocal();
private WebApplicationContext springContext;
@Override
public void init(ServletConfig Config) throws ServletException {
super.init(Config);
springContext = (WebApplicationContext) Config
.getServletContext()
.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if (springContext == null) {
throw new RuntimeException(
"Check Your Web.Xml Setting, No Spring Context Configured");
}
}
@Override
protected SerializationPolicy doGetSerializationPolicy(HttpServletRequest request,
String moduleBaseURL, String strongName) {
System.out.print("begin doGetSerializationPolicy procedure ...\n");
System.out.print("moduleBaseURL" + moduleBaseURL + "...\n");
System.out.print("strongName" + strongName + "...\n");
if (request == null) {
System.out.print("request is null...");
}
return super.doGetSerializationPolicy((HttpServletRequest) perThreadRequest.get(),
moduleBaseURL, strongName);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
System.out.print("Begin service procedure...");
perThreadRequest.set(req);
perThreadResponse.set(resp);
/*
if (req == null){
System.out.print("request is null");
}
//String pathInfo = req.getPathInfo();
//System.out.print("request path is :" + pathInfo + "........");
System.out.print("request URL is :" + req.getRequestURL() + "........");
*/
int i = req.getRequestURL().indexOf("/login");
String pathInfo = req.getRequestURL().substring(i);
//System.out.print(" the pathInfo is: " + pathInfo + "...");
while (pathInfo.startsWith("/")) {
pathInfo = pathInfo.substring(1);
}
RemoteService service = (RemoteService) springContext.getBean(pathInfo);
/*
if (service == null) {
System.out.print("get service bean fail!.....");
} else {
System.out.print("get service bean ok!......\n");
}
*/
String requestPayload = readPayloadAsUtf8(req);
// System.out.print(requestPayload + "....\n");
// Let subclasses see the serialized request.
//
onBeforeRequestDeserialized(requestPayload);
// Invoke the core dispatching logic, which returns the serialized
// result.
//
String responsePayload = processCall(service, requestPayload);
// Let subclasses see the serialized response.
//
onAfterResponseSerialized(responsePayload);
// Write the response.
//
writeResponse(req, resp, responsePayload);
} catch (Throwable e) {
// Give a subclass a chance to either handle the exception or
// rethrow it
//
doUnexpectedFailure(e);
} finally {
// HttpRequestContext.ThreadLocalHttpRequestContext.remove();
perThreadRequest.set(null);
perThreadResponse.set(null);
}
}
/**
* rewrite processCall
*
* @param bean
* @param payload
* @return
* @throws SerializationException
*/
public String processCall(RemoteService bean, String payload)
throws SerializationException {
try {
System.out.print("begin processCall procedure ...\n");
RPCRequest rpcRequest = RPC.decodeRequest(payload, bean.getClass(),
this);
return RPC.invokeAndEncodeResponse(bean, rpcRequest.getMethod(),
rpcRequest.getParameters(), rpcRequest
.getSerializationPolicy());
} catch (IncompatibleRemoteServiceException ex) {
getServletContext()
.log("An IncompatibleRemoteServiceException was thrown while processing this call.",
ex);
return RPC.encodeResponseForFailure(null, ex);
}
}
private String readPayloadAsUtf8(HttpServletRequest request)
throws IOException, ServletException {
int contentLength = request.getContentLength();
if (contentLength == -1) {
// Content length must be known.
throw new ServletException("Content-Length must be specified");
}
String contentType = request.getContentType();
boolean contentTypeIsOkay = false;
// Content-Type must be specified.
if (contentType != null) {
// The type must be plain text.
if (contentType.startsWith("text/plain")) {
// And it must be UTF-8 encoded (or unspecified, in which case we assume
// that it's either UTF-8 or ASCII).
if (contentType.indexOf("charset=") == -1) {
contentTypeIsOkay = true;
} else if (contentType.indexOf("charset=utf-8") != -1) {
contentTypeIsOkay = true;
}
}
}
if (!contentTypeIsOkay) {
throw new ServletException(
"Content-Type must be 'text/plain' with 'charset=utf-8' (or unspecified charset)");
}
InputStream in = request.getInputStream();
try {
byte[] payload = new byte[contentLength];
int offset = 0;
int len = contentLength;
int byteCount;
while (offset < contentLength) {
byteCount = in.read(payload, offset, len);
if (byteCount == -1) {
throw new ServletException("Client did not send " + contentLength
+ " bytes as expected");
}
offset += byteCount;
len -= byteCount;
}
return new String(payload, "UTF-8");
} finally {
if (in != null) {
in.close();
}
}
}
private void writeResponse(HttpServletRequest request,
HttpServletResponse response, String responsePayload) throws IOException {
byte[] reply = responsePayload.getBytes(CHARSET_UTF8);
String contentType = CONTENT_TYPE_TEXT_PLAIN_UTF8;
if (acceptsGzipEncoding(request)
&& shouldCompressResponse(request, response, responsePayload)) {
// Compress the reply and adjust headers.
//
ByteArrayOutputStream output = null;
GZIPOutputStream gzipOutputStream = null;
Throwable caught = null;
try {
output = new ByteArrayOutputStream(reply.length);
gzipOutputStream = new GZIPOutputStream(output);
gzipOutputStream.write(reply);
gzipOutputStream.finish();
gzipOutputStream.flush();
response.setHeader(CONTENT_ENCODING, CONTENT_ENCODING_GZIP);
reply = output.toByteArray();
} catch (IOException e) {
caught = e;
} finally {
if (null != gzipOutputStream) {
gzipOutputStream.close();
}
if (null != output) {
output.close();
}
}
if (caught != null) {
getServletContext().log("Unable to compress response", caught);
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
}
// Send the reply.
//
response.setContentLength(reply.length);
response.setContentType(contentType);
response.setStatus(HttpServletResponse.SC_OK);
response.getOutputStream().write(reply);
}
private boolean acceptsGzipEncoding(HttpServletRequest request) {
assert (request != null);
String acceptEncoding = request.getHeader(ACCEPT_ENCODING);
if (null == acceptEncoding) {
return false;
}
return (acceptEncoding.indexOf(CONTENT_ENCODING_GZIP) != -1);
}
}
在初始化时装入spring,在处理请求时调用服务Bean.在客户端调用服务时,与一般的调用没什么区别。
下面是客户端调用,
public LoginServiceAsync getLoginService() {
LoginServiceAsync instance = (LoginServiceAsync) GWT
.create(LoginService.class);
/*
if (instance == null) {
System.out.print("async instance is null!");
}
*/
ServiceDefTarget target = (ServiceDefTarget) instance;
System.out.print(GWT.getModuleBaseURL() + LoginService.SERVICE_URI);
target.setServiceEntryPoint(GWT.getModuleBaseURL() + LoginService.SERVICE_URI);
return instance;
}
这个方法得到异步接口,
LoginServiceAsync laa = getLoginService();
laa.IsValidateUser(tbUser.getText(), psd.getText(), new AsyncCallback(){
public void onFailure(Throwable arg0) {
// TODO Auto-generated method stub
Window.alert("Call romote service fail!");
}
public void onSuccess(Object arg0) {
// TODO Auto-generated method stub
Boolean login = (Boolean) arg0;
if (login.booleanValue()) {
Cookies.setCookie("loginPMC", tbUser.getText());
loginPanel.dispose();
createClient();
} else {
Window.alert("Login Fail! Username or password is error!");
}
}
});
这样调用就OK,比yongyuan.jiang的例子的客户端调用要简单一点。
客户端用到了一个第三方包,MyGwt,用它做的客户端要美观一些。可在它的网站上下载:www.mygwt.net
在Servic类里,调用DAO来检测登录,这里只用了很简单的实现类,也可以把它的实现类用Hibernate来实现。
附上这个工程的源码。还请大家多多指点。