📚

【初心者向け/ITスクール42日】Javaを通したページ遷移

2023/09/08に公開

はじめに

今日は、ITスクールに通った42日目の日で、今日学んだ知識を記事にシェアしたいと思います。本記事が、ITを勉強を始めた方々にもロードマップになればいいと思います。

42日目は、HTML/CSSで作成したWEBページをServletとjspを連携して、ページを遷移する練習とMVCモデル2を具象する自習をしました。

その前にhtmlからサーバーにデーターをrequestするパターンを振り返ってみます。

1. <a href>

GET方式。hrefから参照するインクをサーバーにrequestします。

<a href=result.jsp?x=10&?y=10?>go to result</a>

2. location.href

GET方式。同様Javascriptのlocation.hrefから参照するインクをサーバーにrequestします。

function goResult(){
  location.href="result.jsp?x=10&y=10"
}

```html
<div onclick ="goResult();"> go to result </div>

3. <form action="" method="">

GET/POST方式。両方できる方式です。文字だけではなく、ファイルを送ることも可能です。

<form action="result.jsp" method="post">
	x<input name="x" />
	y<input name="y" />
	<button> go to result <button>
</form>

ページ遷移

仮に、サーバーをテスト中の際に/serverというサイトに移動したいと想像してみましょう。しかし時々、サーバーをアップデートしたり、する際にrequestしたサイトに繋がらない場合がありますね?
その時は恐らくこのようなメソッドをServletからこのような命令が発信されます。

response.sendRedirect("temp.jsp");

このように、クライアントに転送するページをコントロールすることをページ遷移といいます。既存の方式ではparameterに込めたデーターをStringに受けて変換しました。

しかし、ページ遷移はattributeというObject classでデーターを扱いますので、より幅いろい対応ができます。

先ほどのsendRedirect()はパラメーターからの値をサーバーに転送することができませんでしたが、データーを持ち、他のサイトに移動させたい場合はRequestDispatcherというオブジェクトforward()メソッドを呼び出し、他のサイトに転送することができます。
MVCモデルのCがこのような役割を担当しています。

SecondPage
RequestDispatcher rd = request.getRequestDispatcher("anotherPage.jsp");
int result = x+ y;
request.setAttribute("result",result);
rd.forward(request,response);

attributeはObjectでデーターを転送しますので、ダウンキャストが必須になります。

anotherPage
   Object ccc= request.getAttribute("c");
   Integer cc = (Integer)ccc;
   int c = cc.intValue();
   
   String d = (String) request.getAttribute("d");
   Random e = (Random) request.getAttribute("e");

  

クリアントからGet Requestがある場合、基本的にresponseするページです。

MVCmodel 2

https://zenn.dev/eldorado215/articles/e9760d0dfb504a

前回は、JDBCを通してMVCパターンを具象してみましたが、今回はhtml,css,jsp,java,servletを活用し、MVCパターンを具象しました。

Controller - BMIResultController.java doGet()

BMIResultController.java

protected void doGet(HttpServletRequest request, HttpServletResponse) throws ServletException, IOException{
request.getRequestDispatcher("BMIInput.html").forward(request,response);

//RequestDispatcher rd = request.getRequestDispatcher("BMIInput.html");
//rd.forward(request,response);
}

View 1 - BMIInput.html

BMIInput.html
<!DOCTYPE html>
<html lang="kr">
  <head>
    <link rel="stylesheet" href="css/style.css" />
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script type="text/javascript" src="ValidCheck.js"></script>
    <script type="text/javascript" src="BMIValidCheck.js"></script>
    <title>Document</title>
  </head>
  <body>
    <div class="box__menu">
      <span>체질량 지수(BMI) 계산</span>
    </div>
    <header>
      <h1>나의 체질량지수(BMI)</h1>
    </header>
    <main>
      <form
        name="pig"
        action="BMIResultController"
        method="post"
        enctype="multipart/form-data"
        onsubmit="return BMIcheckValid();"
      >
        <div class="box__name">
          <span>이름</span><br />
          <input
            name="NAME"
            maxlength="20"
            placeholder="한글/영어 20자까지 입력"
            autocomplete="off"
          />
        </div>
        <div class="box__height">
          <span></span><br />
          <input
            name="HEIGHT"
            placeholder="신장을 입력"
            autocomplete="off"
          />
          <span>cm</span>
        </div>
        <div class="box__weight">
          <span>몸무게</span><br />
          <input
            name="WEIGHT"
            placeholder="체중을 입력"
            autocomplete="off"
          />
          <span>kg</span>
        </div>
        <div class="box__photo">
          <span>사진</span><br />
          <input name="PHOTO" type="file" accept=".jpg,.png" /><br />
          <span id="size">10mb 이하의 jpg,png 파일만 가능합니다.</span>
        </div>
        <div class="box__button">
          <button>측정하기</button>
        </div>
      </form>
    </main>
  </body>
</html>


Controllerにactionする前に、inputタグにonsubmit attributeを通して、BMIcheckValid.jsの
BMIcheckValid()メソッドを呼び出します。

Model 2 - BMIValidCheck.js BMIcheckValid()

BMIValidCheck.js
 function BMIcheckValid(){
        	 
    	//document.form이름.input이름
    	let name = document.pig.NAME
    	let height = document.pig.HEIGHT;
    	let weight = document.pig.WEIGHT;
    	let photo = document.pig.PHOTO;
    	const MAXSIZE=10*1024*1024;	
				
    		
    		//입력 여부 검사
    	if(isEmpty(name)){
    		alert("이름을 입력해주세요");
		name.focus(); 
    		return false;
    	}
    		
    	if(isEmpty(height)){
    		alert("신장을 입력해주세요");
    		height.focus(); 
    		return false;
    	}
    		
    	if(isEmpty(weight)){
    		alert("체중을 입력해주세요");
    		weight.focus(); 
    		return false;
    	}
    		
	if(isEmpty(photo)){
		alert("사진을 첨부해주세요");
		photo.focus();
		return false;
		}
    		
    	//사진의 용량검사
    	if(photo.files[0].size > MAXSIZE){
		alert("10mb 이하의 사진만 업로드 가능합니다.");
		photo.focus();
		 return false;	
    	        }
    		
	//키와 몸무게가 음수가 아닌지 검사     	
    	if(height.value<0){
		alert("신장는 자연수만 입력가능합니다.");
		weight.focus();
		return false;
		}
    		
    	if(weight.value<0){
		alert("몸무게는 자연수만 입력가능합니다.");
		weight.focus();
		return false;
		}
    		
    	//키 몸무게가 숫자인지 검사
    	if(isNotNumber(height)){
		alert("신장은 숫자로 입력해주세요");
    		height.focus(); 
    		return false;
		}
			
	if(isNotNumber(weight)){
		alert("몸무게는 숫자로 입력해주세요");
    		weight.focus(); 
    		return false;
		}		
    				
    	//이름이 문자인지 검사
	const checkEng = /[a-zA-Z]/;
	const checkKor = /[-|-|-]/;

	if(!checkKor.test(name.value)&& !checkEng.test(name.value)){
	alert("이름은 한글과 영어만 입력 가능합니다.");
	name.focus();
	return false;
	    }	
		
	return true;
    } 

Controller - BMIResultController.java doPost()

BMIResultController.java

protected void doPost(HttpServletRequest request, HttpServletResponse) throws ServletException, IOException{
request.getRequestDispatcher("BMIResult.jsp").forward(request,response);

//RequestDispatcher rd = request.getRequestDispatcher("BMIResult.jsp");
//rd.forward(request,response);
}

最終的にはこのような感じになりますが、まだformから処理されていないバイナリーデーターが残っています。

DTO, Model 1(DAO) を作成し、View2(BMIResult.jsp) のみ作成すれば、終わりです。

DTO - Patient.java

Patient.java
package com.hyon.sep08.main;

public class Patient {

	private String name;
	private double height;
	private double weight;
	private String photo;
	private double bmi;
	private String status;
	
	public Patient() {
		super();
	}

	public Patient(String name, double height, double weight, String photo, double bmi, String status) {
		super();
		this.name = name;
		this.height = height;
		this.weight = weight;
		this.photo = photo;
		this.bmi = bmi;
		this.status = status;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}

	public double getWeight() {
		return weight;
	}

	public void setWeight(double weight) {
		this.weight = weight;
	}

	public String getPhoto() {
		return photo;
	}

	public void setPhoto(String photo) {
		this.photo = photo;
	}

	public double getBmi() {
		return bmi;
	}

	public void setBmi(double bmi) {
		this.bmi = bmi;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}
	
}

DAO - Doctor.java

Doctor.java
package com.hyon.sep08.main;

import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;


public class Doctor {
	public static void calculateBMIResult(HttpServletRequest request) throws IOException {
			
request.setCharacterEncoding("UTF-8");
String path = request.getServletContext().getRealPath("img");
	
MultipartRequest mr = new MultipartRequest(request, path, 1024*1024*10,"UTF-8", new DefaultFileRenamePolicy()
	);
	
String name = mr.getParameter("NAME");
double height = Double.parseDouble(mr.getParameter("HEIGHT"));
double weight = Double.parseDouble(mr.getParameter("WEIGHT"));
double bmi = weight/((height/100)*(height/100));
String photo = mr.getFilesystemName("PHOTO");
String status= "";

if(bmi>=40) status = "고도비만(고급돼지)";
else if(bmi>=35) status = "중등도비만(중급돼지)";
else if(bmi>=30) status = "경도비만(초급돼지)";
else if(bmi>=25) status = "과체중(돼지입문)";
else if(bmi>=18.5) status = "정상(돼지아님)";
else status = "저체중(멸치)";
	
photo = URLEncoder.encode(photo,"UTF-8");
photo.replace("+"," ");
	
	
request.setAttribute("patient" ,new Patient(name, height, weight, photo, bmi, status));
	}
}

VIEW2 - Result.jsp

Result.jsp
<%@page import="java.net.URLDecoder"%>
<%@page import="com.hyon.sep08.main.Patient"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="kr">
  <head>
    <link rel="stylesheet" href="css/style.css" />
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script type="text/javascript" src="ValidCheck.js"></script>
    <script type="text/javascript" src="BMIValidCheck.js"></script>
    <title>실행 결과</title>
    <style>
    {
      main{
      align-items: center;
      flex-direction: column;
      }
      marquee{
      font-size: 2em;
      }
    }
    </style>
  </head>
  <body>
  
<%
request.setCharacterEncoding("UTF-8");

Patient patient = (Patient)request.getAttribute("patient");
String name =patient.getName();
double height =patient.getHeight();
double weight=patient.getWeight();
double bmi =patient.getBmi();
String status =patient.getStatus();

patient.setPhoto(URLDecoder.decode(patient.getPhoto(),"UTF-8"));
String photo = patient.getPhoto();


%>
   <div class="box__menu">
      <span>체질량 지수(BMI) 계산</span>
    </div>
    <header>
      <h1><%=name %>님의 BMI 결과</h1>
    </header>
    <main>
       <img src="img/<%=photo %>">
       <h2>이름:<%=name %></h2>
       <h2>신장:<%=height %></h2>
       <h2>몸무게: <%=weight %></h2>
       <h2>BMI: <%=bmi %></h2>
	   <marquee>당신은 <%=status %> 입니다.</marquee> 
	   </main>
</body>
</html>

result

Discussion