okinawa

IT勉強メモ

Javaの文字化け対策

文字化けで混乱したところ

文字化け済みの文字にgetBytes("UTF-8")とかやってもしょうがないんだよ。

化けた文字を別の文字コードに変換してるだけだから、別の文字コードでまた化けた文字ができるだけ。

文字化けしてるってことはめちゃくちゃなバイト配列になってるから、それにエンコードかけてもまた変なバイト配列ができるってことね。

→これを解決する方法みつかった。「別の文字コードに変換する方法2」のところに書いた。

文字化けの原因特定

下記サイトで文字化け前の文字を入力して調査する。

ltside.com

ここで原因がわかったら下記のコードで文字コードを変換する。

String str = "あああ" // ←ここが文字化けしている想定
String s = new String(str.getBytes("ISO-8859-1"), "変換したい文字コード");

基本

基本的には開発環境の文字コードとファイルの文字コードを合わせればOK。

例えばEclipseでtest.propertiesファイルを見たら文字化けしてた!という時。

まずはEclipseUTF-8にする。

test.propertiesファイルをサクラエディタとかで開いて、UTF-8に設定する。そして中身を編集して保存する。

これだけで普通はOK。

デフォルトの文字コードを見る方法

System.out.println("デフォルト文字コード;" + System.getProperty("file.encoding"));

リクエスト値に文字コードを設定する

ただし、GETはダメでPOSTのみ有効らしい。

request.setCharacterEncoding("UTF-8");

別の文字コードに変換する方法

String str = "あ";
byte[] bytes = str.getBytes("UTF-8"); // UTF-8でバイト配列に変換
String str2 = new String(bytes, "UTF-8"); //文字に戻す

// 元の文字が文字化けしてなければ、どの文字コードでも変換できるはず?→多分ダメ
byte[] bytes = str.getBytes("SJIS");
String str2 = new String(bytes, "SJIS");

qiita.com

www.sejuku.net

別の文字コードに変換する方法2(まずはこれをやる!)

この方法が一番良い気がする。
元の文字が文字化けしていてもOK!

String str = "あ" //←これが文字化けしている想定

// byte配列をそのまま取り出す
byte[] iso = str.getBytes("ISO-8859-1");

// あとはお好みの文字列に自由に変換可能
String utf3 = new String(iso, "UTF-8");
String sjis = new String(iso, "SJIS");
String eucjp = new String(iso, "EUC-JP");

・参考
ISO-8859-1とは : JavaA2Z

jsp文字コード追加

<%@page contentType="text/html; charset=UTF-8" %>

<% request.setCharacterEncoding("UTF-8"); %>

web.xml文字コードフィルターを追加する方法

追加したらプロジェクトをクリーンする。

<?xml version="1.0" encoding="UTF-8"?>

<web-app>
  <display-name>Struts Blank Application</display-name>
  
<!-- ↓ここからフィルター -->
    <filter>
        <!-- ↓フィルターの名前を設定 -->
        <filter-name>EncodeFilter</filter-name>
        <!-- ↓上記で放り込んだフィルタークラスのパス -->
        <filter-class>filters.SetCharacterEncodingFilter</filter-class>
        <!-- ↓フィルタークラスのフィールドの初期化。この場合はUTF-8でエンコーディングさせる設定 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <!-- ↓使いたいフィルターの名前と一致させる -->
        <filter-name>EncodeFilter</filter-name>
        <!-- ↓どのURLを呼んだときに上記フィルタを起動させるか設定。この場合は全てのURLに対してフィルタを使う -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
<!-- ここまでフィルター -->
  
  <!-- Standard Action Servlet Configuration -->
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
 </servlet>


  <!-- Standard Action Servlet Mapping -->
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>


  <!-- The Usual Welcome File List -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

・参考
Linuxに使われる日々 : strutsで日本語が文字化けするのを直す - livedoor Blog(ブログ)

sever.xml文字コード指定

