Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java ME (J2ME) > Подскажите в чем проблема при работе с HTTP?


Автор: Clever_ui 22.11.2007, 04:12
В постах нашел вот такую процедуру отправки запроса ПОСТ на адрес, немного ее передал, но интересная ситуация происходит...

Сразу скажу, что процедура вызывается из потока. Так вот когда тестирую на эмуляторе, все нормально, т.е. данные приходят на сервер, короче все ок... Сразу оговорюсь повесил самописный сервер на локалхост и на него же из эмулятора шлю, в этом случае все ОК. Как только я указываю реальный адрес в сети, происходит исключение, непонятно почему...

Может кто-то подскажет??? Не нужно ли тут ждать пока не будут получены данные???

 
Код

void postViaHttpConnection(String url, String post) throws IOException {
        String str = null;
        HttpConnection c = null;
        InputStream is = null;
        OutputStream os = null;
        String Str="";
        int rc;
        System.out.println("!!!!!!");
        try {
            c = (HttpConnection)Connector.open(url);

            // Set the request method and headers
            c.setRequestMethod(HttpConnection.POST);
            c.setRequestProperty("User-Agent", "тест");
            c.setRequestProperty("Content-Language", "en-US");
            c.setRequestProperty("content-length", String.valueOf(post.length()));
            
            String.valueOf(post);
            
            // Getting the output stream may flush the headers
            os = c.openOutputStream();
            os.write(post.getBytes());

            rc = c.getResponseCode();
            System.out.println("!!!!!! - Код ответа: "+rc);
            if (rc != HttpConnection.HTTP_OK) {
                throw new IOException("HTTP response code: " + rc);
            }
            is = c.openInputStream();
            // Get the ContentType
            String type = c.getType();
            System.out.println("!!!!! -   "+type);
            // Get the length and process the data
            int len = (int)c.getLength();
            
            
            System.out.println("Длина входящего потока: "+String.valueOf(len));
            
            int ch;
            while ((ch = is.read()) != -1) {
                Str = Str + (char)ch;
            }            
            
            }
        catch (ClassCastException e) {
            throw new IllegalArgumentException("Not an HTTP URL");
        } finally {
            if (is != null) ;
                is.close();
            if (os != null) ;
                os.close();
            if (c != null) ;
                c.close();
        }
        
       Res=Str;
       System.out.println("!!!!! -   "+Str);       
    }    


M
W0LF
Пожалуйста, обрамляйте код в тег code - правая верхняя кнопка окна сообщения

Автор: W0LF 22.11.2007, 08:45
1! - 
 
Цитата

  System.out.println("!!!!!! - Код ответа: "+rc);
 

 что выдает эта строка на экран?
2! - 
 
Цитата

 c.setRequestProperty("User-Agent", "тест");
 

Если мидлет не подписан - этот параметр передаваться не будет, точнее будет как untrusted,
Вывод - убери эту строку
3! - 
  
Цитата

  c.setRequestProperty("Content-Language", "en-US");
  

Убери это тоже.
4! - 
Цитата

c.setRequestProperty("content-length", String.valueOf(post.length()));

Попробуй "Content-Length" написать именно так.
5! - 
  
Цитата

  String.valueOf(post);
  

Эта строка вроде как не нужна.
6! - 
Так же есть такое свойтсво - 
с.setRequestProperty("Content-Type",
                        "multipart/form-data; boundary=" + boundary);

Пример отсылки запроса(я уже вроде как где-то описывал) - 
Код

/**
     * Creates Entity-Body of post request
     *
     * @param boundary
     * @param parameters Hashtable of parameters ("key" - name of parameter,
     *                   "value" - value of parameter)
     * @return <description>
     */
    private static byte[] getMultiPart(String boundary, Hashtable parameters) {
        String crlf = "\r\n";
        StringBuffer sb = new StringBuffer();
        Enumeration e = parameters.keys();
        while (e.hasMoreElements()) {
            String nameOfParameter = (String) e.nextElement();
            String valueOfParameter = (String) parameters.get(nameOfParameter);
            sb.append("--" + boundary + crlf);
            sb.append("Content-Disposition: form-data; name=\"" + nameOfParameter + "\""
                    + crlf);
            sb.append(crlf);
            sb.append("" + valueOfParameter + crlf);
        }
        sb.append("--" + boundary + "--" + crlf);
        return sb.toString().getBytes();
    }


Вот пример логина - 
Код

 /**
     *
     * @param login
     * @param password
     * @param network
     * @throws IOException
     */
    public static void buildLoginRequest(String login, String password,
                                  String network) throws IOException {
        String boundary = "1B" + System.currentTimeMillis();
        Hashtable parameters = new Hashtable();
        parameters.put(Constants.REQUEST_PROPERTY_TYPE, Constants.REQUEST_NAME_LOGIN);
        parameters.put(Constants.REQUEST_FIELD_NAME_USER_NAME, login);
        parameters.put(Constants.REQUEST_FIELD_NAME_PASSWORD, password);
        parameters.put(Constants.REQUEST_FIELD_NAME_NETWORK, network);
        byte[] data = getMultiPart(boundary, parameters);
        sendRequestParseResponse(data, boundary);
    }



