スケッチテスト項目の回顧


プロジェクト名:スケッチテスト


開発環境:


Tomcat 8.0.x / JSP 2.3 / Servlet 3.1 / Open JDK 1.8.x / MariaDB 10.1.x UTF-8


開始点

딱히 없다. 포트폴리오도 만들어야하고 그냥 무언가 만들어 보고 싶던 와중에 
당장 눈에 보이는 결과물을 찾게 되었고 그림판만 만들기엔 너무 식상해서 
스케치 퀴즈로 방향을 돌렸다.
생소한 프레임워크로 도전해보려다가 난관에 부딪히고 방향을 바꾸긴 했지만 
이 또한 나중에 언급할 것 이다.

Structure Setting


まず基本構想で、必要な要素は何かを考えました.
大まかなフレームワークは以下の通りです.

  • 誰もが速記問題を作ることができるはずで、誰もが1つの問題を作ることができるはずです.
  • 題を作るために、画板を思い出しました.△画板はとても起きられない番組です.
  • 問題を理解するために、ランダムに問題を持ってきて撒く必要があります.

  • 多くの人が使用しており、管理が必要です.

  • いずれにしても,ローカルで単独で使用するのではなく,多数のユーザを考慮してコードを記述する.

  • プレイヤーを分ける.(=ログインと会員加入機能が必要です.)

  • 管理者はWeb上でユーザーを制御する必要があります.(=管理者ページを追加します.)

  • 画像ストレージファイルを安全かつ効率的に管理する必要があります.
  • データ格納方式を考慮する必要がある.
  • 회원가입(register.html) → 회원가입 유효성 검사(regcheck.jsp) → 로그인(login.jsp) → 
    
    로그인 유효성 검사(logincheck.jsp) → 인덱스페이지(index.jsp) → 문제 제작(canvas.jsp) → 
    
    문제 제출(send.jsp) → 문제 풀기(viewquize.jsp) → 로그 제출 → 
    
    문제 정답 여부 확인(answercheck.jsp) → 다음 문제 이동(viewquize.jsp) 및 해당 계정 스코어 +1;

  • エンコードはDBデザインから(?)


    達人たちが言う.コーディング前にデザイン(?)やらなければならない.
    感じない.まずハーモニーを編んでおきます(この時どうしてそうなったんだろう…)
    まずは基本的にDB表を自分の考え通りにまとめました.
    基本的にはユーザデータを含むテーブルが必要であり,ファイルを格納するテーブルが必要であり,意識フローに従ってカラムに記入した.
    韓国人は戦う民族じゃないですか.得点機能を加えれば、試合はもっと活発になると信じている人もいる.
    また、管理兼以降のサービス運営のため、ログインも必要です.
    表の構造は次のとおりです.
  • Table Structure

    userinfo [id(varchar(30)),pw(varchar(30)),score(int)] 
    
    imagedata [id(varchar(30)),src(longtext),num(int),answer(varchar(30))]
    
    quizelog [num(int),id(varchar(30)),quizenum(int),userinput(varchar(30)),
    answer(varchar(30)),result(varchar(4)),time(datetime)]
    まずuserinfoにスペースを割り当ててアイデンティティパスワードのスコアを記録します.
    画像データにはgreen、imgファイル名、デフォルトキー値、正解が含まれます.
    パスワードはサーバ上で独自に暗号化されるため、パスワードのタイプは別途決定されません.
    Imgdata

    ログには、プライマリ・キー、回答の送信者、質問番号、入力値、回答、回答結果、および時間値が含まれます.
    quizelog

    コードを書く過程で、多くの人が使っている画像が不適切な場所にアップロードされることを考慮しなければなりません.
    管理者は、アップロードを個別にチェックして承認するかどうかを検討していますが、
    保障されていないため、ユーザーに通報を受け、管理者が受信した内容を確認するしかない.
    そこで、通報を受ける用紙を作成しました.
    違法文字(名前をつけた感じがおかしい…)

    今回の符号化過程で経験したいくつかの苦しみを以下に示す。


  • パスワードを暗号化するにはどうすればいいですか。


    Base 64やMD 5、SHAをそのまま使うと長さも負担になりますし、SQLがスルーされるとパスワードも出てきます.
    探しているのが時間の問題であることを知られないように、SHA 256で一度エンコードし、文字列をカットします.
    特定の符号化が発見されないように簡単に考えた.
    public String sha256(String pw) {
        String SHA = "";
        MessageDigest sh;
        try
        {
            sh = MessageDigest.getInstance("SHA-256");
            sh.update(pw.getBytes());
            byte byteData[] = sh.digest();
            StringBuffer sb = new StringBuffer();
            for(int i=0; i<byteData.length;i++)
                sb.append(Integer.toString((byteData[i]&0xff) + 0x100, 16).substring(1));
            return SHA = sb.toString().substring(3,15); //SHA256인코딩 후 중간문자 12개만 추출.
        } catch (NoSuchAlgorithmException e) {
            System.out.println("err");
            e.printStackTrace();
        }
        return SHA;
    }

  • 画像データを格納する方法。


    まず、画像をコミットする場合、クライアントはCanvasをキャプチャして保存し、サーバに送信する必要があります.
    面倒なので、できるだけユーザーを便利にしたいので、CanvasをBase 64にコードしたほうがいいです.
    一つ目のアイデアはDBでバットで叩くことです.
    しかし、Canvasでは1画ごとにデータのサイズが幾何級数的に増加します.(24 KB、5タッチ)
    DBがこのデータを受信できるかどうか見てみましょうそれが貯蔵スペースになるのではないかと心配しています.
    Googleゲームを始めました幸いLONGTEXTタイプはINTタイプで42億字入り
    これで十分だと思い、すぐにBase 64でSQLゲートを爆破しました.
    結果は成功した.

  • もっと効果的に保存できますか?


    いずれにしても、この方法はサーバとクライアントに有害であることに気づきました.
    クライアントの立場では、イメージではなくテキストでロードされ、キャッシュできないという問題があります.
    サーバー側に画像プレビューがなく、ファイル名が長すぎて、目的のファイルを見つけるのが難しい.
    最も重要なのは、SQLファイルの容量が大幅に増加したことです.
    最終的には、PNGタイプとして格納し、クライアントが送信するBase 64データを格納することを決定する多くの提案を得た.
    サーバ上でPNGファイルに変換して保存します.イメージファイル名はUUIDです.
    TIMESTAMP値と出題者IDのみを加算することにした.
  •                 Savefile s = new Savefile();
                    Date now = new Date();
                    SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddhhmmss");
                    String filename = sf.format(now)+id+".png";
                    Savefile.img.decodeStringtoFile(url.substring(22),"tomcat/webapps/img/"+filename);
                    
    
    
           
                   public static void decodeStringtoFile(String encodesString, String outputFileName) throws IOException 
                   {
                   BASE64Decoder base64Decoder = new BASE64Decoder();
                   InputStream inStream = new ByteArrayInputStream(encodesString.toString().getBytes("UTF-8"));
                   BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(outputFileName));
                   base64Decoder.decodeBuffer(inStream, outStream);
                   inStream.close();
                   outStream.close();
                   }
    最終的に生成されるファイル名は20200966071235 IDである.PNGはこう書いてあります
  • 画板の花(?)UNDO機能。

  • 지인에게 테스트를 부탁하고 피드백 받는 중 되돌리기 기능이 필요 하다는 요청이 있었다.
    
    곧 바로 구현을 시작 했고 첫 번째 떠오르는 자료 구조는 Stack이었다.
    
    유저가 한 획 그을 때 마다 Canvas를 저장 하고 Base64로 인코딩해서 Push했다. (~~Base64 참 좋아한다.~~)
    
    배열에 넣고 UNDO를 실행 할 때 마다  배열에서 Pop해서 Canvas를 새롭게 덮어서 그려주었다.

  • Problem
  • Undoを3回押すまで、Undoは正常に動作します.

  • Why?
  • を引くたびにbeginPath()が実行されます.これは、開始と終了の両方が保存されている問題です.

  • Solution
  • の初回実行時に関数を3回適用する一時的な方法を確立した.

  • Thinking
  • で考慮しなければならないのは、絵のタッチが多ければ多いほど、Stackのデータが多くなることです.
    クライアントに負担がかかりますか?(StackレンジのLimitが必要かもしれません.)
  • 通報されたイメージをどのように管理しますか?

  • 위에서 언급했듯이 다수가 이용하는 환경에 관리자가 사진을 하나하나 검토하기 힘들다는 전제하에
    유저들에게 신고를 접수 받고 접수받은 건에 대해서만 웹에서 관리 할 수 있으면 어떨까.
    우선 관리자 계정을 먼저 구분할 방법이 필요했고 다음과 같이 테이블을 하나 더 작성했다.
    
    Create table admin(permission varchar(30));
    
    일종의 Whitelist다. 여기 테이블에 등록 된 아이디는 관리자인 셈.
    
    관리자 로그인시 관리자페이지 버튼이 보이도록 코드를 작성했다.    
    if(session.getAttribute("admin") == "1") {%>
         <button>관리자 페이지</button> 
    <%}%> 
    管理者ページ