Serversプロジェクトのserver.xmlに赤字部分を追記。
追加したらプロジェクトをクリーンする。

URIEncoding="UTF-8" useBodyEncodingForURI="true"/>

・参考

Linuxに使われる日々 : strutsで日本語が文字化けするのを直す - livedoor Blog(ブログ)

Unicodeとは

文字コードの規格の1つ。

Unicode規格で策定されたUTFにはUTF-8UTF-16UTF-32の3種類がある。

符号化文字集合Unicode

文字符号化方式UTF-7UTF-8UTF-16UTF-32

ということらしい。

https://wa3.i-3-i.info/word11422.html

プログラムはなぜ動くのかを読んだメモ

 

私が読んだのは第2版。

www.nikkeibp.co.jp

 

型宣言はメモリ領域の確保

charは1バイト型

shortは2バイト型

longは4バイト型

型宣言すると上記のメモリ領域が確保される。

C言語のポインタ

ポインタはデータ型を意識すると理解しやすい。

ポインタ宣言はWindows用プログラムの場合、32ビットのメモリ領域を確保する。

 

char *d; // charのポインタ宣言。32ビットメモリ領域。

short *e; // shortのポインタ宣言。32ビットメモリ領域。

long *f; // long型のポインタ宣言。32ビットメモリ領域。

 

どの型で宣言してもポインタはメモリ領域を32ビット確保する。

じゃあ何が違うのか?

ポインタに格納されたアドレスから一度に何バイトのデータを読み書きするかが違う。

charなら1バイトずつ読み書き。

shortなら2バイトずつ読み書き。

longなら4バイトずつ読み書き。

 

Java機械語に変換されるまで

ソースコード(sample.java)→バイトコード(sample.class)
→ネイティブコード(ここでJava仮想マシンが各OSに合わせる)

ちなみにCPUの種類が変わればネイティブコードの種類も変わる。
x86/x64/AMD64とか色々あるらしい。

 

 32bitCPUと64bitCPU

32bitCPUが4GB以上のメモリを認識できないのは2の32乗が4GBだから。

64bitは128TB。

128TBのメモリが普及するのはいつ頃だろう。

 

リンク・リンカーとは

ソースコードには書かれていないが必要なものを取ってくる処理。
たとえばSystem.out.println()とソースに書いたとする。
しかし、そのソース内にはprinlnメソッドの処理内容は書かれていない。
なので、必要なソースを取ってきて結合する。
ちなみに不要な記述を削除するのもやっているらしい。

ソースコード(sample.java)→リンク→バイトコード(sample.class)→ネイティブコード→.exeファイル

 

.exeと.dllの違い

.exeは特定のアプリケーションの実行ファイル。
.dllは複数のアプリケーションの実行時に呼び出されるファイル。色々な関数とかが入っているらしい。
ダイナミックリンクライブラリだからライブラリだったんですねえ。

DLLファイル(Dynamic Link Library)とは - IT用語辞典 e-Words

 

インタプリタコンパイル

インタプリタ:実行時にソースコードの内容を1行ずつ解釈して処理する。
コンパイラ:実行前にソースコード全体を解釈して処理する。

 

ビルドとは

コンパイルとリンクを行うこと。

 

システムコール

OSのカーネル機能の呼び出し。

カーネルとはアプリケーションとハードウェアの架け橋。

 

例:printf
printf→OSに対してシステムコール→OSがハードウェアを制御→ディスプレイに文字列表示


windowsではシステムコールのことをAPIと言うらしい。

ハードウェア制御のときだけシステムコールされる?

 

ハードウェア視点でのプログラム処理の流れ

補助記憶装置(HDD/SSDなど)にある高級言語がネイティブコードに変換される
→ネイティブコードが主記憶装置(メモリ)に格納される
→CPUがメモリから命令やデータを読み出し、CPU内部のレジスタに格納して処理する

 


レジスタとは

