竹形誠司 ブログ
ご質問    »トピック一覧
掲示板へのスパムが多いため、「ご質問」のコーナーはユーザー登録制とさせていただきました。お手数ですが、上の「新規ユーザーの登録」メニューより登録をお願いします。
帳票Web
アプリケーション

受注開発始めました
詳しくは こちら
竹形 誠司 著/ラトルズ刊
JSP帳票アプリケーション実践開発入門
JSP帳票アプリケーション
実践開発入門

JSP業務アプリケーション短期開発入門
JSP業務アプリケーション
短期開発入門

Java+MySQL+Tomcatで始めるWebアプリケーション構築入門
Java+MySQL+Tomcatで始めるWebアプリケーション構築入門

Java+MySQL+Tomcatで作る掲示板とブログ
Java+MySQL+Tomcatで作る
掲示板とブログ
正規表現に関する質問
by スワジランド[swajiland]
「JAVA+MySQL+TomcatではじめるWebアプリケーション構築入門弟3版」を勉強させていただいています。約1月ほどまえからWebアプリの勉強をはじめました。
当方の開発環境は、Windows-XP、eclipse3.4、Tomcat6.0、MySQL5.1であります。
御本のP53にあります正規表現に関して質問させてください。
ダブルクオート記号を置換する際に
str.replaceAll("\\"",""");
という例を示されていますが、
\\"の部分がeclipse3.4でエラーとなり、コンパイルできません。
\は実際は¥の半角です。
ダブルクオートとエンマークを含む文字列をMySQLへ登録しようとすると
エラーで落ちてしまいます。
どうかご教示おねがいいたします。


投稿:スワジランド[swajiland]/2009年 02月 12日 21時 18分 /更新:2009年 02月 12日 21時 19分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
竹形です。こんにちは。
ご質問の件、確認してみましたら、確かにエラーになりますね。これはeclipsの問題ではないようで、コマンドラインからのコンパイルでもエラーになりました。replaceAllの引数のうち、最初の引数では"\"を重ねないで、次のように書いてみてください。

