2010年4月26日月曜日

Server returned HTTP response code: 403 for URLに対して

このエントリーをはてなブックマークに追加
Javaです.

URLConnectionを使って,HTTPコネクションをはり,HTMLを取得する際,下記のように書く.

import java.io.*;
import java.net.*;

public class MyURLConnection {
public static void main(String[] args) {
try {
URL url = new URL("http://example.com/");
URLConnection conn = url.openConnection();
BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}


ただ,サイトによっては,
java.io.IOException: Server returned HTTP response code: 403 for URL:
というエラーが発生する.
そこで,下記のように,ヘッダを設定するとすんなり通る.

import java.io.*;
import java.net.*;

public class MyURLConnection {
public static void main(String[] args) {
try {
URL url = new URL("http://example.com");
URLConnection conn = url.openConnection();
/////////////////////////////////////////////////////
conn.setRequestProperty("User-agent","Mozilla/5.0");
/////////////////////////////////////////////////////
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}


これは,ヘッダが正しく設定されてないHTTPコネクションに対しては,サーバ側が受理しないことがあるため(よくわからないプログラムからアクセスされていると推測できる).
そこで,ヘッダを設定してあげると通る.

ということでいいのかな???

2010年4月25日日曜日

Androidでカメラ画像取得→ソケット転送

このエントリーをはてなブックマークに追加
Androidのカメラを使用したかったのでサンプルプログラムを書いてみた.

ついでに,取得した画像をPCにソケットで転送しPCのディスプレイ上で表示した.




以下,プログラム.
カメラ画像の取得については,↓のサイトを参考にした.
Androidメモ

画像の解像度は,デフォルトサイズでは,2048×1536(1M~1.2M)となり,転送に時間がかかったので,480×320に変更した.

[Android側-CameraTest.java]
package com.blogspot.ayakix_lablog.camera;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class CameraTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new CameraView(this));
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}


[Android側-CameraView.java]
package com.blogspot.ayakix_lablog.camera;
import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.BufferedOutputStream;
import java.net.Socket;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder; //ホルダー
private Camera camera; //カメラ
private static final int WIDTH = 480;
private static final int HEIGHT = 320;
private static final int PORT = 4680;
private static final String IP_ADDR = "1.1.1.1"; // IPアドレス

public CameraView(Context context) {
super(context);
// サーフェイスホルダーの生成
holder=getHolder();
holder.addCallback(this);
//プッシュバッッファの指定
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void surfaceCreated(SurfaceHolder holder) {
// カメラの初期化
try {
camera=Camera.open();
camera.setPreviewDisplay(holder);
} catch (Exception e) {
}
}

public void surfaceChanged(SurfaceHolder holder,int format,int w,int h) {
// カメラのプレビュー開始
Camera.Parameters parameters=camera.getParameters();
parameters.setPictureSize(WIDTH, HEIGHT);
parameters.setPreviewFormat(PixelFormat.JPEG);
camera.setParameters(parameters);
camera.startPreview();
}

public void surfaceDestroyed(SurfaceHolder holder) {
// カメラのプレビュー停止
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera=null;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction()==MotionEvent.ACTION_DOWN) {
takePicture();
camera.startPreview();
}
return true;
}

public void takePicture() {
// カメラのスクリーンショットの取得
camera.takePicture(null, null,new Camera.PictureCallback() {
public void onPictureTaken(byte[] data,Camera camera) {
sendData(getContext(), data);
}
});
}

private void sendData(Context context, byte[] data){
// ソケットの作成
Socket socket;
BufferedOutputStream out;
try{
socket = new Socket(IP_ADDR, PORT);
out = new BufferedOutputStream(socket.getOutputStream());
out.write(data);
if(out != null) out.close();
if(socket != null) socket.close();
} catch (Exception ex){
ex.printStackTrace();
}
}
}


[Android側-AndroidManifest.xml]















[PC側-Main.java]
import java.io.*;
import java.net.*;

public class Main {
private static final int PORT = 4680;

public static void main(String argv[]) {
System.out.println("サーバ起動");
int num = 0;
ServerSocket serverSocket = null;
while(true){
try {
// サーバーソケットの生成
if(serverSocket == null) serverSocket = new ServerSocket(PORT);
// クライアントからの接続を待ちます
Socket socket = serverSocket.accept();
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream(new File(num + ".jpg")));
// 入力ストリームを取得
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))!=-1){
out.write(buf, 0, len);
}
// GUIで画像を表示
new GUIExe(num);
// 入出力ストリームを閉じる
out.flush();
out.close();
in.close();
System.out.println("done");
// ソケットを閉じる
socket.close();
num++;
} catch(Exception e) {
e.printStackTrace();
}
}
}
}

class GUIExe extends Thread {
private int num;

public GUIExe(int num) {
this.num = num;
this.start();
// スレッド開始
}
public void run() {
new GUI(num);
}
}


[PC側-GUI.java]
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class GUI extends JFrame {
private int num;
private final int WIDTH = 480;
private final int HEIGHT = 320;

public GUI(int num){
this.num = num;
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});

this.setBounds(0, 0, WIDTH, HEIGHT);
this.setLocation(num/3*WIDTH, num%3*HEIGHT);
this.setUndecorated(true);
this.setVisible(true);
}

public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
BufferedImage readImage = null;
try {
readImage = ImageIO.read(new File(num + ".jpg"));
} catch (Exception e) {
e.printStackTrace();
readImage = null;
}
if (readImage != null){
g2.drawImage(readImage, 0, 0, WIDTH, HEIGHT, this);
}
}
}

2010年4月15日木曜日

Firefoxアドオン-vimperatorのプラグインmulti_requester.js

このエントリーをはてなブックマークに追加
FirefoxのアドオンにVimperatorというものがあります.
[参考] 
Vimperator :: Add-ons for Firefox
Firefox Hacks:Vimperator――FirefoxをVim風のキーバインドで操作 - ITmedia エンタープライズ

デフォルトでもとても便利で重宝しているのですが,カスタマイズ性が高く,プラグインを導入することでより利便性が高まります.

今回はmulti_requester.jsというプラグインを導入したので,メモします.
[参考]
[vimperator]リクエスト結果をバッファ出力(muilti_requester.js) – suVeneのアレ

リンク先にもあるように,複数の検索ページからリクエスト結果をvimperatorのバッファ部分に出力することができます.

使用可能な検索エンジンは下記ページを参考にしてください.

アイテム - データベース: Multi Requester - wedata


検索エンジンの例を挙げます.カッコ内はコマンド例です.

 [alc (:mr alc 検索文字)]
 和英-英和辞書であるアルクからデータを引っ張ってきます.Webページで知らない単語があった場合,バッファに文字を出せるため,タブを切り替えたり ページを移動することなく,辞書をひくことができ,便利です.



[Yahoo 天気予報 (:mr weather-yahoo 地名or郵便番号 )]
Yahoo 天気予報からデータを引っ張ってきます.必要最小限のデータだけを引っ張ってくるので,見やすいです.


[php リファレンス検索 (:mr php-search 検索文字)]
phpの関数等を調べることができます.



ちなみに,multi_requester以外にも便利なプラグインがたくさんあります.
下記ページからダウンロードし, pluginフォルダの中にjsファイルを置くだけで使用可能となります.
/lang/javascript/vimperator-plugins/branches/2.2 – CodeRepos::Share – Trac