レジスタとは、マイクロプロセッサ(MPU/CPU)内部にある、演算や実行状態の保持に用いる記憶素子。

最も高速な記憶装置だが、一般的なCPU製品で数個から数十個(容量に換算して数十バイト程度)と数が限られる。

GPUなど特殊なプロセッサでは数万個(数百キロバイト)のレジスタを内蔵するものもある。

 レジスタ(register)とは - IT用語辞典 e-Words

 

 

クリックされた要素をJavaScriptで取得する

複数の同じURLのリンクがあってどれがクリックされたか判定したかった↓

f:id:dodosu:20210815115705p:plain

イベントオブジェクトから取得

こっちはクラス名がなくてもできる。

html

            <p><a href="#" onclick="changeColor2(event)">click4!</a></p>
            <p><a href="#" onclick="changeColor2(event)">click5!</a></p>
            <p><a href="#" onclick="changeColor2(event)">click6!</a></p>

JavaScript

function changeColor2(event) {
  // event.targetでイベントが発生した要素を取得
  const link = event.target;
  link.classList.add('visited');
}

CSS

a {
  color: blue;
}

/* click済みの所を紫にする */
.visited {
  color: purple;
}

getElementsByClassNameで取得

html

            <p><a class="link" href="#">click1!</a></p>
            <p><a class="link" href="#">click2!</a></p>
            <p><a class="link" href="#">click3!</a></p>

JavaScript

// 複数のlinkクラスを配列で取得する
const link = document.getElementsByClassName('link');

for (let i = 0; i < link.length; i++) {
  // 各ボタンをイベントリスナーに登録
  link[i].addEventListener('click', function () {
    
    // visitedクラスを付与
    link[i].classList.add('visited');
  });
}

CSS

.link {
  color: blue;
}

/* click済みの所を紫にする */
.link.visited {
  color: purple;
}

参考

www.mdn.co.jp

www.javadrive.jp

CSS修正の心得

心得

アンチパターン

検証モードで修正点を1個見つけては、1個ずつ修正する。

良いパターン

検証モードでページ全体をみて、まとめて修正できるポイントを探す。

レイアウト崩れの犯人探し

崩れているレイアウトの最上位タグを怪しむところから始めよう。

最上位から下へCSSの設定が伝播していくので。

ブラウザのフォントについてメモ

・参考

www.ipentec.com

www.e-performance.co.jp

 

ブラウザにはデフォルトフォントというのがある。
font-familyで何も指定しなければ、デフォルトフォントが適用される。

 

IEの場合は

の3つ。

 

多分、普通のテキストはMS-P Gothicで、h1とかがMS-P 明朝。

MS ゴシック (欧文:Courier New)はどこで使われているかわからず。

 

ちなみに参考サイトに

  • Sans-Serif (ゴシック体系)
  • Serif (明朝体系)

とあるのだが

ゴシック体とか明朝体ってのは1つのフォントではないらしい。

ゴシック体と明朝体から派生したフォントが沢山あるようで、フォントの親のようなもの。

知らなかったなあ。

JavaScriptでよく使いそうなメソッド

参考

確かな力が身につくJavaScript「超」入門 第2版 | SBクリエイティブ

JavaScript Primer - 迷わないための入門書 #jsprimer

www.naka-style-blog.com

イベントでよく使う関数

要素の取得

document.querySlector('要素名');
document.querySlectorAll('要素名'); //要素を全て取得します。配列で返ってきます
document.getElemntById('id名');
document.getElementsByClassName('クラス名');

ちなみに、要素を作る場合
document.createElement('要素名');
要素.cloneNode(true); //複製する場合はtrue

ノードの取得