str.replaceAll("\"",""");
このあたりの記述は古い版を引きずっている所があるので、もう一度確認してみます。ご報告ありがとうございました。
投稿:竹形 誠司[takegata]/2009年 02月 13日 05時 29分 /更新:2009年 02月 13日 05時 29分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
ちなみに、通常はMySQLに登録する文字列でダブルクオートをエスケープする必要はありません(文字列の囲みはシングルクオートです)。

また、PreparedStatementを使えば特殊文字のエスケープが自動的に行われるので、シングルクオートなどもエスケープする必要がありません。

ただし、MySQLを取り出した文字をブラウザに表示する際は"&"や"<"など、HTMLで特殊な扱いとなっている記号を&gt;や&amp;などのエンティティに置換する必要があります。
投稿:竹形 誠司[takegata]/2009年 02月 13日 05時 39分 /更新:2009年 02月 13日 05時 40分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
朝早くで早速のお返事ありがとうございました。感激!!
PreparedStatementという手法は知りませんでした。投稿した後、
「SQLの実行にはStatementよりPreparedStatementを使おう 」を読んでこれは便利!と思いました。まだ試しておりませんが・・・・
当方、掲示板を作成中ですが、なにせ旧来のStatementを使っていたので、insert文を使用するときどうしても、列名(comment)に変数(投稿文)を入れる場面が出てきますよね、その変数にダブルクオートが入っていたり、¥マーク(半角)があると、エラーで落ちてしまって困っていました。
竹形様のご指摘によれば、これはMySQLのエラーではなく、Javaのコンパイルのエラーなんでしょうかね。(再質問しちゃってます)
そういう理由でエスケープを利用して無理やりダブルクオートを&quot;に変換してMySQLへ保存して、取りだして表示するときに元に戻すように逆変換しようと考えていた次第です。ところが、ダブルクオートや¥マーク(半角)の置換ができないので丸2日くらいjava本を読んだり、ネットで検索したりして苦しんでおりました。
まずは、PreparedStatementという手法で戦ってみます。
どうもご丁寧にありがとうございました。
投稿:スワジランド[swajiland]/2009年 02月 13日 09時 15分 /更新:2009年 02月 13日 09時 16分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
竹形です。どうも。
ダブルクオートはそのままSQL文の中に入れても普通の文字として扱われるので、大丈夫だと思います。エラーが起こるのは何か他の原因ではないでしょうか。

逆にシングルクオートがクセ者で、これはエスケープしないとエライことになります。上のコメントにも書きましたが、PreparedStatementを使えばSQLで引っかかる文字は自動的にエスケープされるので、こちらの方法が絶対にお勧めです。

拙著53ページの記述についてですが、私の勘違いがありました。正誤表に反映させていただきたいと思います。ご指摘ありがとうございました。この件に関してはちょっと面白いことが分かったので、あとでブログに書きます。
投稿:竹形 誠司[takegata]/2009年 02月 13日 09時 39分 /更新:2009年 02月 13日 09時 39分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
お忙しいところ再度質問させてください。ご指導のとおり
str.replaceAll("\"","&quot;"); \は実際は¥の半角です。
に変更したらコンパイルできましたが、結果的にはダブルクオートを置換することができませんでした。「Javaのエスケープシーケンスと正規表現」ブログを読ませていただきましたが、申し訳ありませんがちょっと理解できませんでした。
PreparedStatementの方は試してみて、とても強力な手法であることがわかりました。このHPに来なければ知ることはできませんでした。申し少しでJavaを諦める寸前でした。どうもありがとうございました。ダブルクオート(半角)も¥マーク(半角も)エスケープなしでMySQLに登録できました。ちなみにシングルクオート(半角)も試したところスコーンと問題なく入ってしまいました。シングルクオートはSQLインジェクションとやらの対策のために入れられないように入力インターフェースでエラーになるように対策をしておいたほうがよいのでしょうか?このときに一発で変換できる上の置換(replaceAll)を使いたいのですが、どうもうまくいきません。正規表現は難しいですね。再度ご指導お願いいたします。

投稿:スワジランド[swajiland]/2009年 02月 14日 11時 02分 /更新:2009年 02月 14日 11時 03分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
竹形です。どうも。

次のようなコードを試してみてください。
public class TestQuot{
    public static void main(String[] args){
        String str="これは¥"テスト¥"です";
        System.out.println(str.replaceAll("¥"","&quot;"));
    }
}
これを実行すると、次のように表示されると思います。
これは&quot;テスト&quot;です
うまく置換されないのは、何か別の要因ではないでしょうか。例えば、strに入っている文字列の時点で既にダブルクオートが入っていないとか。あっと、上のコードは\を全角で書いているので、コピーする場合は半角に直してください。

PreparedStatementのsetStringメソッドを使っている限り、エスケープシーケンスへの変換はすべて自動で行われるのでSQLインジェクションは起こりません。シングルクオートをreplaceAllでエスケープシーケンスに変換するような処理は不要です。
投稿:竹形 誠司[takegata]/2009年 02月 14日 13時 58分 /更新:2009年 02月 14日 14時 01分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
ご指導ありがとうございます。ご指示どおりのプログラムを実行しましたら、正しく置換されました。この場合はstrに明示的に¥”を書いていますので、置換されていることがはっきりわかりやすいのですが、私が今回悩んでいるところは、htmlのformタグを使ってinputで以下のようにjspへ渡した場合、
<form method=POST action=hatugencheck.jsp>
テーマ<input type=text name=theme/><br>
内容<textarea name=comment></textarea><br>
<input type=submit value=\"送信\"/>
</form>
jsp側で
String themes = request.getParameter("theme");
themes.replaceAll("\"","&quote;");
String comments = request.getParameter("comment");
comments.replaceAll("\"","&quote;");
として受けて置換しようとしたのですが、ダブルクオートが&quote;に置換されませんでした。
お忙しいところ恐縮ですが、もし何かご教示いただけるのであればよろしくお願い申し上げます。
当方の開発環境は、Windows-XP、eclipse3.4、Apache2.2、Tomcat6.0、MySQL5.1、jdk1.6_0.11であります。

投稿:スワジランド[swajiland]/2009年 02月 15日 01時 19分 /更新:2009年 02月 15日 02時 16分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
あー、それはですね。&quot;がブラウザでダブルクオートに変換されるからではないでしょうかね。ブラウザの[表示]→[ソース]でHTMLのソースを見てみてください。

ウェブのフォームから入力された文字列をウェブ画面に表示すると、例えば、<BR>などの文字列は、ブラウザ側で改行のタグと解釈されてしまいます。

当サイトでは、"<",">","&"の3つの記号をキャラクタエンティティ("&lt;","&gt;""&amp;")に変換してからブラウザに表示しているので、「&quot;」と書けばHTMLでは「&amp;quot;」となり、結果的に「&quot;」と表示されますが、この変換をしなければ、「&quot;」と書いた場合にクオーテーションマークが表示されてしまいます。

これはSQLインジェクションとは別の話なんですが、このような処理を行っていない掲示板では、書き込みにJavaScriptを埋め込まれてハック/クラックされる危険があります。

つまり、ウェブに入力された文字列をデータベースに保存する場合は
文字列 --> [シングルクオートとセミコロンのエスケープ] --> SQL文
の処理が必要で(PreparedStatementを使えば自動的に処理されます)、ウェブ画面に表示する場合は、
文字列 --> ["<",">","&"をエンティティに置換] --> HTML
の処理が必要ということです。

投稿:竹形 誠司[takegata]/2009年 02月 15日 06時 46分 /更新:2009年 02月 15日 10時 34分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
何度もすみません。
eclipseのデバッガで文字列を受け取るjspの挙動を見ていても、
String themes = request.getParameter("theme");
themes.replaceAll("\"","&quote;");
String comments = request.getParameter("comment");
comments.replaceAll("\"","&quote;");
の置換部分で、ダブルクオートにまったく反応していないのです。
通常であれば、2行目の箇所にきて置換が行われればeclipseの変数をウォッチする部分で黄色く変わったことがわかるのですが、それがまったく無反応です。
そのために、themeという文字列に”(半角)が含まれていた場合に
hatugencheck.jspというプログラムで内容を確認させているのですが、
themeのvalueにはダブルクオートを含んだ文字列が渡ってしまい、ダブルクオート以降の文字列がhtmlで表示されないことになってしまっています。htmlをコード表示させてみたものを下に示します。(ヘタクソですみません。)
<form method=POST action=hatugentouroku.jsp>
<table class=t1 border=1><tr><td class=s1 width=100 align=center>投稿者</td><td class=s1 width=500>スワジランド123</td></tr><tr><td class=s1 width=100 align=center>テーマ</td><td class=s1 width=500><input type=text name=theme size="96" value="あああああ"いいいいいい"/></tr><tr><td class=s1 width=100 align=center>内容</td><td class=s1 width=500><textarea name=comment rows="20" cols="69" wrap="hard">うううううううう
"
ええええええええ
</textarea></td></tr></table><br>
内容を確認して、よければ登録ボタンを押してください。<br>
<input type=submit value="登録"/>
</form>
もし何か良いお知恵がありましたらお助けください。
それとも私は何か間違ったことをやっているでしょうか?
ご教示おねがいいたします。
投稿:スワジランド[swajiland]/2009年 02月 15日 14時 11分 /更新:2009年 02月 15日 14時 13分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
うーむ、全体がどうなっているのかよく分からないので、なんとも・・・どうしましょうね。

hatugencheck.jspとhatugentouroku.jspのコードを貼っていただけますか?
投稿:竹形 誠司[takegata]/2009年 02月 15日 14時 23分 /更新:2009年 02月 15日 14時 24分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
お返事早くてほんとうに恐縮いたします。
あつかましくも下手なプログラムのほう貼らせていただきます。
hatugencheck.jspは以下です。
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="Shift_JIS"%>
<%@ page import="java.sql.*" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<title>投稿チェック</title>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<STYLE TYPE="text/css">
    TABLE.t1{
    border-collapse:collapse;
    border-style:solid;
    border-color:black;
    border-width:2px;
    table-layout:fixed;
    margin-left:10pt;
    margin-top:0pt;
    }
   
    TABLE.t2{
    border-collapse:collapse;
    border-style:solid;
    border-color:black;
    border-width:2px;
    table-layout:fixed;
    margin-left:50pt;
    margin-top:0pt;
    }
   
    TD.s1{
    font-size:9pt;
    font-weight:bold;
    border-style:solid;
    border-width:1pxx;
    padding:2pt;
    padding-top:2pt;
    padding-bottom:2pt;
    vertical-align:middle;
    }
   
    TD.s2{
    font-size:9pt;
    font-weight:normal;
    border-style:solid;
    border-width:1pxx;
    padding:2pt;
    padding-top:2pt;
    padding-bottom:2pt;
    border-bottom-style:solid;
    border-bottom-width:2px;
    vertical-align:middle;
    }
   
    TD.s3{
    font-size:9pt;
    font-weight:bold;
    border-style:solid;
    border-width:2pxx;
    padding:2pt;
    padding-top:2pt;
    padding-bottom:2pt;
    vertical-align:middle;
    }

    TH.t1{
    font-size:10pt;
    background-color:#00EEEE;
    border-style:solid;
    border-width:1pxx;
    border-bottom-style:double;
    border-bottom-width:3px;   
    }
   
    TH.t2{
    font-size:10pt;
    background-color:#00FF88;
    border-style:solid;
    border-width:1pxx;
    border-bottom-style:double;
    border-bottom-width:3px;
    }
   
    H1{
    border:outset;
    padding:3pt;
    background-color:#DDDDCC;
    width:820px;
    }
   
    H2{
    margin-left:10pt;
    margin-bottom:0;
    width:820px;   
    }
   
    H3{
    font-weight:normal;
    margin-left:20pt;
    margin-top:10pt;
    margin-bottom:0pt;
    padding-top:2pt;
    padding-bottom:0pt;
    border-top-style:solid;
    border-color:#AAAAAA;
    border-bottom-style:solid;
    background-color:aqua;
    width:820px;
    }
   
    H4{
    font-size:10pt;
    font-weight:normal;
    margin-left:30pt;
    margin-top:0pt;
    margin-bottom:0pt;
    padding-top:1pt;
    padding-bottom:1pt;
    width:820px;
    }
   
</STYLE>


</head>
<body>
<%
    request.setCharacterEncoding("Shift_JIS");
    String id =(String)session.getAttribute("id");
    String pass =(String)session.getAttribute("pass");
    String preprogram =(String)session.getAttribute("preprogram");
   
    String firstnames =(String)session.getAttribute("firstname");
    String lastnames =(String)session.getAttribute("lastname");
    String nicknames =(String)session.getAttribute("nickname");
    String malefemales =(String)session.getAttribute("malefemale");
    String themes = request.getParameter("theme");
    themes.replaceAll("\"","&quote;");
    String comments = request.getParameter("comment");
    comments.replaceAll("\"","&quote;");
    HttpSession ses = request.getSession();
    ses.setAttribute("login","true");
    ses.setAttribute("id",id);
    ses.setAttribute("pass",pass);
    ses.setAttribute("preprogram","hatugencheck");
   
    ses.setAttribute("lastname",lastnames);
    ses.setAttribute("firstname",firstnames);
    ses.setAttribute("nickname",nicknames);
    ses.setAttribute("malefemale",malefemales);
           
    out.println("<h2>投稿チェック</h2>");
    out.println("<form method=POST action=hatugentouroku.jsp>");
    out.println("<table class=t1 border=1><tr><td class=s1 width=100 align=center>投稿者</td><td class=s1 width=500>"+ nicknames + "</td></tr>" +
            "<tr><td class=s1 width=100 align=center>テーマ</td><td class=s1 width=500"+
            "><input type=text name=theme size=\"96\" value=\""+ themes + "\"/></tr>" +
            "<tr><td class=s1 width=100 align=center>内容</td><td class=s1 width=500"+
            "><textarea name=comment rows=\"20\" cols=\"69\" wrap=\"hard\">"+ comments + "</textarea></td></tr></table><br>");
           
    out.println("内容を確認して、よければ登録ボタンを押してください。<br>");       
    out.println("<input type=submit value=\"登録\"/>");
    out.println("</form>");
   
   
%>   
</body>
</html>
hatugentouroku.jspは以下のとうりです。
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="Shift_JIS"%>
<%@ page import="java.sql.*" %>
<%@ page import="java.util.regex.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.text.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>発言登録Top</title>
</head>
<body>
<%
    request.setCharacterEncoding("Shift_JIS");
    String ids =(String)session.getAttribute("id");
    String passs =(String)session.getAttribute("pass");
    String preprogram =(String)session.getAttribute("preprogram");
    String firstnames =(String)session.getAttribute("firstname");
    String lastnames =(String)session.getAttribute("lastname");
    String nicknames =(String)session.getAttribute("nickname");
    String malefemales =(String)session.getAttribute("malefemale");
   
    String themes = request.getParameter("theme");
    String comments = request.getParameter("comment");
   
        Class.forName("com.mysql.jdbc.Driver");
        Connection users = DriverManager.getConnection(
            "jdbc:mysql://Localhost/user_db","****","#####");
        Statement state = users.createStatement();
        int res = 0;

        //★画期的なsql文(竹形さんよりいただき)
        String strSql="INSERT INTO keijiban_hatugen (id,lastname,firstname,nickname,malefemale,theme,comment,hatugenjikan) "
              +"VALUES (?,?,?,?,?,?,?,?)";  //★すっきり
        PreparedStatement pstmt = users.prepareStatement(strSql);
        Locale.setDefault(new Locale("ja","JP","JP"));
        GregorianCalendar gc = new GregorianCalendar();
        SimpleDateFormat sf1 = new SimpleDateFormat("GGGGyyyy年MM月dd日(E)");
        SimpleDateFormat sf2 = new SimpleDateFormat("ahh時mm分ss秒");
        String s1 = sf1.format(gc.getTime());
        String s2 = sf2.format(gc.getTime());
        pstmt.setString(1,ids);
        pstmt.setString(2,lastnames);
        pstmt.setString(3,firstnames);
        pstmt.setString(4,nicknames);
        pstmt.setString(5,malefemales);
        pstmt.setString(6,themes);
        pstmt.setString(7,comments);
        pstmt.setString(8,s1+"\r\n"+s2);
        res = pstmt.executeUpdate();
       
        if (res == 1){
            HttpSession ses = request.getSession();
            ses.setAttribute("login","true");
            ses.setAttribute("id",ids);
            ses.setAttribute("pass",passs);
            ses.setAttribute("preprogram","hatugentouroku.jsp");
            pageContext.forward("keijibantop.jsp");
   
        }else{ //ここへ来ることはない
            HttpSession ses = request.getSession();
            ses.setAttribute("login","false");       
            pageContext.forward("loginerror2.jsp");
        }
        state.close();
        users.close();

%>
   
   
</body>
</html>
投稿:スワジランド[swajiland]/2009年 02月 15日 15時 17分 /更新:2009年 02月 15日 15時 18分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
んーっ、かなり複雑なことをされていますね。
とりあえず、気が付いたところは
themes.replaceAll("\"","&quote;");
ですが、これではthemesの中身が書き換えられません。replaceAllは「変換した後の文字列を返す」メソッドなので、
themes = themes.replaceAll("\"","&quote;");
のようにする必要があります。ただ、ここでダブルクオートをエンティティに置換するのは、あまり良い方法とは言えないでしょう。以下の部分

    out.println("<h2>投稿チェック</h2>");
    out.println("<form method=POST action=hatugentouroku.jsp>");
    out.println("<table class=t1 border=1><tr><td class=s1 width=100 align=center>投稿者</td><td class=s1 width=500>"+ nicknames + "</td></tr>" +
            "<tr><td class=s1 width=100 align=center>テーマ</td><td class=s1 width=500"+
            "><input type=text name=theme size=\"96\" value=\""+ themes + "\"/></tr>" +
            "<tr><td class=s1 width=100 align=center>内容</td><td class=s1 width=500"+
            "><textarea name=comment rows=\"20\" cols=\"69\" wrap=\"hard\">"+ comments + "</textarea></td></tr></table><br>");
           
    out.println("内容を確認して、よければ登録ボタンを押してください。<br>");       
    out.println("<input type=submit value=\"登録\"/>");
    out.println("</form>");   
は <% と %>の間から出してしまえば、次のように書けます。Javaの変数は<%=と%>の間に書けば、HTMLデータの中に出力されます。こうすればダブルクオートをエンティティに変換する必要はありません。
<h2>投稿チェック</h2>
<form method=POST action=hatugentouroku.jsp>
<table class=t1 border=1>
<tr>
<td class=s1 width=100 align=center>投稿者</td>
<td class=s1 width=500><%=nicknames%></td>
</tr>
<tr>
  <td class=s1 width=100 align=center>テーマ</td>
  <td class=s1 width=500>
  <input type=text name=theme size="96" value="<%=themes%>">←★ココ
</tr>
<tr>
  <td class=s1 width=100 align=center>内容</td>
  <td class=s1 width=500 >
  <textarea name=comment rows="20" cols="69" wrap="hard"><%=comments%></textarea></td>
</tr>
</table>
<br>
内容を確認して、よければ登録ボタンを押してください。<br>
<input type=submit value="登録">
</form>   
ただ、これは確認画面ですよね?INPUT要素やTEXTAREAは確認画面では普通は使いませんけど、これはどのようなことを意図されているのでしょうか?私であれば、hiddenのINPUT要素を使って次のように書きます。
<h2>投稿チェック</h2>
<form method=POST action=hatugentouroku.jsp>
<table class=t1 border=1>
<tr>
<td class=s1 width=100 align=center>投稿者</td>
<td class=s1 width=500><%=nicknames%></td>
</tr>
<tr>
  <td class=s1 width=100 align=center>テーマ</td>
  <td class=s1 width=500>
    <%=themes.replaceAll("<","&lt;").replaceAll("&","&amp;")%>
    <input type="hidden" name="theme" value="<%=themes%>">
  </td>
</tr>
<tr>
  <td class=s1 width=100 align=center>内容</td>
  <td class=s1 width=500 >
    <%=comments.replaceAll("<","&lt;").replaceAll("&","&amp;")%>
    <input type="hidden" name="comment" value="<%=comments%>">
  </td>
</tr>
</table>
<br>
内容を確認して、よければ登録ボタンを押してください。<br>
<input type=submit value="登録">
</form>   
"<"と"&"をエンティティに変換している理由は↑の方で述べたとおりです。
投稿:竹形 誠司[takegata]/2009年 02月 15日 19時 01分 /更新:2009年 02月 15日 20時 13分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
ご指導ありがとうございました。
themes = themes.replaceAll("\"","&quote;");
comments = comments.replaceAll("\"","&quote;");
に変更しましたら置換できました。ご指摘のとおりダブルクオートは新しいSQL文で保存すると自動変換されて問題ないことがわかりました。<マークのほうが難題であることが分かりました。たいへん参考になりました。上記のスクリプトをそのまま使用させていただくことにします。
確認画面になぜ、inputを使うのか?というご指摘でしたが、確認させると同時に修正も可能にしたいという一石二鳥を考えてのことでした。通常は、本質問掲示板の確認画面で使われているような修正できないモードが多用されているみたいですが、修正したいときに一つ前に戻るというやり方を知らないために苦肉の策です。でもやはり修正したいときに一つ前に戻るというやり方のほうがカッコいいですよね。
javascriptには画面を一つ戻すやり方があるみたいですが、私のeclipseではimport javax.*をやってみたのですが、どうも<script>の呪文が通らないようで、どうやったらjavascriptが使えるようになるのか分からなかったものですから、前に進みながら修正する方法しか思いつかなかったというのが理由です。もしかしてjavascriptをjavaの中で使えるようにするためには、特別なjarファイルをどこからかダウンロードしなければいけないのでしょうか?よろしければ教えていただけますでしょうか。
プログラムの書き方までご指導くださいまして、いろいろと本当にありがとうございました。お返事お待ちしております。
投稿:スワジランド[swajiland]/2009年 02月 16日 00時 56分 /更新:2009年 02月 16日 02時 27分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
INPUTやTEXTAREAのボックスの中で確認しても、実際にどのように表示されるのかは分からないので、HTML上で確認できるようにした方がいいでしょうね。

戻るボタンは次のような感じでどうでしょう。
<INPUT TYPE="button" VALUE="戻る" ONCLICK="history.back()">
ONCLICK=のダブルクオートの中にJavaScriptを書けば、クリック時に実行されます。

JavaScriptはブラウザ側で解釈され、実行されるコードなので、Java側で何かを用意する必要はありません。私はeclipseを使わないので(エディタでコードを書いてコマンドラインでコンパイルします)詳しくは分かりませんが、JavaScriptをデバッグするための機能か何かが(もしあれば)関係しているのかも知れません。

#eclipseが内部で何をやっているのかがよく分からないので、あまり好きになれないのです。
投稿:竹形 誠司[takegata]/2009年 02月 16日 06時 03分 /更新:2009年 02月 16日 07時 30分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
お忙しいところ恐縮です。
ご提示してくれたとおり以下のように改めましたが、
<h2>投稿チェック</h2>
<form method=POST action=hatugentouroku.jsp>
<table class=t1 border=1>
<tr>
<td class=s1 width=100 align=center>投稿者</td>
<td class=s1 width=500><%=nicknames%></td>
</tr>
<tr>
  <td class=s1 width=100 align=center>テーマ</td>
  <td class=s1 width=500>
    <%=themes.replaceAll("<","&lt;").replaceAll("&","&amp;")%>
    <input type="hidden" name="theme" value="<%=themes%>">
  </td>
</tr>
<tr>
  <td class=s1 width=100 align=center>内容</td>
  <td class=s1 width=500 >
    <%=comments.replaceAll("<","&lt;").replaceAll("&","&amp;")%>
    <input type="hidden" name="comment" value="<%=comments%>">
  </td>
</tr>
</table>
<br>
内容を確認して、よければ登録ボタンを押してください。<br>
<input type=submit value="登録">
</form>   
確認画面では<が&lt;と表示されて、&が&amp;と表示されてしまいます。MySQLには<が&lt;と登録され、&が&amp;と登録され、MySQLからデータを取り出して表示すると<や&が表示されます。
確認画面でも<や&が表示されるようにするにはどうしたらよいでしょうか。
ご教示おねがいします。
投稿:スワジランド[swajiland]/2009年 02月 16日 18時 01分 /更新:2009年 02月 16日 18時 10分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
前後のコードを見てみないと何とも言えませんが、themesやcommentに入れた時点で<が&lt;、&が&amp;になっているのではないでしょうか。画面に表示する所以外でreplaceAllを使ってこの変換をしていないか確認してみてください。
投稿:竹形 誠司[takegata]/2009年 02月 16日 18時 45分 /更新:2009年 02月 16日 18時 46分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
前後のプログラムを貼りますので見ていただけませんでしょうか。
hatugensinki.jsp
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="Shift_JIS"%>
<%@ page import="java.sql.*" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<title>新規投稿Top</title>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<%@ include file="hatugensinki.css" %>
</head>
<body>
<%
    String id =(String)session.getAttribute("id");
    String pass =(String)session.getAttribute("pass");

    String preprogram =(String)session.getAttribute("preprogram");
    Class.forName("com.mysql.jdbc.Driver");
    Connection users = DriverManager.getConnection(
        "jdbc:mysql://Localhost/user_db","root","1018");
    Statement state = users.createStatement();

    ResultSet result = state.executeQuery("select * from users where id=\"" + id + "\"");
    boolean flg = false;
    String ids = null;
    String passs = null;
    String lastnames = null;
    String firstnames = null;
    String nicknames = null;
    String lastnamekanas = null;
    String firstnamekanas = null;
    String malefemales = null;
    if (result.next() && result.getString("passwd").equals(pass)){
        flg = true;   
       
        lastnames = result.getString("lastname");
        if (lastnames == null) lastnames = "";
        firstnames = result.getString("firstname");
        if (firstnames == null) firstnames = "";
        nicknames = result.getString("nickname");
        if (nicknames == null) nicknames = "";
        malefemales = result.getString("malefemale");
        if (malefemales == null) malefemales = "";
       
        HttpSession ses = request.getSession();
        ses.setAttribute("login","true");
        ses.setAttribute("id",id);
        ses.setAttribute("pass",pass);
        ses.setAttribute("preprogram","hatugensinki");
       
        ses.setAttribute("lastname",lastnames);
        ses.setAttribute("firstname",firstnames);
        ses.setAttribute("nickname",nicknames);
        ses.setAttribute("malefemale",malefemales);
    }
%>   
<h2>新規投稿</h2>
<form method=POST action=hatugencheck.jsp>
<table border=1>
    <tr>
        <td class=s1 width=100 align=center>投稿者</td>
        <td class=s1 width=500><%=nicknames %></td>
    </tr>
    <tr>
        <td class=s1 width=100 align=center>テーマ</td>
        <td class=s1 width=500><input type=text name=theme size="96"/></td>
    </tr>
    <tr>
        <td class=s1 width=100 align=center>内容</td>
        <td class=s1 width=500>
            <textarea name=comment rows="20" cols="69" wrap="hard"></textarea></td>
    </tr>
</table>
<br>
<input type=submit value="送信"/>
</form>
   
<a href = samplepage2.jsp>他へ移動</a><br>
<a href = login2.jsp>ログオフ</a><br>
   
</body>
</html>
hatugencheck.jsp
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="Shift_JIS"%>
<%@ page import="java.sql.*" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<title>投稿チェック</title>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<%@ include file="hatugencheck.css" %>
</head>
<body>
<%
    request.setCharacterEncoding("Shift_JIS");
    String id =(String)session.getAttribute("id");
    String pass =(String)session.getAttribute("pass");
    String preprogram =(String)session.getAttribute("preprogram");
   
    String firstnames =(String)session.getAttribute("firstname");
    String lastnames =(String)session.getAttribute("lastname");
    String nicknames =(String)session.getAttribute("nickname");
    String malefemales =(String)session.getAttribute("malefemale");
    String themes = request.getParameter("theme");
    String comments = request.getParameter("comment");
    HttpSession ses = request.getSession();
    ses.setAttribute("login","true");
    ses.setAttribute("id",id);
    ses.setAttribute("pass",pass);
    ses.setAttribute("preprogram","hatugencheck");
   
    ses.setAttribute("lastname",lastnames);
    ses.setAttribute("firstname",firstnames);
    ses.setAttribute("nickname",nicknames);
    ses.setAttribute("malefemale",malefemales);
   
%>

<h2>投稿チェック</h2>
<form method=POST action=hatugentouroku.jsp>
<table class=t1 border=1>
<tr>
<td class=s1 width=100 align=center>投稿者</td>
<td class=s1 width=500><%=nicknames%></td>
</tr>
<tr>
  <td class=s1 width=100 align=center>テーマ</td>
  <td class=s1 width=500><pre><%=themes.replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll("&","&amp;")%> 
    <input type=hidden name="theme" value="<%=themes%>">
  </td>
</tr>
<tr>
  <td class=s1 width=100 align=center>内容</td>
  <td class=s1 width=500 ><pre><%=comments.replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll("&","&amp;")%>
    <input type=hidden name="comment" value="<%=comments%>">
  </td>
</tr>
</table>
<br>
内容を確認して、よければ登録ボタンを押してください。<br>
<input type=submit value="登録">
</form>   

   
</body>
</html>
どうしても確認画面(hatugencheck.jsp)で"<"や">"を表示させたいので、よろしくおねがいします。
投稿:スワジランド[swajiland]/2009年 02月 16日 19時 22分 /更新:2009年 02月 16日 19時 22分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
あぁ、これは<PRE>タグを使っているからですね。<PRE>要素の中では、文字列がHTMLコードとして解釈されないので&や<はそのまま表示されます(replaceAllによる置換は不要です)。

<PRE>タグは主にプログラムのコードやテキストで組まれた表などを表示するためのもので、掲示板の表示などにはあまり使いません。<TEXTAREA>で入力された改行位置をHTMLで再現するにはreplaceAllで"\n"を"<BR>"に置換すればよいでしょう。それ以外に<PRE>タグを使う理由はありますか?
投稿:竹形 誠司[takegata]/2009年 02月 16日 19時 33分 /更新:2009年 02月 16日 19時 35分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
改行をさせるために<pre>を使っていました。¥nを<BR>へ置換するという逆の発想が思いつきませんでした。もう一度書き直して試してみます。
どうもありがとうございました。
投稿:スワジランド[swajiland]/2009年 02月 16日 19時 40分 /更新:2009年 02月 16日 19時 40分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
以下のように改めましたら完璧になりました。
<%@ page language="java" contentType="text/html; charset=Shift_JIS"
    pageEncoding="Shift_JIS"%>
<%@ page import="java.sql.*" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<title>投稿チェック</title>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<%@ include file="hatugencheck.css" %>
</head>
<body>
<%
    request.setCharacterEncoding("Shift_JIS");
    String id =(String)session.getAttribute("id");
    String pass =(String)session.getAttribute("pass");
    String preprogram =(String)session.getAttribute("preprogram");
   
    String firstnames =(String)session.getAttribute("firstname");
    String lastnames =(String)session.getAttribute("lastname");
    String nicknames =(String)session.getAttribute("nickname");
    String malefemales =(String)session.getAttribute("malefemale");
    String themes = request.getParameter("theme");
    String comments = request.getParameter("comment");
    HttpSession ses = request.getSession();
    ses.setAttribute("login","true");
    ses.setAttribute("id",id);
    ses.setAttribute("pass",pass);
    ses.setAttribute("preprogram","hatugencheck");
   
    ses.setAttribute("lastname",lastnames);
    ses.setAttribute("firstname",firstnames);
    ses.setAttribute("nickname",nicknames);
    ses.setAttribute("malefemale",malefemales);
   
%>

<h2>投稿チェック</h2>
<form method=POST action=hatugentouroku.jsp>
<table class=t1 border=1>
<tr>
<td class=s1 width=100 align=center>投稿者</td>
<td class=s1 width=500><%=nicknames%></td>
</tr>
<tr>
  <td class=s1 width=100 align=center>テーマ</td>
  <td class=s1 width=500><%=themes.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;")%> 
    <input type=hidden name="theme" value="<%=themes.replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll("\"","&quot;").replaceAll("&","&amp;")%>">

  </td>
</tr>
<tr>
  <td class=s1 width=100 align=center>内容</td>
  <td class=s1 width=500 ><%=comments.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll("\n","<br>")%>
    <input type=hidden name="comment" value="<%=comments.replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll("\"","&quot;").replaceAll("&","&amp;")%>">

  </td>
</tr>
</table>
<br>
内容を確認して、よければ登録ボタンを押してください。<br>
<input type=submit value="登録">
</form>   

   
</body>
</html>
これで確認画面も、MySQLの中身も、そこから取り出した表示も全てパーフェクトに表示することができました。.replaceAllで置換していく順序が上のようでなければうまく変換できませんでした。めちゃくちゃスッキリした気分です。
本当にご親切にありがとうございました。先生の御本を買っていなければ、とうにJAVAを諦めてPHPとかに走ってしまっていたかもしれません。そしてやっぱり同じようなところでつまずいて掲示板を作ることをやめていたと思います。このようなブログで熱心なご指導を仰げたのは何かのご縁であると感じております。
また近いうちにお邪魔させていただくことがありますが、その節はよろしくお願いいたします。JAVA+MySQL+Tomcatの発展にこれからもご尽力おねがいいたします。
投稿:スワジランド[swajiland]/2009年 02月 16日 20時 35分 /更新:2009年 02月 16日 20時 35分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
うまくいってよかったですね。
私もいろいろ勉強になりました。
また何かあればよろしくお願いします。
投稿:竹形 誠司[takegata]/2009年 02月 16日 20時 41分 /更新:2009年 02月 16日 20時 41分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
今、コードを見ていて気が付いたのですが、INPUTのhiddenでデータを渡す所はreplaceAllで < や & を &lt; や &amp; に変換する必要はありません。こうすると"&lt;"や "&amp;" がMySQLに入ってしまうので、データベースから読み出して画面に表示すると"&lt;"や "&amp;"になってしまうと思います。
投稿:竹形 誠司[takegata]/2009年 02月 16日 20時 47分 /更新:2009年 02月 16日 20時 47分
RE:正規表現に関する質問
by スワジランド[swajiland]
竹形様
はい、MySQLの中に&lt;や&amp;が入ってしまっていますが、取り出して表示するとき、htmlで表示させているので、<や&に変換されていますが、これは手法としては誤ったやりかたなのでしょうか。本来は、<や&を直接MySQLに登録して処理できればきれいなのですが、取り出して表示するときに逆に&lt;や&amp;に変換しなければいけなくなりはしませんでしょうか?
投稿:スワジランド[swajiland]/2009年 02月 16日 21時 20分 /更新:2009年 02月 16日 21時 20分
RE:正規表現に関する質問
by 竹形 誠司[takegata]
まぁ、いろいろ考え方はあると思いますが、たとえば、メッセージの内容をメールで送信するような場合に"&lt;"のまま送られてしまうので、データベースには"<"のまま登録しておいて、そこから取り出して画面に表示する際に&lt;に変換するというのがいいと思います。つまり

[テキストデータ]---変換--->[ウェブ画面に表示]

[テキストデータ]---そのまま--->[メール送信]

といった感じにデータの使い分けがやりやすくなるわけです。どこだったかのサイトのRSSフィーディングで「AT&T株式会社」が「AT&amp;T株式会社」になっていて笑ってしまったことがありました。これもおそらく&を&amp;に変換してから保存したためではないかと思います。
投稿:竹形 誠司[takegata]/2009年 02月 16日 21時 43分 /更新:2009年 02月 16日 21時 45分