001: /*
002: *
003: * Copyright (c) 2007, Sun Microsystems, Inc.
004: *
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * * Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * * Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * * Neither the name of Sun Microsystems nor the names of its contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032: /**
033: * Examples using HttpConnection.
034: */package example.http;
035:
036: import java.io.*;
037:
038: import javax.microedition.io.Connector;
039: import javax.microedition.io.ContentConnection;
040: import javax.microedition.io.HttpConnection;
041: import javax.microedition.io.StreamConnection;
042: import javax.microedition.lcdui.Display;
043: import javax.microedition.lcdui.Form;
044: import javax.microedition.lcdui.Gauge;
045: import javax.microedition.midlet.*;
046:
047: /**
048: * sample http example MIDlet.
049: */
050: public class HttpExample extends MIDlet implements Runnable {
051: /** example URL for HTTP GET */
052: String url = "http://cds.cmsg.sun.com:80/serverscript/serverscript";
053:
054: /** string buffer for assembling HTTP requests. */
055: StringBuffer buffer = new StringBuffer();
056:
057: /** user interface component for displaying network progress. */
058: Gauge gauge;
059:
060: /** user interface screen for displaying progress gauge. */
061: Form form;
062:
063: /**
064: * Create the progress form and gauge.
065: * This program is not interactive, it will exit when done.
066: */
067: public HttpExample() {
068: gauge = new Gauge("Progress", false, 10, 0);
069: form = new Form("Progress");
070: form.append(gauge);
071: Display.getDisplay(this ).setCurrent(form);
072: }
073:
074: /**
075: * Start a thread to run the examples.
076: */
077: public void startApp() {
078: new Thread(this ).start();
079: }
080:
081: /**
082: * Run the examples.
083: */
084: public void run() {
085: ;
086:
087: try {
088: gauge.setLabel("Get using ContentConnection");
089: gauge.setValue(2);
090: getViaContentConnection(url);
091:
092: gauge.setLabel("Get using StreamConnection");
093: gauge.setValue(4);
094: getViaStreamConnection(url);
095:
096: gauge.setLabel("Get using HttpConnection");
097: gauge.setValue(6);
098: getViaHttpConnection(url);
099:
100: gauge.setLabel("Post using HttpConnection");
101: gauge.setValue(8);
102: postViaHttpConnection(url);
103: } catch (Exception e) {
104: System.out.println(e);
105: e.printStackTrace();
106: }
107:
108: gauge.setValue(10);
109: notifyDestroyed();
110: }
111:
112: /**
113: * Pause, discontinue with the http tests
114: */
115: public void pauseApp() {
116: }
117:
118: /**
119: * Destroy must cleanup everything. The thread is signaled
120: * to stop and no result is produced.
121: * @param unconditional true if forced shutdown.
122: */
123: public void destroyApp(boolean unconditional) {
124: }
125:
126: /**
127: * Simple read of a url using StreamConnection.
128: * No HTTP specific behavior is needed or used.
129: * <p>
130: * Connector.open is used to open url and a StreamConnection is returned.
131: * From the StreamConnection the InputStream is opened.
132: * It is used to read every character until end of file (-1).
133: * If an exception is thrown the connection and stream is closed.
134: * @param url the URL to process.
135: */
136: void getViaStreamConnection(String url) throws IOException {
137: StreamConnection c = null;
138: InputStream s = null;
139:
140: try {
141: c = (StreamConnection) Connector.open(url);
142: s = c.openInputStream();
143: buffer.setLength(0);
144:
145: int ch;
146:
147: while ((ch = s.read()) != -1) {
148: process((byte) ch);
149: }
150: } finally {
151: if (s != null) {
152: s.close();
153: }
154:
155: if (c != null) {
156: c.close();
157: }
158: }
159: }
160:
161: /**
162: * Simple read of a url using ContentConnection.
163: * No HTTP specific behavior is needed or used.
164: * <p>
165: * Connector.open is used to open url and a ContentConnection is returned.
166: * The ContentConnection may be able to provide the length.
167: * If the length is available, it is used to read the data in bulk.
168: * From the StreamConnection the InputStream is opened.
169: * It is used to read every character until end of file (-1).
170: * If an exception is thrown the connection and stream is closed.
171: * @param url the URL to process.
172: */
173: void getViaContentConnection(String url) throws IOException {
174: ContentConnection c = null;
175: InputStream is = null;
176:
177: try {
178: c = (ContentConnection) Connector.open(url);
179: is = c.openInputStream();
180: buffer.setLength(0);
181:
182: int len = (int) c.getLength();
183:
184: if (len > 0) {
185: byte[] data = new byte[len];
186: int actual = is.read(data);
187: process(data);
188: } else {
189: int ch;
190:
191: while ((ch = is.read()) != -1) {
192: process((byte) ch);
193: }
194: }
195: } finally {
196: if (is != null) {
197: is.close();
198: }
199:
200: if (c != null) {
201: c.close();
202: }
203: }
204: }
205:
206: /**
207: * Read the HTTP headers and the data using HttpConnection.
208: * Check the response code to insure successful retrieval.
209: * <p>
210: * Connector.open is used to open url and a HttpConnection is returned.
211: * The HTTP headers are read and processed.
212: * If the length is available, it is used to read the data in bulk.
213: * From the HttpConnection the InputStream is opened.
214: * It is used to read every character until end of file (-1).
215: * If an exception is thrown the connection and stream is closed.
216: * @param url the URL to process.
217: */
218: void getViaHttpConnection(String url) throws IOException {
219: HttpConnection c = null;
220: InputStream is = null;
221: OutputStream os = null;
222:
223: try {
224: int status = -1;
225:
226: // Open the connection and check for re-directs
227: while (true) {
228: c = (HttpConnection) Connector.open(url);
229: setRequestHeaders(c);
230:
231: // Get the status code, causing the connection to be made
232: status = c.getResponseCode();
233:
234: if ((status == HttpConnection.HTTP_TEMP_REDIRECT)
235: || (status == HttpConnection.HTTP_MOVED_TEMP)
236: || (status == HttpConnection.HTTP_MOVED_PERM)) {
237: // Get the new location and close the connection
238: url = c.getHeaderField("location");
239: c.close();
240:
241: System.out.println("Redirecting to " + url);
242: } else {
243: break;
244: }
245: }
246:
247: // Any 500 status number (500, 501) means there was a server error
248: if ((status == HttpConnection.HTTP_NOT_IMPLEMENTED)
249: || (status == HttpConnection.HTTP_VERSION)
250: || (status == HttpConnection.HTTP_INTERNAL_ERROR)
251: || (status == HttpConnection.HTTP_GATEWAY_TIMEOUT)
252: || (status == HttpConnection.HTTP_BAD_GATEWAY)) {
253: System.err.print("WARNING: Server error status ["
254: + status + "] ");
255: System.err.println("returned for url [" + url + "]");
256:
257: if (is != null) {
258: is.close();
259: }
260:
261: if (os != null) {
262: os.close();
263: }
264:
265: if (c != null) {
266: c.close();
267: }
268:
269: return;
270: }
271:
272: // Only HTTP_OK (200) means the content is returned.
273: if (status != HttpConnection.HTTP_OK) {
274: throw new IOException("Response status not OK ["
275: + status + "]");
276: }
277:
278: // Get the ContentType
279: String type = c.getType();
280: processType(type);
281:
282: // open the InputStream
283: is = c.openInputStream();
284: buffer.setLength(0);
285:
286: // Get the length and process the data
287: int len = (int) c.getLength();
288:
289: if (len > 0) {
290: byte[] data = new byte[len];
291: int actual = is.read(data);
292: process(data);
293: } else {
294: int ch;
295:
296: while ((ch = is.read()) != -1) {
297: process((byte) ch);
298: }
299: }
300: } finally {
301: if (is != null) {
302: is.close();
303: }
304:
305: if (c != null) {
306: c.close();
307: }
308: }
309: }
310:
311: /**
312: * Add request properties for the configuration, profiles,
313: * and locale of this system.
314: * @param c current HttpConnection to apply request headers
315: */
316: void setRequestHeaders(HttpConnection c) throws IOException {
317: String conf = System.getProperty("microedition.configuration");
318: String prof = System.getProperty("microedition.profiles");
319: int space = prof.indexOf(' ');
320:
321: if (space != -1) {
322: prof = prof.substring(0, space - 1);
323: }
324:
325: String locale = System.getProperty("microedition.locale");
326:
327: String ua = "Profile/" + prof + " Configuration/" + conf;
328: c.setRequestProperty("User-Agent", ua);
329:
330: if (locale != null) {
331: c.setRequestProperty("Content-Language", locale);
332: }
333: }
334:
335: /**
336: * Post a request with some headers and content to the server and
337: * process the headers and content.
338: * <p>
339: * Connector.open is used to open url and a HttpConnection is returned.
340: * The request method is set to POST and request headers set.
341: * A simple command is written and flushed.
342: * The HTTP headers are read and processed.
343: * If the length is available, it is used to read the data in bulk.
344: * From the StreamConnection the InputStream is opened.
345: * It is used to read every character until end of file (-1).
346: * If an exception is thrown the connection and stream is closed.
347: * @param url the URL to process.
348: */
349: void postViaHttpConnection(String url) throws IOException {
350: int status = 0;
351: HttpConnection c = null;
352: InputStream is = null;
353: OutputStream os = null;
354:
355: try {
356: c = (HttpConnection) Connector.open(url);
357:
358: // Set the request method and headers
359: c.setRequestMethod(HttpConnection.POST);
360: c.setRequestProperty("If-Modified-Since",
361: "29 Oct 1999 19:43:31 GMT");
362: c.setRequestProperty("User-Agent",
363: "Profile/MIDP-1.0 Configuration/CLDC-1.0");
364: c.setRequestProperty("Content-Language", "en-US");
365:
366: // Getting the output stream may flush the headers
367: os = c.openOutputStream();
368: os.write("LIST games\n".getBytes());
369: os.flush(); // Optional, openInputStream will flush
370:
371: // Get the status code, causing the connection to be made
372: status = c.getResponseCode();
373:
374: // Any 500 status number (500, 501) means there was a server error
375: if ((status == HttpConnection.HTTP_NOT_IMPLEMENTED)
376: || (status == HttpConnection.HTTP_VERSION)
377: || (status == HttpConnection.HTTP_INTERNAL_ERROR)
378: || (status == HttpConnection.HTTP_GATEWAY_TIMEOUT)
379: || (status == HttpConnection.HTTP_BAD_GATEWAY)) {
380: System.err.print("WARNING: Server error status ["
381: + status + "] ");
382: System.err.println("returned for url [" + url + "]");
383:
384: if (is != null) {
385: is.close();
386: }
387:
388: if (os != null) {
389: os.close();
390: }
391:
392: if (c != null) {
393: c.close();
394: }
395:
396: return;
397: }
398:
399: // Only HTTP_OK (200) means the content is returned.
400: if (status != HttpConnection.HTTP_OK) {
401: throw new IOException("Response status not OK ["
402: + status + "]");
403: }
404:
405: // Open the InputStream and get the ContentType
406: is = c.openInputStream();
407:
408: String type = c.getType();
409: processType(type);
410:
411: // Get the length and process the data
412: int len = (int) c.getLength();
413:
414: if (len > 0) {
415: byte[] data = new byte[len];
416: int actual = is.read(data);
417: process(data);
418: } else {
419: int ch;
420:
421: while ((ch = is.read()) != -1) {
422: process((byte) ch);
423: }
424: }
425: } finally {
426: if (is != null) {
427: is.close();
428: }
429:
430: if (os != null) {
431: os.close();
432: }
433:
434: if (c != null) {
435: c.close();
436: }
437: }
438: }
439:
440: /**
441: * Process the type.
442: * @param type that type
443: */
444: void processType(String type) {
445: }
446:
447: /**
448: * Process the data one character at a time.
449: * @param b one byte of data
450: */
451: void process(byte b) {
452: buffer.append((char) b);
453: }
454:
455: /**
456: * Process the data from the array.
457: * @param b an array of bytes.
458: */
459: void process(byte[] b) {
460: for (int i = 0; i < b.length; i++) {
461: process(b[i]);
462: }
463: }
464: }
|