7日目JSPサーブレット
41282 ワード
韓日
注意する。
文字列は「」で囲まなければならないので、外部の「」を置き換える必要があります.
イメージセットアイテム
ファイル構造
データベース構造
プロジェクトのデフォルトページの設定
web.xmlのwelcome-file-listタグの下にwelcome-fileタグを作成し、その間にページアドレスを入力します.
WEB-INF/web.xml
<welcome-file-list>
<!-- 이미지 갤러리 프로젝트의 기본페이지를 controller.java(서블릿)로 설정 -->
<welcome-file>gallery</welcome-file>
</welcome-file-list>
=>urlにhttp://localhost:ポート番号/プロジェクト名/と入力するとホームページのControllerとなります.servlet(このサーブレットのアドレスは「/Gallery」)Controller.java(servlet)
@WebServlet("/gallery")
public class Controller extends HttpServlet {
private static final long serialVersionUID = 1L;
private Map<String, String> actionMap = new HashMap<>();
public Controller() {
// 컨트롤러 생성자 (처음 시작할 때 한번 실행). key-value로 한묶음
actionMap.put("home", "/home.jsp");
actionMap.put("image", "/image.jsp");
actionMap.put("rate", "/image.jsp");
// 여기서 넣어준 key값으로 아래 doGet메서드가 실행되었을 때 key값이 action에 저장되고, 그 action을 통해 value값을 조회해 해당 주소로 forward해주는거임
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// action parameter 불러오기
String action = request.getParameter("action");
// 만약 action이 없거나 actionMap에 초기값이 없으면 action에 home을 넣음
if(action == null || !actionMap.containsKey(action)) action = "home";
// actionMap의 action값이 home이면 home.jsp페이지로, image면 image.jsp페이지로 이동
request.getRequestDispatcher(actionMap.get(action)).forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// image.jsp에서 post방식으로 받은 parameter(action, image, rating 총 세 가지 속성의 각 값)를 doGet으로 처리
doGet(request, response);
}
}
「アドレス」ウィンドウにhttp://localhost:8090/ImageGallery/、すなわちwebと入力します.xmlで設定したように/galeryに移動します.アドレスウィンドウにはアドレスが表示されませんが、この移動もget方式です.したがって、/galeryで作成したジェネレータが実行されるとdoGet()メソッドも順次実行されます.
1) private Map
2)コントローラ()メソッド(コントローラ作成者)は、最初に/ライブラリアドレスに移動したときに1回のみ実行し、1)作成した海図にkey-value値をペアで配置します.
3−1)doGetメソッドは,要求と応答をパラメータとして実行する.
request.getParameter(「アクション」)によって要求されたパラメータアクション属性の値を文字列アクション変数に格納します.
3-2)if文を使用して、現在のactionの値がnull(最初の接続時にaction=null)である場合、またはactionMap内部にキーがない場合、actionを「home」に設定します.
3-3)要求に格納されているアドレス(actionMap.get(action)=>actionに格納されているキー値、actionMapから一致する値を取得する)(要求と応答をパラメータとする)
=>パラメータ付きで移動します.
4)post方式でデータを受信するとdoPost()メソッドが実行され,現在作成されているメソッドはdoGetメソッドで受信したパラメータを直接処理する.
ページをヘッダー、ホームページ、フッターに分割
1つのページを必要な部分から別のjspファイルに切り取り、各ファイルを適切な場所にリンクします.
たとえば、ヘッダー、ホームページ、フッターに分けると、ホームページの上部はヘッダーのimport、下部はフッターのimportになります.
header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/style.css">
<title>${param.title}</title>
</head>
<body>
<div class="headerWrapper">
<div class="header">
<!-- {}안의 코드는 현재 프로젝트의 경로를 의미함 -->
<img src="${pageContext.request.contextPath}/images/logo.png"/>
<span id="title"></span>
</div>
</div>
<div class="content">
=>parameterはtitleプロパティのvalue値をhomeとして受信します.jspで指定します.home.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<!-- JSTL로 import해줌 -->
<!-- header.jsp의 title 값을 여기 value에 넣어서 지정해줌 -->
<c:import url="header.jsp">
<c:param name="title" value="Home"></c:param>
</c:import>
<!-- body태그 아래 들어갈 내용들. 자세한건 아래에 정리함. -->
<!-- footer.jsp를 import해줌-->
<c:import url="footer.jsp"></c:import>
=>header importタグ間でjstlを使用してparameterのtitle属性にheaderとして値を設定します.jspがtitleプロパティをパラメータとしてロードできるようにするfooter.jsp
</div>
<div id="footer">
<p>Copyright © 2022 Busan_IT</p>
</div>
</body>
</html>
DBから画像情報を取得する
ここで、アカウントidはroot、db名はwebshopである.
1) context.xmlリソースの変更
2)DBデータを使用するJSPファイルの上部
<%@tagliburi="http://java.sun.com/jsp/jstl/sql"prefix="sql"%>を入力してsqlライブラリのリンクを保留
META-INF/context.xml=>接続プール設定
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/webshop" auth="Container" type="javax.sql.DataSource"
maxActive="20" maxIdle="5" maxWait="10000"
username="계정id" password="계정비밀번호" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/webshop?useSSL=false"/>
</Context>
home.jsp<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<!-- header.jsp import하는 코드. 생략. -->
<!-- dataSource의 값이 context.xml의 resource 와 같아야 함 -->
<sql:setDataSource var="ds" dataSource="jdbc/webshop" />
<!-- 여기에 sql로 DB에 쿼리를 날려 값을 받아온 후 이미지를 나열하는 코드 작성 -->
画像を行単位で動的に表示
home.jsp
<!-- DB에서 전체이미지를 id순으로 검색해 이 결과를 results에 배열로 저장한다. -->
<sql:query var="results" dataSource="${ds}" sql="select * from images order by id" />
<!-- results에는 쿼리 실행결과가 저장되고 이것을 results.rows로 받아 한줄씩 row로 반복 -->
<!-- 경로(contextPath)/pics/사진이름.jpg 를 동적(Dynamic)으로 생성 -->
<!-- 한 행(8개)씩 변수 image에 저장. 갯수를 바꾸고싶으면 tablewidth의 value값 8을 다른 숫자로 바꿈 -->
<!-- 변수 picName(사진이름.확장자)을 만들어 이미지의 경로지정에 활용 -->
<table class="images">
<c:set var="tablewidth" value="8"></c:set>
<c:forEach var="image" items="${results.rows}" varStatus="row">
<c:if test="${row.index % tablewidth == 0}"><tr></c:if>
<c:set var="picName" scope="page" value="${image.stem}.${image.image_extension}"/>
<td>
<c:url value="/gallery?action=image&image=${image.id}" />
<a href="<c:url value="/gallery?action=image&image=${image.id}" />">
<img src="${pageContext.request.contextPath}/pics/${picName}">
</a>
</td>
<c:if test="${row.index+1 % tablewidth == 0}"></tr></c:if>
</c:forEach>
<!-- index번호가 8의 배수이면 tr이 열리고 td가 반복된 후 7의 배수가 되면 td의 반복을 멈추고 tr이 닫힘 => 한 행의 이미지가 8개가 됨 -->
</table>
=>picName変数の値は、動的に設定されたパスを介して「画像名.拡張子」をaラベルにリンクします.(jstlを使用してデータベースに格納された特定の属性を受信する値は${image.id}=>画像名,${image.image extension}=>画像拡張子である.排他画像ページ-画像を表示
home.jsp
<a href="<c:url value="/gallery?action=image&image=${image.id}" />">
<img src="${pageContext.request.contextPath}/pics/${picName}">
</a>
=>aタグのhrefを各画像のidに対応するリンクとして指定する.質問をする.なぜこのリンクでjspに移動しますよね?これは各画像へのリンクだけではありませんか?それはイメージを高めるしかないのではないでしょうか.
答えurl valueは、aタグのhref値をgetで移動します.
すなわち、現在クリックしている画像のid値を使用して、/ライブラリにナビゲートします.
コントロールサーバの基本ジェネレータでactionMapに予め配置されている3つのキー値の同じ値を検索し、対応するvalueアドレスに移動するdoGetメソッドが作成されました.
したがって,aタグからインポートしたパラメータはaction属性の値(image)を問合せ,対応する値/imageとする.jspで転送します.
画像名の最初の文字のみを大文字で表す
写真名を印刷するときは、最初の文字を大文字にし、残りの文字を小文字にします.
image.jsp
<c:out value="${fn:toUpperCase(fn:substring(image.stem, 0, 1))}${fn:toLowerCase(fn:substring(image.stem, 1, -1))}" />
=>ここでイメージ.stemは画像名の属性です.(データベース内の画像名のフィールド名はstem)データベースに格納されている画像のスコアを取得
データベース内の各画像の平均順位値を取得しますが、小数点以下の位置のみを取得します.
_image.jsp
<div class="rating">Rated: <fmt:formatNumber value="${average_ranking}" maxFractionDigits="1"/> (점수)</div>
画像のスコアリング-オブジェクトの使用(トランザクション)
DBを更新すると、一度に1つのタスクしか実行しないように変更されます.
2人以上が同時に採点した場合、データベース情報の変更異常を防止できます.
取引
image.jsp
<!-- 트랜젝션이 사용될때는 데이터소스가 하나밖에 없으므로 하나의 트랜젝션 안에 코드를 짜면 변수를 만들어 거기에 저장하고 사용하는 과정이 필요없음 -->
<sql:transaction dataSource="jdbc/webshop">
<!-- 여기서 param.image는 사진을 눌렀을 때 id가 넘어온 값임. 즉 ?에 id가 들어감 -->
<!-- 질문. 근데 이러면 results에는 id에 해당하는 하나의 값만 들어가는거 아닌가?? => 맞음. 하나의 값만 변수 results에 저장됨 -->
<sql:query var="results" sql="select * from images where id=?">
<sql:param>${param.image}</sql:param>
</sql:query>
<!-- id로 값을 찾기때문에 한 개만 선택됨 -->
<!-- results는 위에서 클릭한 이미지의 id에 해당하는 하나의 값만 가졌지만 results가 원래 배열이기때문에 배열의 가장 첫번째 값인 하나만 변수 image에 저장됨 -->
<c:set var="image" scope="page" value="${results.rows[0]}"></c:set>
<c:set var="picName" scope="page" value="${image.stem}.${image.image_extension}"/>
<c:set var="average_ranking" scope="page" value="${image.average_ranking}"/>
<!-- 이미지의 이름과 점수를 각각 picName, average_ranking 변수에 저장함 -->
<!-- /gallery에서 받아온 action이 "rate"이면 rankings와 average_ranking을 업데이트한다 -->
<c:if test='${param.action == "rate"}'>
<c:set scope="page" var="newRating" value="${(image.average_ranking*image.rankings + param.rating)/(image.rankings + 1)}"/>
<c:set scope="page" var="average_ranking" value="${newRating}" />
<sql:update sql="update images set average_ranking=?, rankings=? where id=?" >
<sql:param>${newRating}</sql:param>
<sql:param>${image.rankings + 1}</sql:param>
<sql:param>${param.image}</sql:param>
</sql:update>
</c:if>
<!-- (image.average_ranking*image.rankings + param.rating)/(image.rankings + 1) => (매긴점수*매긴횟수)+내가방금매긴점수 / 점수를 매긴 총 횟수(방금 내가 매겼으니 +1해주는것) -->
<!-- var="average_ranking" value="${newRating}"은 새로 바뀐 평균점수를 이전에 표시하던 평균점수변수에 덮어씌운것(덮어씌워 업데이트함) -->
<!-- sql:update아래에 있는 sql:param들은 순서대로 sql문의 ?에 들어간다 -->
</sql:transaction>
採点を取引と書くと、同時に複数の人が採点しても、順次平均点が適用されます.=>未採点時の初期画面
=>5分後、スコアが更新されました
完全なコード
後で追加します.
Reference
この問題について(7日目JSPサーブレット), 我々は、より多くの情報をここで見つけました https://velog.io/@0829kuj/jsp서블릿-7일차テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol