[21.1.22]Interceptor利用


受信者の設定


Handler Interceptor Adapterを継承するクラスの作成


1. preHandle(request, response, handler)

  • 書き換え方法
  • コントローラメソッドの作成要求が有効になる前に要求をブロックするために必要な機能
  • ほとんどのセッションは以前は機能的でした
  • handlerが含むオブジェクト
  • サーバが要求を処理する前に
  • @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    		throws Exception {
    	logger.info("===== preHandle 호출");
    	return super.preHandle(request, response, handler);
    }
    preHandle()の戻り値の意味
  • true:本来実行するコントローラメソッドを実行
  • false:コントローラメソッドを実行しない
  • 2. postHandle(request, response, handler, ModelAndView)

  • DispatcherServiceletコントローラメソッドの実行後にビュー(JSP)を処理する前に備えるべき機能の作成
  • ビューに戻る必要があるデータをModelAndView
  • に保存
  • クライアントが応答を受信する前に
  • @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    		ModelAndView modelAndView) throws Exception {
    	logger.info("===== postHandle 호출");
    	super.postHandle(request, response, handler, modelAndView);
    }
    ModelAndViewオブジェクト
  • ブロックされたパス上のモデルおよびビュー情報の取得
  • 3. aftetCompletion(request, response, handler, ex)

  • DispatcherServicelet画面処理(ビュー)完了後に完了する必要がある機能
  • @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    		throws Exception {
    	logger.info("===== afterCompletion 호출");
    	super.afterCompletion(request, response, handler, ex);
    }

    servlet-context.beanからxmlへのurlマッピングの設定

  • Bean管理Interceptorクラスの例
  • <beans:bean id="sample1" class="edu.spring.ex04.interceptor.SampleInterceptor1">
    </beans:bean>
  • Interceptor設定ブロックURLマッピング
  • <interceptors>
    	<interceptor>
    		<mapping path="/" />
    		<beans:ref bean="sample1" />
    	</interceptor>
    </interceptors>
    refのbeanをbeanのパスに設定し、ブロックします.
    データの送受信中に、ブロッカーがデータをブロックすることもあります.

    ブロッキングの使用例

    @GetMapping("/test1")
    public String test1() {
    	logger.info("test1() 호출");
    	return "test";
    }
    	
    @GetMapping("/test2")
    public String test2(Model model) {
    	logger.info("test2() 호출");
    	model.addAttribute("data", "test2");
    	return "test";
    }
  • データのないurlとデータのあるurlが存在する場合、preHandle()とpostHandle()を使用してブロック
  • @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    		throws Exception {
    	logger.info("===== preHandle 호출");
    	HandlerMethod handlerMethod=(HandlerMethod) handler;
    	Method method=handlerMethod.getMethod();
    		
    	//url 경로에 있는 bean 객체
    	logger.info("Bean : "+handlerMethod.getBean());
    	//url 경로에 있는 메소드 이름
    	logger.info("method : "+method.getName());
    		
    	return true;
    }
  • サーバがクライアント信号を受信する前に実行する方法.マッピングされたurlが呼び出されると、
  • がサーバより先に実行されます.
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    		ModelAndView modelAndView) throws Exception {
    	logger.info("===== postHandle 호출");
    	String data=(String)modelAndView.getModel().get("data");
    	logger.info("data : "+data);
    		
    	if(data==null) {
    		HttpSession session=request.getSession();
    		session.setAttribute("data", "DUMMY DATA");
    	}
    		
    	super.postHandle(request, response, handler, modelAndView);
    }

  • サーバがビューにデータを送信するときに実行する方法.サーバからデータが転送されてビューに到達する前に、データをブロックしてデータを干渉することができます.

  • モデルにデータがない場合は、セッションを作成してデータを置き換え、データがある場合は既存のデータで送信します.

  • 絵を使うと、このように遮断器が発生します.

    Interceptor-ログインセッションの確認


    ログインセッションの作成とチェックが必要な場合は、ブロッカーを使用して一般的なタスクを一度に処理できます.欠点はコードの流れを把握するのが難しいことです
    ブロッカーはログインセッションをチェックします.
    セッションがある場合は、コントローラメソッドの実行後に続行します(ブロッカーなし)
    ログインセッションがない場合は、ログインページに移動するurlを保存します.
    コントローラが実行される前にログインしているかどうかを確認するため、preHandle()のみが使用されます.
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    		throws Exception {
    	logger.info("===== preHandle 호출");
    	HttpSession session=request.getSession();
    	String userid=(String)session.getAttribute("userid");
    		
    	if(userid!=null) {
    		logger.info("로그인 상태 -> controller method 실행");
    		return true;
    	} else {
    		logger.info("로그아웃 상태 -> controller method 실행 안됨");
    			
    		//전체 요청 주소에서 쿼리 스트링을 제외한 부분
    		String uri=request.getRequestURI();
    		logger.info("요청 uri : "+uri);
    		String contextRoot=request.getContextPath();
    		logger.info("contextRoot : "+contextRoot);
    		uri=uri.replace(contextRoot, "");
    		
    		//전체 요청 주소에서 쿼리 스트링만 추출
    		String queryString=request.getQueryString();
    		logger.info("쿼리 스트링 : "+queryString);
    		
    		String targetURL="";
    		if(queryString==null) {
    			targetURL=uri;
    		}else {
    			targetURL=uri+"?"+queryString;
    		}
    		request.getSession().setAttribute("targetURL", targetURL);
    		
            	response.sendRedirect("/ex04/member/login");
    		return false;			
    	}
    }
    リクエストのcontrollerがリクエストに必要なことをしたい場合は、リクエストをパラメータとして受信するだけです.
    	@PostMapping("/login")
    	public String loginPost(String userid, String password, HttpServletRequest request) throws Exception{
    		logger.info("loginPost() 호출");
    		if(userid.equals("test") && password.equals("1234")) {
    			logger.info("로그인 성공");
    			HttpSession session=request.getSession();
    			session.setAttribute("userid", userid);
    			
    			//세션에서 targetURL 가져오기
    			String targetURL=(String)session.getAttribute("targetURL");
    			logger.info("목표 url : "+targetURL);
    			if(targetURL!=null) {
    				session.removeAttribute("targetURL");
    				return "redirect:"+targetURL;
    			}else {
    				return "redirect:/board/list";				
    			}
    			
    		}else {
    			logger.info("로그인 실패");
    			return "redirect:/member/login";
    		}
    	}

    imgScalr-画像サムネイル


    pom.xmlライブラリの追加

  • imgScale-画像サムネイル用ライブラリ
  • <dependency>
    	<groupId>org.imgscalr</groupId>
    	<artifactId>imgscalr-lib</artifactId>
    	<version>4.2</version>
    </dependency>
  • Multipart Fileアップロードライブラリ
  • <dependency>
    	<groupId>commons-fileupload</groupId>
    	<artifactId>commons-fileupload</artifactId>
    	<version>1.3.3</version>
    </dependency>

    servlet-context.xmlパスの追加

  • bean
  • に文字列リソースを追加
    <beans:bean id="uploadPath" class="java.lang.String">
    	<beans:constructor-arg value="C:\\Study\\FileUploadTest">
    	</beans:constructor-arg>
    </beans:bean>
    Javaでは、String uploadPath=new String("경로");しか使用できません.
    インスタンスの作成を続行し、beanとして追加して目的に応じて区別します.
  • ファイルアップロード最大容量設定:1024 x 1024 x 10 B=10 MB
  • <beans:bean id="multipartResolver" 
    	class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    	<beans:property name="maxUploadSize" value="10485760"></beans:property>
    </beans:bean>

    個々のファイルをアップロード


    <view.jsp>

  • enctype:データ符号化を示す
  • <form action="upload" method="post" enctype="multipart/form-data">
    	<input type="file" name="file"><br>
    	<input type="submit" value="업로드">
    </form>

    <controller.java>

  • servlet-context.xmlファイルに設定された文字列リソース
  • を入力
    @Resource(name ="uploadPath")
    private String uploadPath;
  • form受信ファイルアップロード
  • @PostMapping("/upload")
    public void uploadPost(MultipartFile file, Model model) {
    	logger.info("uploadPost() 호출");
    	logger.info("파일 이름 : "+file.getOriginalFilename());
    	logger.info("파일 크기 : "+file.getSize());
    		
    	String savedFile=saveUploadFile(file);
    	logger.info("저장된 파일 이름 : "+savedFile);		
    }
  • UUID:アップロードされたファイル名は重複しません
  • private String saveUploadFile(MultipartFile file) {	
    	UUID uuid=UUID.randomUUID();
    	String savedName=uuid+"_"+file.getOriginalFilename();
    	File target=new File(uploadPath, savedName);
    		
    	try {
    		FileCopyUtils.copy(file.getBytes(), target);
    		logger.info("파일 저장 성공");
    		return savedName;
    	} catch (IOException e) {
    		logger.error("파일 저장 실패");
    		return null;			
    	}
    }

    複数のファイルをアップロード


    <view.jsp>

    <form action="upload2" method="post" enctype="multipart/form-data">
    	<input type="file" name="files" multiple><br>
    	<input type="submit" value="업로드">
    </form>

    <Controller.java>

    @PostMapping("/upload2")
    public String uploadPost2(MultipartFile[] files, Model model) {
    	String result="";
    	for (MultipartFile f : files) {
    		result += saveUploadFile(f)+" ";
    	}
    	logger.info("result = "+result);
    	return "upload";
    }