Код

/**
     *
     * @param data
     * @param boundary
     * @throws IOException
     */
    private static void sendRequestParseResponse(byte[] data, String boundary)
            throws IOException {
        byte[] responseData;
        try {
            responseData = HttpSender.getInstance().send(Constants.URL, data, boundary);
        } catch (IOException ioe) {
            Logger.logError(className, "sendRequestParseResponse "
                    + ioe.getMessage());//этот класс можно описать самому
            throw new IOException(ioe.getMessage());
        }
        XMLParser.parseResponse(responseData);//это я дальше парсил ответ, этого класса в примере нет
    }


непосредственно HttpSender
Код

/**
 * @author Alexander Lonsky
 */

import src.utils.Logger;
import src.model.Constants;

import javax.microedition.io.Connector;
import javax.microedition.io.ConnectionNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import javax.microedition.io.HttpConnection;

public class HttpSender {
    private static HttpSender httpSender = null;

    private HttpSender() {
    }

    public static synchronized HttpSender getInstance() {
        if (httpSender == null) {
            httpSender = new HttpSender();
        }
        return httpSender;
    }

    /**
     * -
     *
     * @param url
     * @param dataOutput if dataOutput == null - get request else post request
     * @return response data
     */
    public synchronized byte[] send(String url, byte[] dataOutput, String boundary) throws IOException {
        if (url == null) {
            return null;
        }
        HttpConnection hCon;
        ByteArrayOutputStream bStrm = new ByteArrayOutputStream();
        try {
            hCon = (HttpConnection) Connector.open(url);
            if (dataOutput != null) {
                hCon.setRequestMethod(HttpConnection.POST);
                hCon.setRequestProperty("Content-Type",
                        "multipart/form-data; boundary=" + boundary);
                hCon.setRequestProperty("Content-Length", String.valueOf(dataOutput.length));
                OutputStream os;
                os = hCon.openOutputStream();
                os.write(dataOutput);
                os.close();
            }
        } catch (ConnectionNotFoundException cnfe) {
            Logger.logError(getClass().getName(), "send(1) : "
                    + Constants.ERROR_TYPE_CONNECTION_NOT_FOUND);
            throw new IOException(Constants.ERROR_TYPE_CONNECTION_NOT_FOUND);
        } catch (IOException ioe) {
            Logger.logError(getClass().getName(), "send(2) : openURL ioe exception" + ioe.getMessage());
            throw new IOException("openURL ioe exception");
        } catch (ClassCastException cce) {
            Logger.logError(getClass().getName(), "send(3) : Bad url exception");
            throw new IOException("Bad url exception");
        } catch (SecurityException se) {
            Logger.logError(getClass().getName(), "send(4) : Permissions denied exception");
            throw new IOException("Permissions denied exception");
        } catch (NullPointerException npe) {
            Logger.logError(getClass().getName(), "send(5) : ");
            throw new IOException("NullPointer exception");
        }
        if (hCon.getResponseCode() == HttpConnection.HTTP_OK) {
            InputStream is;
            is = hCon.openInputStream();
            int ch;
            try {
                while ((ch = is.read()) != -1) {
                    bStrm.write(ch);
                }
                bStrm.close();
                is.close();
                hCon.close();
            } catch (IOException ioe) {
                Logger.logError(getClass().getName(), "can't read from stream");
            }
        } else {
            Logger.logError(getClass().getName(), String.valueOf(hCon.getResponseCode())
                    + " : " + hCon.getResponseMessage());
            throw new IOException(String.valueOf(hCon.getResponseCode())
                    + " : " + hCon.getResponseMessage());
        }
        return bStrm.toByteArray();
    }

}

Автор: Clever_ui 22.11.2007, 09:08
Первая строка выводит просто номер ответа после вызова getResponseCode, ну грубо говоря смотрю если 200 - то все ок... (я в нетбинс сижу)

Реальный сервер не отвечал пока не сделал:

Код

...
c.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
...


на счет:
Код

c.setRequestProperty("User-Agent", "Test");



Необязательно мидлет должен быть подписан, потому что мой HTTP сервер получает именно то что я передаю в UserAgent.

Добился чтобы отправлял и получал ответ, но теперь новая проблема, отправляемый мной текст, берется из TextField, на сервер он приходит в виде "кракозябр" smile

как решить проблему? 

Предварительно собирается строка запроса, она кодируется в BASE64 и отсылается на сервер, там декодируется и вместо русских букв ерунда...
т.е. кодировка в телефоне отличается от кодировки винды... Я предполагаю, что текст этот в UTF-8 но как его сконвертить в Win1251 ?


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)