【初心者向け/ITスクール42日】Javaを通したページ遷移
はじめに
今日は、ITスクールに通った42日目の日で、今日学んだ知識を記事にシェアしたいと思います。本記事が、ITを勉強を始めた方々にもロードマップになればいいと思います。
42日目は、HTML/CSSで作成したWEBページをServletとjspを連携して、ページを遷移する練習とMVCモデル2を具象する自習をしました。
その前にhtmlからサーバーにデーターをrequestするパターンを振り返ってみます。
<a href>
1. 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>
<form action="" method="">
3. 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がこのような役割を担当しています。
RequestDispatcher rd = request.getRequestDispatcher("anotherPage.jsp");
int result = x+ y;
request.setAttribute("result",result);
rd.forward(request,response);
attributeはObjectでデーターを転送しますので、ダウンキャストが必須になります。
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
前回は、JDBCを通してMVCパターンを具象してみましたが、今回はhtml,css,jsp,java,servletを活用し、MVCパターンを具象しました。
Controller - BMIResultController.java doGet()
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
<!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()
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()
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
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
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
<%@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>
Discussion