親要素.childNodes //親要素の子ノードを取得
親要素.children //親要素の子要素を取得
親要素.firstChild //親要素の最初の子ノードを取得
親要素.lastChild //親要素の最後の子ノードを取得
親要素.firstElementChild //親要素の最初の子要素を取得
親要素.firstElementChild //親要素の最初の子要素を取得
小要素.parentNode //小要素の親ノードを取得
要素.previousSibling //要素の1つ前の兄弟ノードを取得
要素.nextSibling //要素の1つ後の兄弟ノードを取得
要素.previousElementSibling //要素の1つ前の兄弟要素を取得
要素.nextElementSibling //要素の1つ後の兄弟要素を取

要素の追加と削除

要素.appendChild(子要素); //要素に小要素を追加します
要素.insertBefore(子要素, 指定要素); //要素の指定要素の前に子要素をいれます
要素.removeChild(子要素); //要素の子要素を削除します
要素.innerHTML = ''; //要素にHTMLを追加する

属性の変更

要素.textContent = 'text'; //要素の中身がtextになります
要素.style.color = 'red'; //要素の色がredになります
要素.classList.add('クラス名'); //要素にクラス名をつけます
要素.classList.remove('クラス名'); //要素のクラス名を除きます
要素.classList.contain('クラス名'); //要素にクラス名が付いているか判定します
要素.classList.toggle('クラス名'); //クラス名が付いていれば外し、付いてなければつけます
要素.setAttribute('属性名' '属性値') // class/id/name/styleなど色々なhtml属性に値を追加できて便利

要素の挿入に便利なメソッド  insertAdjacentHTML

insertAdjacentHTML(‘挿入する場所’, ‘挿入する要素’);
document.getElementById('list').insertAdjacentHTML('beforeend', hoge)

'beforebegin' 取得した要素 の直前に挿入

'afterbegin' 取得した要素の子要素として挿入。すでに子要素がある場合はその前に挿入。

'beforeend' element 取得した要素の子要素として挿入。すでに子要素がある場合はその後に挿入。

'afterend' 取得した要素の直後に挿入

基本動作のキャンセル preventDefault

function(event) { event.preventDefault(); }

form要素の読み取り

取得したform要素.読み取りたいフォーム部品のname属性.value

document.getElementById('form').word.value;

イベントオブジェクト 引数で渡すと関数で受け取れる

引数のeventにイベントオブジェクトが入る。

function(event) { }

ページ遷移

location.href = ‘https://google.com’

要素取得

querySelector(‘CSSセレクタ’);

querySelector(‘div’);

要素全取得

querySelectorAll(‘CSSセレクタ’);

querySelectorAll(‘div’); //全div要素を取得する

データ属性

htmlにdata-hogeと書いてJavaScriptからdataset.hogeでアクセスする仕組み。

参考

データ属性の使用 - ウェブ開発を学ぶ | MDN

<article
  id="electric-cars"
  data-columns="3"
  data-index-number="12314"
  data-parent="cars">
</article>
const article = document.getElementById('electric-cars');
article.dataset.columns // "3"
article.dataset.indexNumber // "12314"
article.dataset.parent // "cars"

HTMLタグの値読み取り・変更の基本

要素.属性

getElementById('electric-cars').src // 読み取り
getElementById('electric-cars').value //読み取り
getElementById('electric-cars').class = ‘new’; // 変更
getElementById('electric-cars').textContent = ‘abc’; // 変更

reduceメソッド

【JavaScript入門】初心者でも分かるreduce()の使い方とサンプル例まとめ | 侍エンジニアブログ

reduce() メソッドは、配列の各要素に対して (引数で与えられた) 関数を実行して、単一の出力値を生成します。

配列.reduce(function(累積値, 要素, インデックス番号, 配列) { })

JavaScriptのオブジェクトメモ

参考

www.oreilly.co.jp

基本

すべてのオブジェクトは可変。StringもObjectも。でもネイティブオブジェクトの変更は非推奨。

instanceOfは何のインスタンスかを判定。Objectは常にtrue.全てのオブジェクトはObjectを継承しているから。

let s = “aaa”;
console.log(s instanceof String); // true
console.log(s instanceof Object); // true

