Hide
Meet people who work on similar things as you – get help if you need it Join Siafoo Now or Learn More

GWT Proxy Servlet Atom Feed 0

In Brief A servlet designed to get around the Same Origin Policy restriction for POSTing forms or parsing JSON while developing a Google Web Toolkit (GWT) based webapp. It is most useful when the backend for your application is running under some other local server (like the paste server).... more
# 's
  1package my.package;
2
3/**
4 * Copyright 2009 Stou Sandalski (Siafoo.net)
5 * Copyright 1999-2008 The Apache Software Foundation
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21import java.io.IOException;
22import java.io.InputStream;
23import java.io.OutputStream;
24import java.util.Enumeration;
25
26import javax.servlet.ServletException;
27import javax.servlet.http.HttpServlet;
28import javax.servlet.http.HttpServletRequest;
29import javax.servlet.http.HttpServletResponse;
30import java.io.BufferedReader;
31import java.io.BufferedWriter;
32import java.io.InputStreamReader;
33import java.io.OutputStreamWriter;
34import java.util.ArrayList;
35import java.util.List;
36
37import org.apache.http.HttpEntity;
38import org.apache.http.HttpResponse;
39import org.apache.http.NameValuePair;
40import org.apache.http.client.HttpClient;
41import org.apache.http.client.entity.UrlEncodedFormEntity;
42import org.apache.http.client.methods.HttpGet;
43import org.apache.http.client.methods.HttpPost;
44import org.apache.http.client.methods.HttpRequestBase;
45import org.apache.http.impl.client.DefaultHttpClient;
46import org.apache.http.message.BasicNameValuePair;
47import org.apache.http.protocol.HTTP;
48
49public class ProxyServlet extends HttpServlet {
50
51 /**
52 *
53 */
54 private static final long serialVersionUID = 8L;
55
56 private static final String targetServer = "http://localhost:5000";
57
58 @Override
59 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
60 handleRequest(req, resp, false);
61 }
62
63 @Override
64 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
65 handleRequest(req, resp, true);
66 }
67
68 @SuppressWarnings("unchecked")
69 protected void handleRequest(HttpServletRequest req, HttpServletResponse resp, boolean isPost) throws ServletException, IOException {
70
71 HttpClient httpclient = new DefaultHttpClient();
72
73 StringBuffer sb = new StringBuffer();
74
75 sb.append(targetServer);
76 sb.append(req.getRequestURI());
77
78 if(req.getQueryString() != null){
79 sb.append("?" + req.getQueryString());
80 }
81
82 HttpRequestBase targetRequest = null;
83
84 if(isPost){
85 System.out.println("POST");
86 HttpPost post = new HttpPost(sb.toString());
87
88 Enumeration<String> paramNames = req.getParameterNames();
89
90 String paramName = null;
91
92 List <NameValuePair> params = new ArrayList <NameValuePair>();
93
94 while(paramNames.hasMoreElements()){
95 paramName = paramNames.nextElement();
96 params.add(new BasicNameValuePair(paramName, req.getParameterValues(paramName)[0]));
97 }
98
99 post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
100 targetRequest = post;
101 }else{
102 System.out.println("GET");
103
104 HttpGet get = new HttpGet(sb.toString());
105 targetRequest = get;
106 }
107
108// // This copies the headers but I never really cared to get it to work properly
109// System.out.println("Request Headers");
110// Enumeration<String> headerNames = req.getHeaderNames();
111// String headerName = null;
112// while(headerNames.hasMoreElements()){
113// headerName = headerNames.nextElement();
114// targetRequest.addHeader(headerName, req.getHeader(headerName));
115// System.out.println(headerName + " : " + req.getHeader(headerName));
116// }
117
118 HttpResponse targetResponse = httpclient.execute(targetRequest);
119 HttpEntity entity = targetResponse.getEntity();
120
121 // Send the Response
122 InputStream input = entity.getContent();
123 OutputStream output = resp.getOutputStream();
124
125 BufferedReader reader = new BufferedReader(new InputStreamReader(input));
126 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
127 String line = reader.readLine();
128
129 while(line != null){
130 writer.write(line + "\n");
131 line = reader.readLine();
132 }
133
134 reader.close();
135 writer.close();
136 httpclient.getConnectionManager().shutdown();
137 }
138
139}

A servlet designed to get around the Same Origin Policy restriction for POSTing forms or parsing JSON while developing a Google Web Toolkit (GWT) based webapp. It is most useful when the backend for your application is running under some other local server (like the paste server).

Warning

Using this servlet has the potential to break parts of your application or expose you to bad things! You should know what you are doing! Use it for DEVELOPMENT ONLY!

The servlet will proxy a call like http://localhost:8080/foo/bar/baz to another server http://localhost:5000/foo/bar/baz.

Download the example project, run it and then open http://localhost:8080/search?q=cosmological+constant to see something like:

http://www.siafoo.net/image/175?w=400

To install it you must:

  1. Add the servlet to the tomcat/webapps/ROOT/WEB-INF/web.xml or war/WEB-INF/web.xml and change the mapping like this:
# 's
 1 <servlet>
2 <servlet-name>proxy</servlet-name>
3 <servlet-class>my.package.ProxyServlet</servlet-class>
4</servlet>
5
6<servlet-mapping>
7 <servlet-name>proxy</servlet-name>
8 <url-pattern>/*</url-pattern>
9</servlet-mapping>
10
11<servlet-mapping>
12 <servlet-name>shell</servlet-name>
13 <url-pattern>/servlet/*</url-pattern>
14</servlet-mapping>
  1. Install the HttpClient library in your buildpath
  2. Change the targetServer parameter to the server you want to recieve the proxied calls (the example uses www.google.com).

Comments

over 7 years ago (17 Nov 2009 at 02:02 PM) by toggle57
I am running in an Eclipse/SmartGWT environment with PHP on the back end and would like to know how to integrate this servlet into my application project.

I have included the Proxy servlet class with the server part of my application project but when I run the application the Proxy fails because it is executing functions (i.e. Sockets) that are not compatible/supported with GWT.

Is it posible to run this servlet in a separate (non GWT) project on the same localhost:8080 port? The GWT environment uses Jetty, and must be running its own servlet container.

Is it possible to have that container kick off the proxy servlet, or is it necessary to separately install tomcat on my localhost Apache/PHP environment.
over 7 years ago (17 Nov 2009 at 07:57 PM) by Stou S.
The purpose of the servlet is to allow the GWT hosted container tool to access backends that are running on a different port/server than GWT but using urls that are still part of the GWT app url space. That is when you access /some_url from within the GWT app, the proxy will actually call http://targetServer/some_url and forward the data result.

For production servers you will typically map your GWT frontend and backend to the same server so there is no SOP restriction and so you do not need the servlet. For example your web-app backend lives at example.com/foo and your front end lives at example.com/bar when the user clicks on something in the front end, the front end will post/get to some url inside example.com/foo. Using apache you can easily configure everything to live under the same server.

The servlet works fine with Jetty (See link above for an example project). Also GWT does not pose any restrictions to what server-side code you can run. Are you trying to use this thing with AppEngine?
over 7 years ago (19 Nov 2009 at 03:03 PM) by toggle57
When I created my gwt/eclipse project it created a GreetingServiceImpl servlet and web.xml already provided configuration for that servlet.

I simply added your class to the same package as the greet servlet and configured it in the web.xml to match on *.php.

When I run my application in hosted mode the HttpProxy servlet is kicked off when my application attempts to access a php url - just as I would like. But the moment it executes a java library function that is not supported by GWT (i.e. a socket function - and your servlet would not be much good without that) I get an exception indicating that it is not supported.

This is why I have been asking if it is necessary to put it in its own non GWT eclipse project, but then I worry about colissions on localhost:8080.

I hope thats clear, and thanks in advance for you input.
over 7 years ago (19 Nov 2009 at 09:00 PM) by Stou S.
Have you tried the example project I provide above? Again, GWT does not restrict what can run on the server: http://code.google.com/webtoolkit/doc/1.6/DevGuideServerCommunication.html#DevGuideServerSide you are probably missing the libraries. Please try the example project and modify it to match your code. If you are still getting an exception, post it here and I'll take a look.
over 7 years ago (01 Dec 2009 at 10:05 AM) by toggle57
Thank you Stou,

I think my issue was envionment related. I reinstalled J2EE, GWT pluggin and recreated my project from scratch and the problem went away. Also note that I did see that I had included the appengine jars when I created the original project - I did not see the check box on the GWT wizard that includes it by default.

After these changes your proxy worked wonderfully. Thank you for your time and code.

I am posting a recomendation for others having this issue on the SmartGwt forums to use your code.
over 6 years ago (31 Aug 2010 at 05:51 PM) by rakesh
I tried to you the example above and it works fine and returns the following messages. It really helped me understand few things. However I tried to change the URL from www.google.com to some other url from where I am suppose to get the xml data. But I am still getting the same reply.

Would you be able to help me with this. Once I get the resp back in the response object I will be able to use the xml api to extract the data but I am not getting the xml object back.
over 6 years ago (01 Sep 2010 at 10:28 PM) by Stou S.
Without more information I can't really tell you what the problem could be. If the servlet works for www.google.com but doesn't when you change the serverUrl to your own server... then it must be something with your backend.

Also we pretty much gave up on SmartGwt and I have removed it from my computer so I can't really help you too much with it either.

Sorry!