プリミティブ型をオブジェクトのように扱うと、その時だけオブジェクト扱いになり、そのあとはプリミティブ型に戻る。

let s = “abc”;
s.length; // オブジェクト扱い

ドット記法。cody.living ブラケット記法。cody[“living”]

ブラケット記法なら変数使える。

let s = “liv”;
let s2 = “ing”;
cody[s + s2];

オブジェクト内に存在しないプロパティにアクセスしようとすると、JavaScriptはその関数がコンストラクタを持つ限り、プロトタイプチェーンをさかのぼって上位オブジェクト内まで見る。最上位はObject.prototype。P44

プロパティが見つからずにundefinedが返された場合は、プロトタイプチェーンをさかのぼった結果、上位のオブジェクト内にも該当のプロパティ見つからなかったということ。

hasOwnPropertyはプロトタイプチェーンをさかのぼらず探す。inはさかのぼって探す。

let test = {“foo”};
console.log(test.hasOwnProperty(“toString”)); // false
console.log(“toString” in test); // true

全てのオブジェクトはObject.prototypeから継承する。

関数もオブジェクト。つまり値。変数や配列に値として格納できる。戻り値にもできる。

5章 グローバルオブジェクト

グローバルオブジェクトはすべてのオブジェクトを格納する唯一無二のオブジェクト。

グローバル変数、グローバルプロパティはグローバルオブジェクト直下に格納されている。

ブラウザでのグローバルオブジェクトはwindow。

グローバル直下には全てのスコープがアクセスできる。だからwindow.alert()のようなグローバルメソッドはどこからでも呼べる。

JavaScriptを記述する際はグローバルオブジェクトに記述しているということらしい。

var myStringVar = 'myString'; // letにするとfalseになるんだが?
console.log('myStringVar' in window); // 出力:true(*)

6章 thisとはなにか、thisは何を参照するか

グローバルスコープのthisはグローバルオブジェクトを参照する。

関数の中で使われるthisは親オブジェクトを参照する。

var body = {
    living : true,
    age : 33,
    gender : 'male',
    getGender : function() { return body.gender; } //下と同じ
    getGender : function() { return this.gender; } // genderの親プロパティはbody
};

thisの値の決まり方。

window.hoge = 'hoge'; // グローバルオブジェクト直下
window.myObject = {hoge: 'I am myObject.hoge'};

window.sayhoge = function() {
    console.log(this['hoge']);
};

window.myObject.sayhoge = sayhoge;

window.myObject.sayhoge(); // こっちのsayhoge()のthis(親オブジェクト)はmyObjectなので'I am myObject.hoge'を出力
window.sayhoge(); // こっちのsayhoge()のthisはwindow(グローバルオブジェクト)なので'hoge'を出力

コンストラクタはreturnを書かなくても、インスタンス自身が返される。つまりreturn this。JavaScriptではコンストラクタ内のthisは自分自身のインスタンスのこと。だからnewするとインスタンスが返ってくる。

7章 スコープとクロージャ

クロージャはスコープチェーンに存在する変数への参照を(囲い込んで)保持している関数。

prototypeプロパティははすべてのFunction()インスタンスに自動的に付与される。

var func = function(){};
console.log(typeof func.prototype); // object

プロトタイプチェーンはprotoプロパティによって構成される?

Array.prototype.foo = 'foo'; // Array()のすべてのインスタンスがfooプロパティを継承
var myArray = new Array();

// *.constructor.prototypeを使用する(冗長な)方法でfooの値をトレース
console.log(myArray.constructor.prototype.foo); // 出力:'foo'
console.log(myArray.__proto__.foo); // 出力:'foo'

// プロトタイプチェーンを使うこともできる
console.log(myArray.foo) // 出力:'foo'

14章 null

undefinedは未定義で存在すらない。nullは値が代入されていない。

未定義というのはプロトタイプチェーンでも発見できないもの。