Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor...

48

Transcript of Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor...

Page 1: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe
Page 2: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Tytuł oryginału: Mastering Spring MVC 4

Tłumaczenie: Andrzej Watrak

ISBN: 978-83-283-2347-6

Copyright © 2015 Packt Publishing

First published in the English language under the title ‘Mastering Spring MVC 4 – (9781783982387)’.

Polish edition copyright © 2016 by Helion S.A. All rights reserved.

All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher.

Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji.

Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli.

Autor oraz Wydawnictwo HELION dołożyli wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie biorą jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Autor oraz Wydawnictwo HELION nie ponoszą również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce.

Wydawnictwo HELIONul. Kościuszki 1c, 44-100 GLIWICEtel. 32 231 22 19, 32 230 98 63e-mail: [email protected]: http://helion.pl (księgarnia internetowa, katalog książek)

Pliki z przykładami omawianymi w książce można znaleźć pod adresem: ftp://ftp.helion.pl/przyklady/smvc4p.zip

Drogi Czytelniku!Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/smvc4pMożesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.

Printed in Poland.

• Kup książkę• Poleć książkę • Oceń książkę

• Księgarnia internetowa• Lubię to! » Nasza społeczność

Page 3: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spis tre ci

O autorze 11

O korektorach merytorycznych 12

Przedmowa 15

Rozdzia 1. B yskawiczne tworzenie aplikacji Spring 19

Rozpocz cie pracy w rodowisku Spring Tool Suite 20Rozpocz cie pracy w rodowisku IntelliJ 25Rozpocz cie pracy w serwisie start.Spring.io 26

Rozpocz cie pracy za pomoc wiersza polece 26Pierwsze kroki 27

Kompilowanie kodu za pomoc narz dzia Gradle 28Chc zobaczy kod! 32

Spring Boot od wewn trz 34Dyspozytor i konfiguracja elementów aplikacji 35Interpreter widoków, zasoby statyczne i ustawienia regionalne 38

Konfiguracja obs ugi b dów i kodowania znaków 40Konfiguracja wbudowanego serwletu kontenera serwera (Tomcat) 42

Port HTTP 44Konfiguracja protoko u SSL 44Inne opcje konfiguracyjne 45

Podsumowanie 46

Rozdzia 2. Tajniki architektury MVC 47

Architektura MVC 47Krytyka architektury MVC i dobre praktyki 48

Anemiczny model domeny 48Informacje ze róde 50

Platforma MVC 1-0-1 50

Poleć książkęKup książkę

Page 4: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

4

Szablony Thymeleaf 51Twoja pierwsza strona 52

Architektura platformy Spring MVC 54Serwlet DispatcherServlet 54Przekazywanie danych do widoku 55

J zyk Spring Expression Language 56U ycie parametru przy odczytywaniu danych 56

Dosy ju „Witaj, wiecie!”, odczytujmy tweety! 58Rejestracja aplikacji 58Zastosowanie projektu Spring Social 60Dost p do serwisu Twitter 60

Strumienie i funkcje lambda w Java 8 62Styl material design i biblioteka WebJars 63

Uk ady stron 66Poruszanie si po witrynie 67

Punkt kontrolny 71Podsumowanie 72

Rozdzia 3. Obs uga formularzy i z o onych adresów URL 73

Strona profilu — formularz 73Weryfikacja danych 80

Dostosowanie komunikatów o b dach 82Niestandardowe adnotacje do weryfikacji danych 85

Internacjonalizacja 85Zmiana ustawie regionalnych 87T umaczenie tekstów aplikacji 89Lista w formularzu 91

Weryfikacja danych po stronie klienta 94Punkt kontrolny 96Podsumowanie 96

Rozdzia 4. adowanie plików i obs uga b dów 99

adowanie plików 99Umieszczanie obrazu w odpowiedzi na zapytanie 104Zarz dzanie konfiguracj adowania plików 104Wy wietlenie za adowanego obrazu 107Obs uga b dów adowania plików 108T umaczenia komunikatów o b dach 112

Zapisywanie profilu u ytkownika w sesji 112W asne strony z komunikatami o b dach 116Zmienne tablicowe w adresach URL 117Wszystko razem 121Punkt kontrolny 128Podsumowanie 129

Poleć książkęKup książkę

Page 5: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spis tre ci

5

Rozdzia 5. Tworzenie aplikacji w stylu REST 131

Czym jest styl REST? 131Model dojrza o ci Richardsona 132

Poziom 0 — HTTP 132Poziom 1 — zasoby 132Poziom 2 — metody HTTP 133Poziom 3 — kontrolki hipermediów 134

Wersje interfejsu API 135Przydatne kody HTTP 136Klient jest królem 137Diagnostyka interfejsu REST API 139

Rozszerzenia przegl darek wy wietlaj ce format JSON 139Klient REST w przegl darce 139Narz dzie httpie 139

Dostosowanie odpowiedzi JSON 139Interfejs API do zarz dzania zasobami u ytkowników 144Kody stanu i obs uga wyj tków 147

Zwrot kodu stanu za pomoc obiektu ResponseEntity 148Zwrot kodów stanu za pomoc wyj tków 149

Dokumentowanie interfejsu za pomoc platformy Swagger 153Tworzenie odpowiedzi XML 154Punkt kontrolny 156Podsumowanie 157

Rozdzia 6. Zabezpieczanie aplikacji 159

Podstawowe uwierzytelnienie 159Upowa nieni u ytkownicy 160Uprawnione adresy URL 163Znaczniki bezpiecze stwa w szablonie Thymeleaf 164

Formularz logowania 165Uwierzytelnienie przez Twitter 170

Konfiguracja uwierzytelnienia spo eczno ciowego 170Obja nienia do kodu 174

Rozproszone sesje 176Protokó SSL 178

Generowanie certyfikatu z w asnym podpisem 179Jeden kana 179Dwa kana y 180Za bezpiecznym serwerem 181

Punkt kontrolny 181Podsumowanie 182

Rozdzia 7. Zero ryzyka — testy jednostkowe i integracyjne 183

Dlaczego powinienem testowa swój kod? 183Jak powiniene testowa swój kod? 184Programowanie zorientowane na testy 185

Poleć książkęKup książkę

Page 6: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

6

Testy jednostkowe 186Narz dzia odpowiednie do zadania 187

Testy integracyjne 187Twój pierwszy test jednostkowy 188Imitacje i atrapy 191

Imitowanie klas przy u yciu narz dzia Mockito 191Tworzenie atrap klas podczas testów 193Trzeba u ywa imitacji czy atrap? 195

Testy jednostkowe kontrolerów REST 195Testowanie uwierzytelnienia 201Tworzenie testów integracyjnych 202

Konfiguracja systemu Gradle 202Pierwszy test FluentLenium 204Obiekty stron w bibliotece FluentLenium 209Tworzenie testów w j zyku Groovy 212Testy jednostkowe z wykorzystaniem biblioteki Spock 212Testy integracyjne z wykorzystaniem biblioteki Geb 215Obiekty stron w bibliotece Geb 217

Punkt kontrolny 220Podsumowanie 221

Rozdzia 8. Optymalizacja zapyta 223

Produkcyjny profil aplikacji 223Kompresja gzip 224Kontrola pami ci podr cznej 224Pami podr czna aplikacji 226

Uniewa nianie danych w pami ci podr cznej 231Rozproszona pami podr czna 232

Metody asynchroniczne 233Tagi ETag 237Protokó WebSocket 241Punkt kontrolny 244Podsumowanie 244

Rozdzia 9. Udost pnianie aplikacji w chmurze 245

Wybór operatora us ug chmurowych 245Cloud Foundry 246OpenShift 246Heroku 247

Udost pnienie aplikacji w us udze Pivotal Web Services 247Instalacja narz dzi konsolowych Cloud Foundry 247Z o enie aplikacji 248Aktywacja us ugi Redis 252

Udost pnienie aplikacji w us udze Heroku 253Instalacja narz dzi 253Konfiguracja aplikacji 254Profil Heroku 255

Poleć książkęKup książkę

Page 7: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spis tre ci

7

Uruchomienie aplikacji 256Aktywacja us ugi Redis 258

Ulepszanie aplikacji 259Podsumowanie 260

Rozdzia 10. Nie tylko Spring Web 261

Platforma Spring 261Core (rdze ) 262Execution (uruchamianie) 262Data (dane) 262Inne ciekawe projekty 263

Wdro enie 263Platforma Docker 263

Aplikacje jednostronicowe 264Najwa niejsi gracze 265Przysz o 265Bezstanowo 266

Podsumowanie 266

Skorowidz 267

Poleć książkęKup książkę

Page 8: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

8

Poleć książkęKup książkę

Page 9: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

4

adowanie plikówi obs uga b dów

W tym rozdziale umo liwisz u ytkownikom adowanie obrazów do profili. Dowiesz si rów-nie , jak obs ugiwa b dy w platformie Spring MVC.

adowanie plikówTeraz umo liwisz u ytkownikom adowanie obrazów do profili. Opis, jak to zrobi , znajduje siw dalszej cz ci rozdzia u, ale teraz upro nieco projekt i utwórz w katalogu templates/profilenow stron uploadPage.html:

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorator="layout/default"> <head lang="pl"> <title> adowanie obrazu</title> </head> <body> <div class="row" layout:fragment="content"> <h2 class="indigo-text center"> adowanie obrazu</h2> <form th:action="@{/upload}" method="post" enctype="multipart/form-data" class="col m8 s12 offset-m2"> <div class="input-field col s6"> <input type="file" id="file" name="file"/> </div> <div class="col s6 center">

Poleć książkęKup książkę

Page 10: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

100

<button class="btn indigo waves-effect waves-light" type="submit" name="save" th:text="#{submit}">Wy lij <i class="mdi-content-send right"></i> </button> </div> </form> </div> </body></html>

Nie ma tu niczego ciekawego poza atrybutem enctype. Plik z obrazem b dzie wysy any metodPOST na adres URL upload. Teraz w pakiecie profile obok klasy ProfileController utwórz od-powiedni kontroler:

package masterSpringMvc.profile;

import org.apache.tomcat.util.http.fileupload.IOUtils;import org.springframework.core.io.FileSystemResource;import org.springframework.core.io.Resource;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.multipart.MultipartFile;

import java.io.*;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;

@Controllerpublic class PictureUploadController { public static final Resource PICTURES_DIR = new FileSystemResource("./pictures");

@RequestMapping("upload") public String uploadPage() { return "profile/uploadPage"; }

@RequestMapping(value = "/upload", method = RequestMethod.POST) public String onUpload(MultipartFile file) throws IOException { String filename = file.getOriginalFilename(); File tempFile = File.createTempFile("pic", getFileExtension(filename), PICTURES_DIR.getFile()); try (InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(tempFile)) { IOUtils.copy(in, out); }

Poleć książkęKup książkę

Page 11: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

101

return "profile/uploadPage"; }

private static String getFileExtension(String name) { return name.substring(name.lastIndexOf(".")); }}

Pierwsz operacj wykonywan przez powy szy kod jest utworzenie tymczasowego pliku w kata-logu pictures (obrazy), znajduj cym si w g ównym katalogu projektu. Sprawd wi c, czy tenkatalog istnieje. W j zyku Java tymczasowy plik posiada unikatowy identyfikator w systemieplików. Usuni cie pliku zale y od u ytkownika.

Utwórz w g ównym katalogu projektu katalog pictures, a w nim pusty plik o nazwie .gitkeep,aby katalog by zapisywany w systemie Git.

Puste katalogi w systemie Git

System Git s u y do zarz dzania plikami i nie ma mo liwo ci zapisywania w nim pustych katalogów.Powszechnie stosowan metod omini cia tego ograniczenia jest stosowanie pustych plików, na przyk ad.gitkeep. W ten sposób zmusza si system do uwzgl dniania katalogu w procesie kontroli wersji projektu.

Plik adowany przez u ytkownika jest reprezentowany w kontrolerze przez interfejs MultipartFile. Interfejs ten posiada kilka metod zwracaj cych nazw pliku, jego wielko i zawarto .

Szczególnie interesuje nas metoda getInputStream. Reprezentowany przez ni strumie wej-ciowy zostanie skopiowany do metody fileOutputStream za pomoc metody IOUtils.copy.

Pisanie kodu kopiuj cego strumie wej ciowy do wyj ciowego jest do nudne, wi c wygodniejb dzie skorzysta z biblioteki Apache Utils, zawartej w pliku tomcat-embed-core.jar, umiesz-czonym w cie ce classpath.

W tej cz ci b dziesz intensywnie wykorzystywa ciekawe funkcjonalno ci platformy Springi biblioteki NIO wprowadzonej w wersji Java 7:

pomocnicz klas String reprezentuj c zasób, który mo na przetwarza na ró nesposoby;

blok instrukcji try...with automatycznie zamykaj cy strumie nawet w przypadkuwyst pienia wyj tku, dzi ki czemu nie trzeba ka dorazowo definiowa bloku finally.

W powy szym kodzie ka dy plik za adowany przez u ytkownika zostanie skopiowany do ka-talogu pictures.

Platforma Spring Boot oferuje kilka w a ciwo ci umo liwiaj cych dostosowanie procesu a-dowania plików. Przyjrzyjmy si klasie MultipartProperties.

Poleć książkęKup książkę

Page 12: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

102

Jej najciekawsze w a ciwo ci to: multipart.maxFileSize, w a ciwo definiuj ca maksymaln wielko adowanego

pliku. Przy próbie za adowania wi kszego pliku jest zg aszany wyj tekMultipartException. Domy lna wielko pliku to 1 MB.

multipart.maxRequestSize, w a ciwo definiuj ca maksymaln wielko daniawielocz ciowego. Domy lna wielko to 10 MB.

Powy sze warto ci domy lne s odpowiednie dla Twojej aplikacji. Po za adowaniu kilku pli-ków katalog pictures b dzie wygl da nast puj co:

Zaczekaj! Kto za adowa plik ZIP! A trudno w to uwierzy . Trzeba w kodzie kontrolera spraw-dza , czy adowane pliki faktycznie reprezentuj obrazy:

package masterSpringMvc.profile;

import org.apache.tomcat.util.http.fileupload.IOUtils;import org.springframework.core.io.FileSystemResource;import org.springframework.core.io.Resource;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.servlet.mvc.support.RedirectAttributes;import java.io.*;

@Controllerpublic class PictureUploadController { public static final Resource PICTURES_DIR = newFileSystemResource("./pictures");

@RequestMapping("upload") public String uploadPage() { return "profile/uploadPage"; }

@RequestMapping(value = "/upload", method = RequestMethod.POST) public String onUpload(MultipartFile file, RedirectAttributes redirectAttrs) throws IOException { if (file.isEmpty() || !isImage(file)) { redirectAttrs.addFlashAttribute("error", "Niew a ciwy plik. Za aduj plik z obrazem."); return "redirect:/upload";

Poleć książkęKup książkę

Page 13: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

103

} copyFileToPictures(file); return "profile/uploadPage"; }

private Resource copyFileToPictures(MultipartFile file) throws IOException { String fileExtension = getFileExtension(file.getOriginalFilename()); File tempFile = File.createTempFile("pic", fileExtension, PICTURES_DIR.getFile()); try (InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(tempFile)) { IOUtils.copy(in, out); } return new FileSystemResource(tempFile); }

private boolean isImage(MultipartFile file) { return file.getContentType().startsWith("image"); }

private static String getFileExtension(String name) { return name.substring(name.lastIndexOf(".")); }}

Bardzo proste! Metoda getContentType zwraca informacj o typie pliku w formacie MIME (ang.Multipurpose Internet Mail Extensions — uniwersalne rozszerzenie poczty internetowej), np.image/png, image/jpg itp. Wystarczy wi c sprawdzi , czy ci g MIME rozpoczyna si od s owaimage.

W formularzu zosta a zakodowana obs uga b dów, wi c trzeba rozbudowa stron o jakie ele-menty umo liwiaj ce wy wietlanie komunikatów. Wpisz w pliku uploadPage.html nast puj -ce wiersze tu poni ej tytu u strony:

<div class="col s12 center red-text" th:text="${error}" th:if="${error}"> B d adowania pliku</div>

Przy nast pnej próbie za adowania pliku ZIP pojawi si komunikat o b dzie, jak na poni -szym rysunku:

Poleć książkęKup książkę

Page 14: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

104

Umieszczanie obrazu w odpowiedzi na zapytanieadowane obrazy nie s zapisywane w statycznych katalogach. Aby wy wietli je na stronie

trzeba przedsi wzi specjalne rodki.

W kodzie strony uploadPage.html tu nad znacznikiem form wpisz poni sze wiersze:

<div class="col m8 s12 offset-m2"> <img th:src="@{/uploadedPicture}" width="100" height="100"/></div>

Powy szy kod b dzie próbowa pobra obraz z kontrolera. W klasie PictureUploadControllerutwórz odpowiedni metod :

@RequestMapping(value = "/uploadedPicture")public void getUploadedPicture(HttpServletResponse response) throws IOException { ClassPathResource classPathResource = new ClassPathResource("/images/anonymous.png"); response.setHeader("Content-Type", URLConnection.guessContentTypeFromName(classPathResource.getFilename())); IOUtils.copy(classPathResource.getInputStream(), response.getOutputStream());}

Powy szy kod b dzie umieszcza bezpo rednio w odpowiedzi obraz z pliku src/main/resources/images/anonymous.png. To bardzo ciekawy sposób!

Je eli ponownie otworzysz stron , pojawi si na niej nast puj cy obraz:

Rysunek anonimowego u ytkownika znalaz em na stronie http://iconmonstr.com/user-icon i zapisa emgo jako obraz o wymiarach 128×128 pikseli w pliku PNG.

Zarz dzanie konfiguracj adowania plikówW tym momencie warto jest okre li w pliku konfiguracyjnym application.properties katalogdla adowanych obrazów i cie k do rysunku anonimowego u ytkownika.

Poleć książkęKup książkę

Page 15: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

105

Utwórz pakiet config, a w nim klas PicturesUploadProperties:

package masterSpringMvc.config;

import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.core.io.DefaultResourceLoader;import org.springframework.core.io.Resource;import java.io.IOException;

@ConfigurationProperties(prefix = "upload.pictures")public class PictureUploadProperties { private Resource uploadPath; private Resource anonymousPicture;

public Resource getAnonymousPicture() { return anonymousPicture; }

public void setAnonymousPicture(String anonymousPicture) { this.anonymousPicture = new DefaultResourceLoader().getResource (anonymousPicture); }

public Resource getUploadPath() { return uploadPath; }

public void setUploadPath(String uploadPath) { this.uploadPath = new DefaultResourceLoader().getResource(uploadPath); }}

W tej klasie wykorzystany zosta pakiet ConfigurationProperties platformy Spring Boot, umo li-wiaj cy automatyczne mapowanie w a ciwo ci znalezionych w plikach umieszczonych w cie ceclasspath (domy lnie w pliku application.properties), z uwzgl dnieniem typów tych w a ciwo ci.

Zwró uwag , e zdefiniowana jest metoda z argumentem typu String, ale nic nie stoi na prze-szkodzie, aby inna metoda zwraca a inny typ danych, który b dzie najprzydatniejszy.

Teraz w pakiecie config zdefiniuj klas PicturesUploadProperties:

@SpringBootApplication@EnableConfigurationProperties({PictureUploadProperties.class})public class MasterSpringMvc4Application extends WebMvcConfigurerAdapter { // kod pomini ty}

W pliku application.properties zdefiniuj nast puj ce w a ciwo ci:

upload.pictures.uploadPath=file:./picturesupload.pictures.anonymousPicture=classpath:/images/anonymous.png

Poleć książkęKup książkę

Page 16: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

106

Poniewa u yta zosta a klasa DefaultResourceLoader platformy Spring, mo na zastosowa prefiksy,np. file: lub classpath: do okre lenia po o enia zasobów.

Jest to sposób alternatywny do utworzenia klasy FileSystemResource lub ClassPathResource.

Zalet powy szej metody jest mo liwo dokumentowania kodu. Dzi ki niej od razu wida ,e katalog z obrazami znajduje si w g ównym katalogu obiektu, natomiast obraz przedstawiaj cy

anonimowego u ytkownika znajduje si w pliku zapisanym w cie ce classpath.

To wszystko. Teraz mo na wykorzysta zdefiniowane w a ciwo ci w kontrolerze. Poni ej przed-stawione s odpowiednie cz ci klasy PictureUploadController:

package masterSpringMvc.profile;

import masterSpringMvc.config.PictureUploadProperties;import org.apache.tomcat.util.http.fileupload.IOUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.core.io.Resource;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletResponse;import java.io.*;import java.net.URLConnection;

@Controllerpublic class PictureUploadController { private final Resource picturesDir; private final Resource anonymousPicture;

@Autowired public PictureUploadController(PictureUploadProperties uploadProperties) { picturesDir = uploadProperties.getUploadPath(); anonymousPicture = uploadProperties.getAnonymousPicture(); }

@RequestMapping(value = "/uploadedPicture") public void getUploadedPicture(HttpServletResponse response) throws IOException { response.setHeader("Content-Type", URLConnection.guessContentTypeFromName(anonymousPicture.getFilename())); IOUtils.copy(anonymousPicture.getInputStream(), response.getOutputStream()); }

private Resource copyFileToPictures(MultipartFile file) throws IOException {

Poleć książkęKup książkę

Page 17: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

107

String fileExtension = getFileExtension(file.getOriginalFilename()); File tempFile = File.createTempFile("pic", fileExtension, picturesDir.getFile()); try (InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(tempFile)) { IOUtils.copy(in, out); } return new FileSystemResource(tempFile); } // Pozosta a cz kodu pozostaje bez zmian}

Je eli uruchomisz aplikacj ponownie, stwierdzisz, e strona si nie zmieni a. Obraz anoni-mowego u ytkownika b dzie dalej pokazywany, a obrazy adowane przez u ytkowników b ddalej zapisywane w podkatalogu pictures w g ównym katalogu projektu.

Wy wietlenie za adowanego obrazuTeraz dobrze by oby wy wietli obraz za adowany przez u ytkownika, prawda? W tym celudo klasy PictureUploadController dodaj atrybut modelu:

@ModelAttribute("picturePath")public Resource picturePath() { return anonymousPicture;}

Umie powy szy atrybut w kodzie, aby odczyta jego warto po za adowaniu obrazu:

@RequestMapping(value = "/uploadedPicture")public void getUploadedPicture(HttpServletResponse response, @ModelAttribute("picturePath") Path picturePath) throws IOException { response.setHeader("Content-Type", URLConnection.guessContentTypeFromName(picturePath.toString())); Files.copy(picturePath, response.getOutputStream());}

Adnotacja @ModelAttribute umo liwia wygodne tworzenie atrybutów modelu dla wybranychmetod, które potem mo na umieszcza w metodzie kontrolera z t sam adnotacj . W powy szymkodzie parametr picturePath b dzie dost pny w modelu danych do czasu przekierowaniau ytkownika na inn stron . Jego domy ln warto ci jest zdefiniowana we w a ciwo ciachnazwa pliku z obrazem anonimowego u ytkownika.

Po za adowaniu pliku trzeba zaktualizowa warto atrybutu. Zmie w tym celu metod onUpload:

@RequestMapping(value = "/upload", method = RequestMethod.POST)public String onUpload(MultipartFile file, RedirectAttributes redirectAttrs, Model model) throws IOException { if (file.isEmpty() || !isImage(file)) {

Poleć książkęKup książkę

Page 18: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

108

redirectAttrs.addFlashAttribute("error", "Niew a ciwy plik. Za aduj plik z obrazem."); return "redirect:/upload"; } Resource picturePath = copyFileToPictures(file); model.addAttribute("picturePath", picturePath); return "profile/uploadPage";}

Dzi ki umieszczeniu w kodzie odwo ania do modelu mo na odczyta warto parametru picturePath po za adowaniu obrazu.

Teraz problem polega na tym, e metody onUpload i getUploadedPicture s wywo ywane w ró -nych zapytaniach. Niestety, warto ci atrybutów modelu s usuwane pomi dzy kolejnymi za-pytaniami.

Dlatego parametr picturePath trzeba zdefiniowa jako atrybut sesji. W tym celu klas kon-trolera nale y opatrzy dodatkow adnotacj :

@Controller@SessionAttributes("picturePath")public class PictureUploadController {}

Uff! Sporo adnotacji jak na prost obs ug atrybutu sesji. Teraz strona b dzie wygl da a jakponi ej:

W ten sposób mo na naprawd atwo tworzy kod. Ponadto nie trzeba bezpo rednio stosowainterfejsu HttpServletRequest ani HttpSession. Co wi cej, mo na równie atwo okre la typobiektu.

Obs uga b dów adowania plikówWnikliwy Czytelnik z pewno ci zauwa y, e powy szy kod mo e zg asza dwa rodzaje wy-j tków:

Poleć książkęKup książkę

Page 19: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

109

IOException: wyj tek zg aszany w sytuacji, gdy co z ego wydarzy si podczaszapisywania pliku na dysku;

MultipartException: wyj tek zg aszany w sytuacji, gdy podczas adowania plikuwyst pi b d, na przyk ad przekroczona zostanie maksymalna wielko pliku.

Teraz jest dobra okazja do zapoznania si z dwoma sposobami obs ugi b dów w rodowiskuSpring:

poprzez lokalne u ycie adnotacji @ExceptionHandler w metodzie kontrolera, poprzez zdefiniowanie globalnego kontenera serwletów.

Obs u wyj tek IOException za pomoc poni szej metody z adnotacj @ExceptionHandler, utwo-rzonej w klasie PictureUploadController:

@ExceptionHandler(IOException.class)public ModelAndView handleIOException(IOException exception) { ModelAndView modelAndView = new ModelAndView("profile/uploadPage"); modelAndView.addObject("error", exception.getMessage()); return modelAndView;}

To prosty, ale skuteczny sposób. Powy sza metoda b dzie wywo ywana za ka dym razem, gdyw kontrolerze zostanie zg oszony wyj tek IOException.

Zg aszanie wyj tków w kodzie Java jest do trudne, wi c w celu sprawdzenia dzia ania me-tody obs ugi wyj tku zmie na czas testów kod metody onUpload w nast puj cy sposób:

@RequestMapping(value = "/upload", method = RequestMethod.POST)public String onUpload(MultipartFile file, RedirectAttributesredirectAttrs, Model model) throws IOException { throw new IOException("Komunikat testowy");}

Po wprowadzeniu powy szych zmian i za adowaniu obrazu na stronie pojawi si poni szykomunikat:

Poleć książkęKup książkę

Page 20: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

110

Teraz trzeba obs u y wyj tek MultipartException. Nale y to zrobi na poziomie konteneraserwletów (czyli serwera Tomcat), poniewa wyj tek ten nie jest zg aszany bezpo rednio przezkontroler.

W tym celu musisz utworzy now metod konfiguracyjn EmbeddedServletContainerCustomizerw klasie WebConfiguration:

@Beanpublic EmbeddedServletContainerCustomizer containerCustomizer() { EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer = new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { container.addErrorPages(new ErrorPage(MultipartException.class, "/uploadError")); } }; return embeddedServletContainerCustomizer;}

Kod jest nieco rozwlek y. Zwró uwag , e EmbeddedServletContainerCustomizer to interfejszawieraj cy jedn metod , któr mo na zast pi wyra eniem lambda:

@Beanpublic EmbeddedServletContainerCustomizer containerCustomizer() { EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer = container -> container.addErrorPages(new ErrorPage(MultipartException.class, "/uploadError")); return embeddedServletContainerCustomizer;}

Mo na wi c po prostu napisa taki kod:

@Beanpublic EmbeddedServletContainerCustomizer containerCustomizer() { return container -> container.addErrorPages(newErrorPage(MultipartException.class, "/uploadError"));}

Powy szy kod tworzy now stron z komunikatem o b dzie, która b dzie wy wietlana w momen-cie zg oszenia wyj tku MultipartException. B dzie ona równie powi zana z kodem HTTP.Interfejs EmbeddedServletContainerCustomizer posiada wiele innych funkcjonalno ci umo li-wiaj cych dostosowanie kontenera serwletów odpowiednio do dzia ania aplikacji. Wi cej informa-cji na ten temat jest dost pnych pod adresem http://docs.spring.io/spring-boot/docs/current/ refe-rence/html/boot-features-developing-web-applications.html#boot-features-customizing-embedded-containers.

Poleć książkęKup książkę

Page 21: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

111

Teraz w klasie PictureUploadController trzeba obs u y adres URL uploadError:

@RequestMapping("uploadError")public ModelAndView onUploadError(HttpServletRequest request) { ModelAndView modelAndView = new ModelAndView("uploadPage"); modelAndView.addObject("error", request.getAttribute(WebUtils.ERROR_MESSAGE_ATTRIBUTE)); return modelAndView;}

Strony z komunikatami o b dach zdefiniowane w kontenerze serwletów posiadaj kilka cie-kawych atrybutów umo liwiaj cych diagnozowanie b dów:

Atrybut Opis

javax.servlet.error.status_code Kod HTTP b dujavax.servlet.error.exception_type Klasa wyj tkujavax.servlet.error.message Komunikat o wyj tkujavax.servlet.error.request_uri Adres URL, dla którego zosta zg oszony wyj tekjavax.servlet.error.exception W a ciwy wyj tekjavax.servlet.error.servlet_name Nazwa serwletu zg aszaj cego wyj tek

Z powy szych atrybutów mo na wygodnie korzysta dzi ki klasie WebUtils z biblioteki SpringWeb.

Je eli u ytkownik spróbuje za adowa bardzo du y obraz, pojawi si czytelny komunikat.

Teraz mo esz sprawdzi , czy b d jest poprawnie obs ugiwany, aduj c du y plik (wi kszy ni1 MB) lub ustawiaj c w a ciwo multipart.maxFileSize na mniejsz warto , na przyk ad 1 kB.

Poleć książkęKup książkę

Page 22: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

112

T umaczenia komunikatów o b dachDla programisty komunikaty o wyj tkach wy wietlane na stronie s naprawd cenne, jednakdla u ytkownika nie przedstawiaj wi kszej warto ci. Dlatego musisz je przet umaczy . W tymcelu w konstruktorze kontrolera nale y zastosowa klas MessageSource:

private final MessageSource messageSource;@Autowiredpublic PictureUploadController(PictureUploadProperties uploadProperties, MessageSource messageSource) { picturesDir = uploadProperties.getUploadPath(); anonymousPicture = uploadProperties.getAnonymousPicture(); this.messageSource = messageSource;}

Teraz mo esz odczytywa komunikaty zapisane w pliku:@ExceptionHandler(IOException.class)public ModelAndView handleIOException(Locale locale) { ModelAndView modelAndView = new ModelAndView("profile/uploadPage"); modelAndView.addObject("error", messageSource.getMessage("upload.io.exception", null, locale)); return modelAndView;}

@RequestMapping("uploadError")public ModelAndView onUploadError(Locale locale) { ModelAndView modelAndView = new ModelAndView("profile/uploadPage"); modelAndView.addObject("error", messageSource.getMessage("upload.file.too.big", null, locale)); return modelAndView;}

Poni ej zdefiniowane s komunikaty:

upload.io.exception=Podczas adowania pliku wyst pi b d. Spróbuj jeszcze raz.upload.file.too.big=Plik jest za du y.

I jeszcze komunikaty w j zyku angielskim:

upload.io.exception=An error occurred while uploading the file. Please try again.upload.file.too.big=Your file is too big.

Zapisywanie profilu u ytkownika w sesjiKolejn niezb dn rzecz jest zapisywanie profilu u ytkownika w sesji, dzi ki czemu informacjenie b d z niego usuwane przy ka dorazowym wy wietleniu strony. Takie dzia anie aplikacjiby oby dla u ytkowników irytuj ce, wi c musisz to zmieni .

Poleć książkęKup książkę

Page 23: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

113

Sesje HTTP umo liwiaj przechowywanie informacji przesy anych w zapytaniach. Protokó HTTP jestprotoko em bezstanowym, tzn. nie ma mo liwo ci powi zania dwóch zapyta wysy anych przez tegosamego u ytkownika. Wi kszo kontenerów serwletów przypisuje ka demu u ytkownikowi plik cia-steczka o nazwie JSESSIONID. Plik ten jest przesy any w nag ówku zapytania i umo liwia zapisywaniedowolnych obiektów w mapie o nazwie HttpSession (sesja HTTP). Taka sesja zazwyczaj ko czy siw chwili zamkni cia przegl darki przez u ytkownika lub po okre lonym czasie braku jego aktywno ci.

Wcze niej pozna e sposób umieszczania obiektów w sesji za pomoc adnotacji @SessionAttributes. Ta metoda dobrze sprawdza si wewn trz jednego kontrolera, ale gdy jest ich kilka,

wtedy pojawiaj si problemy ze wspó dzieleniem danych. Aby móc identyfikowa atrybut napodstawie jego nazwy, trzeba stosowa ci g znaków, co utrudnia modyfikacj kodu. Z tegosamego powodu nie mo na bezpo rednio manipulowa obiektem HttpSession. Kolejnym ar-gumentem przemawiaj cym przeciwko bezpo redniemu manipulowaniu sesj s utrudnieniaw wykonywaniu testów jednostkowych kontrolera.

W rodowisku Spring stosuje si jednak inny popularny sposób zapisywania informacji w sesji,mianowicie opatrywanie metody adnotacj @Scope("session").

Dzi ki temu mo na umieszcza metody w kontrolerach lub innych komponentach aplikacjiSpring, aby odczytywa b d zapisywa w nich dane.

Utwórz w pakiecie profile klas UserProfileSession:

package masterSpringMvc.profile;

import org.springframework.context.annotation.Scope;import org.springframework.context.annotation.ScopedProxyMode;import org.springframework.stereotype.Component;import java.io.Serializable;import java.time.LocalDate;import java.util.ArrayList;import java.util.List;

@Component@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)public class UserProfileSession implements Serializable { private String twitterHandle; private String email; private LocalDate birthDate; private List<String> tastes = new ArrayList<>();

public void saveForm(ProfileForm profileForm) { this.twitterHandle = profileForm.getTwitterHandle(); this.email = profileForm.getEmail(); this.birthDate = profileForm.getBirthDate(); this.tastes = profileForm.getTastes(); }

Poleć książkęKup książkę

Page 24: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

114

public ProfileForm toForm() { ProfileForm profileForm = new ProfileForm(); profileForm.setTwitterHandle(twitterHandle); profileForm.setEmail(email); profileForm.setBirthDate(birthDate); profileForm.setTastes(tastes); return profileForm; }}

Zaimplementowa e wygodny sposób odczytywania i zapisywania danych w postaci obiektuProfileForm. Dzi ki temu b dziesz móg zapisywa i odczytywa dane z kontrolera ProfileController. Musisz w nim umie ci zmienn typu UserProfileSession i zapisa j jako pole

klasy. Ponadto musisz udost pni obiekt ProfileForm jako atrybut modelu, dzi ki czemu nietrzeba b dzie stosowa go w metodzie displayProfile. Na koniec dane profilu po ich spraw-dzeniu nale y zapisa :

@Controllerpublic class ProfileController { private UserProfileSession userProfileSession;

@Autowired public ProfileController(UserProfileSession userProfileSession) { this.userProfileSession = userProfileSession; }

@ModelAttribute public ProfileForm getProfileForm() { return userProfileSession.toForm(); }

@RequestMapping(value = "/profile", params = {"save"}, method = RequestMethod.POST) public String saveProfile(@Valid ProfileForm profileForm, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "profile/profilePage"; } userProfileSession.saveForm(profileForm); return "redirect:/profile"; } // Pozosta a cz kodu bez zmian}

To wszystko, co trzeba zrobi w aplikacji Spring, aby zapisywa dane w sesji.

Je eli teraz u ytkownik wype ni formularz i od wie y stron , wprowadzone dane b d zachowane.

Teraz zamierzam opisa kilka u ytych wcze niej poj .

Poleć książkęKup książkę

Page 25: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

115

Pierwsze z nich to umieszczanie (wstrzykiwanie) obiektów w konstruktorze. Konstruktorkontrolera ProfileController jest opatrzony adnotacj @Autowired, oznaczaj c , e platformaSpring b dzie przetwarza a argumenty konstruktora przed utworzeniem instancji klasy. Alterna-tywnym rozwi zaniem, nieco mniej obszernym, jest zastosowanie wstrzykiwania pól:

@Controllerpublic class ProfileController { @Autowired private UserProfileSession userProfileSession;}

Wstrzykiwanie obiektów w konstruktorze jest zdecydowanie lepszym sposobem, poniewau atwia wykonywanie testów jednostkowych, gdyby trzeba by o zrezygnowa z testów oferowa-nych przez platform Spring. Ponadto zale no ci mi dzy klasami s nieco ci lejsze.

Szczegó owy opis wstrzykiwania pól i konstruktorów jest zawarty w doskona ym wpisie nablogu Olivera Gierkego pod adresem http://olivergierke.de/2013/11/why-field-injection-is-evil.

Kolejn rzecz wymagaj c wyja nienia jest parametr proxyMode (tryb serwera proxy) w adnota-cji @Scope:

@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)

W platformie Spring dost pne s trzy warto ci parametru proxyMode, nie licz c domy lnego: TARGET_CLASS — oznaczaj cy zastosowanie serwera CGI, INTERFACES — oznaczaj cy zastosowanie serwera JDK, NO — oznaczaj cy brak serwera proxy.

Zaleta serwera proxy zazwyczaj ujawnia si podczas wstrzykiwania obiektów do d ugotrwa-ych komponentów, na przyk ad singletonów. Poniewa wstrzykiwanie odbywa si tylko raz,

podczas tworzenia klasy Bean, wi c w kolejnych wywo aniach tej klasy nie jest uwzgl dnianyjej bie cy stan.

W Twoim przypadku aktualny stan klasy Bean jest zapisywany w sesji, a nie bezpo redniow samej klasie. Z tego powodu platforma Spring musi utworzy serwer proxy, który przechwy-tuje wywo ania metod klasy i wykrywa ich mutacje. Dzi ki temu stan klasy mo e by zapisy-wany i odczytywany z sesji HTTP.

W przypadku klasy sesji trzeba stosowa tryb proxy. Serwer CGI dokonuje instrumentalizacjikodu bajtowego i wspó pracuje z ka d klas , natomiast serwer JDK jest nieco mniej inge-rencyjny, ale wymaga zaimplementowania interfejsu.

Ponadto klasa UserProfileSession zosta a zdefiniowana jako implementacja interfejsu Serializable. Nie jest to konieczne, poniewa sesja HTTP mo e przechowywa w pami ci do-

wolne obiekty, ale dobr praktyk jest tworzenie obiektów, które mo na serializowa .

Poleć książkęKup książkę

Page 26: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

116

W rzeczywisto ci mo na zmieni sposób przechowywania danych w sesji. W rozdziale 8.,„Optymalizacja zapyta ”, poznasz sposób zapisywania ich w bazie danych Redis, która wspó -pracuje z obiektami typu Serializable. Najlepiej jest traktowa sesj jako uniwersalny maga-zyn danych. Zadaniem programisty jest opracowanie sposobu zapisywania i odczytywania da-nych z tego magazynu.

Aby serializacja klasy przebiega a poprawnie, ka de jej pole równie musi umo liwia seriali-zacj . W naszym przypadku ci gi znaków oraz daty spe niaj ten warunek, wi c nic nie stoina przeszkodzie.

W asne strony z komunikatami o b dachPlatforma Spring Boot umo liwia definiowanie w asnych widoków z komunikatami o b dach,wy wietlanych zamiast opisanej wcze niej strony z komunikatem Whitelabel Error Page. Widokmusi mie nazw error (b d). Jego przeznaczeniem jest obs uga wszystkich wyj tków. Domy lnaklasa BasicErrorController udost pnia wiele przydatnych atrybutów modelu danych, któremo na wykorzysta na takiej stronie.

Utwórz w katalogu src/main/resources/templates w asn stron error.html do wy wietlania komu-nikatów o b dach:

<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"> <head lang="en"> <meta charset="UTF-8"/> <title th:text="${status}">404</title> <link href="materialize/css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/> </head> <body> <div class="row"> <h1 class="indigo-text center" th:text="${error}">Strona nie istnieje</h1> <p class="col s12 center" th:text="${message}"> dana strona nie istnieje </p> </div> </body></html>

Je eli teraz u ytkownik otworzy adres URL, który nie b dzie obs ugiwany przez aplikacj ,pojawi si w asna strona z komunikatem:

Poleć książkęKup książkę

Page 27: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

117

Bardziej zaawansowanym sposobem obs ugi b dów jest zaimplementowanie klasy ErrorController, czyli kontrolera do obs ugi wyj tków na poziomie globalnym. Przyjrzyj si klasom

ErrorMvcAutoConfiguration i BasicErrorController, b d cym standardowymi implementa-cjami tego kontrolera.

Zmienne tablicowe w adresach URLTeraz wiesz ju , jakimi tematami jest zainteresowany u ytkownik. Warto by oby ulepszykontroler tak, aby wyszukiwa tweety zawieraj ce s owa kluczowe z zadanej listy.

Jednym z ciekawych sposobów przekazywania w adresie URL par danych klucz-warto jestzastosowanie zmiennych tablicowych. Mo na to atwo osi gn za pomoc parametrów zapy-ta . Przyjrzyj si poni szemu kodowi:

jaki Url/parametr?zmienna1=warto 1&zmienna2=warto 2

Zamiast parametru mo na zastosowa tablic zmiennych, jak poni ej:

jaki Url/parametr;zmienna1=warto 1;zmienna2=warto 2

Ka da warto mo e by równie list :

jaki Url/parametr;zmienna1=warto 1,warto 2;zmienna2=warto 3,warto 4

Zmienna tablicowa mo e zosta skojarzona w kontrolerze z obiektami ró nych typów, naprzyk ad:

Map<String, List<?>> — typ obs uguj cy wiele zmiennych z wieloma warto ciami; Map<String, ?> — typ obs uguj cy zmienne z pojedynczymi warto ciami; List<?> — typ stosowany w przypadku, gdy potrzebna jest jedna zmienna, której

nazw mo na konfigurowa .

W Twoim przypadku wymagana jest obs uga adresu jak poni ej:

http://localhost:8080/search/popular;keywords=spring,java

Poleć książkęKup książkę

Page 28: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

118

Pierwszy parametr, popular, oznacza typ wyniku stosowany w interfejsie API do przeszuki-wania serwisu Twitter. Parametr ten mo e przyjmowa warto ci mixed (mieszane), recent (najnow-sze) lub popular (popularne).

Pozosta a cz adresu URL zawiera list s ów kluczowych, któr mo na skojarzy z obiektemtypu List<String>.

Domy lnie platforma Spring MVC usuwa z adresu URL wszystkie znaki za rednikiem. Za-tem pierwsz rzecz , jak trzeba zrobi , aby umo liwi zastosowanie zmiennych tablicowych,jest wy czenie tej funkcjonalno ci.

Wpisz w definicji klasy WebConfiguration poni szy kod:

@Overridepublic void configurePathMatch(PathMatchConfigurer configurer) { UrlPathHelper urlPathHelper = new UrlPathHelper(); urlPathHelper.setRemoveSemicolonContent(false); configurer.setUrlPathHelper(urlPathHelper);}

Utwórz w pakiecie search nowy kontroler o nazwie SearchController. Jego zadaniem b dzieobs uga nast puj cego zapytania:

package masterSpringMvc.search;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.social.twitter.api.Tweet;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.MatrixVariable;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import java.util.List;

@Controllerpublic class SearchController { private SearchService searchService;

@Autowired public SearchController(SearchService searchService) { this.searchService = searchService; }

@RequestMapping("/search/{searchType}") public ModelAndView search(@PathVariable String searchType, @MatrixVariable List<String> keywords) { List<Tweet> tweets = searchService.search(searchType, keywords); ModelAndView modelAndView = new ModelAndView("resultPage"); modelAndView.addObject("tweets", tweets);

Poleć książkęKup książkę

Page 29: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

119

modelAndView.addObject("search", String.join(",", keywords)); return modelAndView; }}

Jak wida , do wy wietlenia tweetów mo na wykorzysta istniej c stron z wynikami wyszu-kiwania. Ponadto wyszukiwanie b dzie realizowane przez inn klas , o nazwie SearchService(us uga wyszukiwania). Us ug t zdefiniuj w tym samym pakiecie, w którym znajduje si kon-troler SearchController:

package masterSpringMvc.search;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.social.twitter.api.Tweet;import org.springframework.social.twitter.api.Twitter;import org.springframework.stereotype.Service;import java.util.List;

@Servicepublic class SearchService { private Twitter twitter; @Autowired public SearchService(Twitter twitter) { this.twitter = twitter; } public List<Tweet> search(String searchType, List<String> keywords) { return null; }}

Teraz musisz zaimplementowa metod search. Argumentem metody twitter.searchOperations().search(parametry) jest obiekt typu searchParameters, umo liwiaj cy zaawansowa-

ne wyszukiwanie tweetów wed ug kilkunastu kryteriów. Ciebie interesuj atrybuty query (za-pytanie), resultType (typ wyniku) i count (liczba).

Najpierw utwórz konstruktor typu ResultType z parametrem searchType. ResultType jest ty-pem wyliczeniowym, zatem mo na przegl da ró ne elementy obiektu i wyszukiwa te, którespe niaj zadane warunki, nie uwzgl dniaj c wielko ci znaków:

private SearchParameters.ResultType getResultType(String searchType) { for (SearchParameters.ResultType knownType :SearchParameters.ResultType.values()) { if (knownType.name().equalsIgnoreCase(searchType)) { return knownType; } } return SearchParameters.ResultType.RECENT;}

Poleć książkęKup książkę

Page 30: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

120

Teraz utwórz nast puj c metod typu SearchParameters:

private SearchParameters createSearchParam(String searchType, String taste) { SearchParameters.ResultType resultType = getResultType(searchType); SearchParameters searchParameters = new SearchParameters(taste); searchParameters.resultType(resultType); searchParameters.count(3); return searchParameters;}

Teraz utworzenie konstruktora typu lista obiektów SearchParameters jest proste i polega jedy-nie na wykonaniu operacji mapowania (pobrania listy s ów kluczowych i zwrócenia dla ka -dego z nich konstruktora typu SearchParameters):

List<SearchParameters> searches = keywords.stream() .map(taste -> createSearchParam(searchType, taste)) .collect(Collectors.toList());

Teraz trzeba odczyta tweety z ka dego konstruktora SearchParameters. Mo na to zrobi w nast -puj cy sposób:

List<Tweet> tweets = searches.stream() .map(params -> twitter.searchOperations().search(params)) .map(searchResults -> searchResults.getTweets()) .collect(Collectors.toList());

Je eli jednak si zastanowisz, odkryjesz, e powy szy kod zwraca list tweetów. Tobie jednakpotrzebna jest prosta, „p aska” lista. Operacj przetwarzania mapy i „sp aszczenia” wyniku reali-zuje metoda flatMap. Mo na wi c utworzy nast puj cy kod:

List<Tweet> tweets = searches.stream() .map(params -> twitter.searchOperations().search(params)) .flatMap(searchResults -> searchResults.getTweets().stream()) .collect(Collectors.toList());

Parametrem metody flatMap jest strumie , co na pocz tku mo e wydawa si niezrozumia e.Przedstawi najpierw pe ny kod klasy SearchService, aby uzyska ca o ciowy obraz:

package masterSpringMvc.search;

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.social.twitter.api.SearchParameters;import org.springframework.social.twitter.api.Tweet;import org.springframework.social.twitter.api.Twitter;import org.springframework.stereotype.Service;import java.util.List;import java.util.stream.Collectors;

@Servicepublic class SearchService {

Poleć książkęKup książkę

Page 31: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

121

private Twitter twitter;

@Autowired public SearchService(Twitter twitter) { this.twitter = twitter; }

public List<Tweet> search(String searchType, List<String> keywords) { List<SearchParameters> searches = keywords.stream() .map(taste -> createSearchParam(searchType, taste)) .collect(Collectors.toList()); List<Tweet> results = searches.stream() .map(params -> twitter.searchOperations() .search(params)) .flatMap(searchResults -> searchResults.getTweets() .stream()) .collect(Collectors.toList()); return results; }

private SearchParameters.ResultType getResultType(String searchType) { for (SearchParameters.ResultType knownType :SearchParameters.ResultType.values()) { if (knownType.name().equalsIgnoreCase(searchType)) { return knownType; } } return SearchParameters.ResultType.RECENT; }

private SearchParameters createSearchParam(String searchType, String taste) { SearchParameters.ResultType resultType = getResultType(searchType); SearchParameters searchParameters = new SearchParameters(taste); searchParameters.resultType(resultType); searchParameters.count(3); return searchParameters; }}

Teraz, po otwarciu adresu http://localhost:8080/search/mixed;keywords=spring,java, pojawisi spodziewany efekt, tj. najpierw wyniki wyszukania s owa Spring, a nast pnie Java (patrzrysunek na nast pnej stronie).

Wszystko razemDo tej pory poszczególne funkcjonalno ci dzia a y osobno, wi c teraz pora je zebra wszyst-kie razem. Wykonaj nast puj ce kroki:

Poleć książkęKup książkę

Page 32: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

122

1. Do strony profilu przenie formularz ze strony do adowania obrazów, a nast pnieusu j .

2. Zmie przycisk Wy lij na stronie profilu tak, aby od razu rozpoczynawyszukiwanie tweetów wed ug preferencji u ytkownika.

3. Zmie stron startow aplikacji tak, aby od razu pojawia y si na niej wynikiwyszukiwania spe niaj ce preferencje u ytkownika. Je eli preferencje nie b dzdefiniowane, powinna pojawi si strona profilu.

Zach cam Ci do samodzielnego przygotowania kodu. By mo e po drodze napotkasz bardzopowa ne problemy, ale posiadasz ju wystarczaj c wiedz , aby je samodzielnie rozwi za .Wierz w Ciebie.

OK. Je eli wykona e zadanie (na pewno tak), rzu okiem na moje rozwi zanie.

Pierwszym krokiem by o usuni cie starej strony uploadPage.html. mia o, zrób to.

Nast pnie tu po elemencie tytu u na stronie profilePage.html wpisa em poni sze wiersze:

<div class="row"> <div class="col m8 s12 offset-m2"> <img th:src="@{/uploadedPicture}" width="100" height="100"/> </div> <div class="col s12 center red-text" th:text="${error}" th:if="${error}"> B d adowania pliku </div> <form th:action="@{/profile}" method="post" enctype="multipart/form-data" class="col m8 s12 offset-m2"> <div class="input-field col s6"> <input type="file" id="file" name="file"/> </div> <div class="col s6 center">

Poleć książkęKup książkę

Page 33: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

123

<button class="btn indigo waves-effect waves-light" type="submit" name="upload" th:text="#{upload}">Za aduj <i class="mdi-content-send right"></i> </button> </div> </form></div>

Powy szy kod jest bardzo podobny do kodu poprzedniej strony uploadPage.html. Usun emtylko tytu i zmieni em etykiet na przycisku do wysy ania formularza. W plikach ustawieregionalnych umie ci em te odpowiednie t umaczenia napisów:

Dla j zyka polskiego:

upload=Za aduj

Dla j zyka angielskiego:

upload=Upload

Zmieni em równie nazw przycisku na upload. Dzi ki temu atwiej b dzie mo na zidentyfi-kowa operacj adowania pliku po stronie kontrolera.

Teraz przy próbie za adowania obrazu u ytkownik zostanie przekierowany na star stron doadowania plików. Musia em poprawi kod metody onUpload w klasie PictureUploadController:

@RequestMapping(value = "/profile", params = {"upload"}, method =RequestMethod.POST)

public String onUpload(@RequestParam MultipartFile file, RedirectAttributes redirectAttrs) throws IOException { if (file.isEmpty() || !isImage(file)) { redirectAttrs.addFlashAttribute("error", "Niew a ciwy plik. Za aduj plik z obrazem."); return "redirect:/profile"; } Resource picturePath = copyFileToPictures(file); userProfileSession.setPicturePath(picturePath); return "redirect:profile";}

Zwró uwag , e adres URL obs uguj cy zapytanie POST zosta zmieniony z /upload na /profile.Obs uga formularza jest o wiele prostsza, je eli zapytania GET i POST dotycz tego samego ad-resu URL. W szczególno ci oszcz dzaj mnóstwa k opotów przy obs udze wyj tków, ponie-wa po wyst pieniu b du nie trzeba u ytkownika przekierowywa na inn stron .

Usun em równie atrybut picturePath modelu danych. Poniewa jest teraz klasa UserProfileSession reprezentuj ca sesj u ytkownika, wi c zosta a tutaj wykorzystana. Atrybut picturePath

doda em do klasy UserProfileSession wraz z odpowiednimi metodami przypisuj cymi i od-czytuj cymi warto ci w a ciwo ci.

Poleć książkęKup książkę

Page 34: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

124

Nie mog em zapomnie o zastosowaniu klasy UserProfileSession i udost pnieniu jej jakopola klasy PictureUploadController.

Pami taj, e wszystkie w a ciwo ci klasy reprezentuj cej sesj musz — w odró nieniu odzasobów — nadawa si do serializacji. Dlatego ich warto ci nale y przechowywa w innysposób. Klasa URL wydaje si dobrze nadawa do tego celu. Mo na j serializowa , a za pomo-c klasy UrlResource mo na utworzy zasób na podstawie adresu URL:

@Component@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)public class UserProfileSession implements Serializable { private URL picturePath; public void setPicturePath(Resource picturePath) throws IOException { this.picturePath = picturePath.getURL(); } public Resource getPicturePath() { return picturePath == null ? null : new UrlResource(picturePath); }}

Ostatni rzecz , jak zrobi em, by o udost pnienie obiektu profileForm jako atrybutu modelu powyst pieniu b du, poniewa wymaga tego strona profilePage.html w momencie wy wietlenia.

Poni ej przedstawiona jest ostateczna wersja klasy PictureUploadController:

package masterSpringMvc.profile;

import masterSpringMvc.config.PictureUploadProperties;import org.apache.tomcat.util.http.fileupload.IOUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.MessageSource;import org.springframework.core.io.FileSystemResource;import org.springframework.core.io.Resource;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletResponse;import java.io.*;import java.net.URLConnection;import java.util.Locale;

@Controllerpublic class PictureUploadController { private final Resource picturesDir;

Poleć książkęKup książkę

Page 35: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

125

private final Resource anonymousPicture; private final MessageSource messageSource; private final UserProfileSession userProfileSession;

@Autowired public PictureUploadController(PictureUploadProperties uploadProperties, MessageSource messageSource, UserProfileSession userProfileSession) { picturesDir = uploadProperties.getUploadPath(); anonymousPicture = uploadProperties.getAnonymousPicture(); this.messageSource = messageSource; this.userProfileSession = userProfileSession; }

@RequestMapping(value = "/uploadedPicture") public void getUploadedPicture(HttpServletResponse response) throws IOException { Resource picturePath = userProfileSession.getPicturePath(); if (picturePath == null) { picturePath = anonymousPicture; } response.setHeader("Content-Type", URLConnection.guessContentTypeFromName(picturePath.getFilename())); IOUtils.copy(picturePath.getInputStream(), response.getOutputStream()); }

@RequestMapping(value = "/profile", params = {"upload"}, method = RequestMethod.POST) public String onUpload(@RequestParam MultipartFile file, RedirectAttributes redirectAttrs) throws IOException { if (file.isEmpty() || !isImage(file)) { redirectAttrs.addFlashAttribute("error", "Niew a ciwy plik. Za aduj plik z obrazem."); return "redirect:/profile"; } Resource picturePath = copyFileToPictures(file); userProfileSession.setPicturePath(picturePath); return "redirect:profile"; }

private Resource copyFileToPictures(MultipartFile file) throws IOException { String fileExtension = getFileExtension(file.getOriginalFilename()); File tempFile = File.createTempFile("pic", fileExtension, picturesDir.getFile()); try (InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(tempFile)) { IOUtils.copy(in, out); } return new FileSystemResource(tempFile); }

Poleć książkęKup książkę

Page 36: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

126

@ExceptionHandler(IOException.class) public ModelAndView handleIOException(Locale locale) { ModelAndView modelAndView = new ModelAndView("profile/profilePage"); modelAndView.addObject("error", messageSource.getMessage("upload. io.exception", null, locale)); modelAndView.addObject("profileForm", userProfileSession.toForm()); return modelAndView; }

@RequestMapping("uploadError") public ModelAndView onUploadError(Locale locale) { ModelAndView modelAndView = new ModelAndView("profile/profilePage"); modelAndView.addObject("error", messageSource.getMessage("upload.file. too.big", null, locale)); modelAndView.addObject("profileForm", userProfileSession.toForm()); return modelAndView; }

private boolean isImage(MultipartFile file) { return file.getContentType().startsWith("image"); }

private static String getFileExtension(String name) { return name.substring(name.lastIndexOf(".")); }}

Teraz wi c u ytkownik mo e otworzy stron profilu i za adowa obraz, jak równie wprowa-dzi informacje osobiste (patrz rysunek na nast pnej stronie).

U ytkownik po wpisaniu danych na stronie profilu powinien zosta przekierowany na stronz wynikami wyszukiwania. W tym celu zmieni em metod saveProfile w klasie ProfileController:

@RequestMapping(value = "/profile", params = {"save"}, method =RequestMethod.POST)

public String saveProfile(@Valid ProfileForm profileForm, BindingResultbindingResult) {

if (bindingResult.hasErrors()) { return "profile/profilePage"; } userProfileSession.saveForm(profileForm); return "redirect:/search/mixed;keywords=" + String.join(",", profileForm.getTastes());}

Poleć książkęKup książkę

Page 37: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

127

Poniewa teraz mo na wyszukiwa tweety na stronie profilu, nie s ju potrzebne pliki searchPa-ge.html i TweetController.java. Mo na je po prostu usun .

Na koniec trzeba zmieni stron startow tak, aby u ytkownik by kierowany na stron wy-szukiwania tweetów spe niaj cych preferencje, o ile zosta y podane na stronie profilu.

W pakiecie controller utworzy em klas nowego kontrolera, który jest odpowiedzialny za przekie-rowanie u ytkownika do g ównej strony aplikacji lub do strony profilu w celu uzupe nieniadanych, lub do strony resultPage.html, je eli wpisane zosta y preferencje:

package masterSpringMvc.controller;

import masterSpringMvc.profile.UserProfileSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;

@Controllerpublic class HomeController { private UserProfileSession userProfileSession;

@Autowired public HomeController(UserProfileSession userProfileSession) { this.userProfileSession = userProfileSession;

Poleć książkęKup książkę

Page 38: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

128

}

@RequestMapping("/") public String home() { List<String> tastes = userProfileSession.getTastes(); if (tastes.isEmpty()) { return "redirect:/profile"; } return "redirect:/search/mixed;keywords=" + String.join(",", tastes); }}

Punkt kontrolnyW tym rozdziale utworzy e dwa kontrolery: kontroler PictureUploadController, odpowie-dzialny za zapisywanie za adowanych plików obrazów na dysk i obs ug b dów, oraz kontro-ler SearchController, wyszukuj cy tweety za pomoc parametrów tablicowych zawieraj cychlist s ów kluczowych.

Kontroler ten przekazuje wyszukiwanie do nowej klasy SearchService.

Usun e niepotrzebny kontroler TweetController.

Utworzy e klas UserProfileSession przechowuj c informacj o u ytkowniku aplikacji.

Na koniec doda e do klasy WebConfiguration dwie metody: jedn , dla kontenera serwletówdo wy wietlania strony z komunikatem o b dzie, i drug , obs uguj c zmienne tablicowe.

Struktura projektu wygl da teraz jak na poni szym rysunku:

Poleć książkęKup książkę

Page 39: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Rozdzia 4. • adowanie plików i obs uga b dów

129

Do zasobów zosta y dodane obraz przedstawiaj cy anonimowego u ytkownika oraz statycznastrona wy wietlaj ca komunikat o b dzie. Strona profilePage.html zosta a rozbudowana o mo li-wo adowania plików, natomiast strona searchPage.html zosta a usuni ta. Struktur zasobówprzedstawia poni szy rysunek:

PodsumowanieW tym rozdziale opisane zosta y metody adowania plików i obs ugi b dów. adowanie plikóww rzeczywisto ci nie jest skomplikowane. Wa na jest jednak decyzja, co nale y zrobi z za a-dowanymi plikami. Mo na je przechowywa w bazie danych jako obrazy, ale w tym przypad-ku zosta y zapisane na dysku, a informacje o ich po o eniu by y przechowywane w sesji u yt-kownika.

Opisane zosta y typowe metody obs ugi wyj tków na poziomie kontrolera i kontenera serwletów.Dodatkowe informacje na temat obs ugi b dów w rodowisku Spring MVC s dost pne podadresem https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc.

Twoja aplikacja wygl da ju ca kiem nie le, a ilo napisanego kodu jest do du a.

Zapoznaj si z nast pnym rozdzia em, w którym dowiesz si , e platforma Spring MVC do-skonale nadaje si równie do tworzenia aplikacji w stylu REST.

Poleć książkęKup książkę

Page 40: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

130

Poleć książkęKup książkę

Page 41: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Skorowidz

Aadnotacja

@Async, 244@Cacheable, 227@CacheConfig, 230@CachePut, 230@CachEvict, 230@Caching, 230@ControllerAdvice, 152@EnableCache, 226@EnableGlobalMethodSecurity, 161@JsonIgnore, 140@JsonIgnoreProperties, 140@ModelAttribute, 107@Primary, 194@RequestMapping, 69, 138@RestController, 138@SessionAttributes, 113@SpringApplicationConfiguration, 194@SpringBootApplication, 33@WebIntegrationTest, 206javax.validation@Valid, 81

adnotacje do weryfikacji danych, 85adres URL, 73

uprawniony, 163zmienne tablicowe, 117

aktywacja us ugi Redis, 252, 258anemiczny model domeny, 48API, 135aplikacja Gradle, 23aplikacje

jednostronicowe, 240, 264Spring, 19w stylu REST, 131

architekturaMVC, 47platformy Spring MVC, 54REST, 131

atrapy, 191atrybut

dateFormat, 80request, 69

atrybuty redirectAttributes, 69

BBDD, Behaviour Driven Development, 187bezstanowo , 266biblioteka

AngularJS, 265AssertJ, 206Backbone.js, 240FluentLenium, 206, 209Geb, 215, 217hamcrest, 188Jolokia, 46mockito, 188NIO, 101Spock, 212, 214spring-test, 188WebJar, 241WebJars, 63, 72

b d 400, 77b dy, 40

formularza, 81adowania plików, 108

Poleć książkęKup książkę

Page 42: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

268

Ccertyfikat z w asnym podpisem, 179chmura, 245ciasteczko, 113ci g a integracja, 183Cloud Foundry, 246CRUD, Create Read Update Delete, 133CSRF, Cross Site Request Forgery, 164

Ddebugowanie, 32deklaracja lokalizacji, 39diagnostyka interfejsu REST API, 139diagnozowanie b dów, 111dokumentowanie interfejsu, 153dost p do serwisu Twitter, 60dostosowanie

komunikatów o b dach, 82odpowiedzi JSON, 139

DSL, Domain Specific Language, 214DTO, Data Transfer Object, 75dyspozytor, 35

Fformat

JSON, 139MIME, 103

formularz, 73logowania, 165

funkcja displayTweets, 243funkcje lambda, 62

GGDK, Groovy Development Kit, 212generowanie certyfikatu, 179

HHATEOAS, 134Heroku, 247, 253HTTP, 132

IIaaS, Infrastructure as a Service, 245imitowanie klas, 191instalacja

narz dzi konsolowych, 247narz dzia Gradle, 29systemu Git, 28

IntelliJ IDEA, 19, 25interceptory, 88interfejs

API, 135, 144CacheManager, 244java.util.Date, 76MultipartFile, 101REST API, 139SessionStrategy, 175UsersConnectionRepository, 175

internacjonalizacja, 85interpreter widoków, 38

JJava 8, 62JavaScript, 237J zyk

DSL, 214Groovy, 212SpEL, 56

Kkana

HTTP, 180HTTPS, 179

klasaApiSecurityConfiguration, 166, 225AuthenticatingSignInAdapter, 171Bean, 154CacheConfiguration, 226, 244CompletableFuture, 237ContentNegotiatingViewResolver, 154DefaultMessageCodesResolver, 84DefaultResourceLoader, 106ErrorController, 117FixedLocaleResolver, 86HomeController, 188

Poleć książkęKup książkę

Page 43: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Skorowidz

269

LocalDate, 76LocalDateTimeSerializer, 143LocaleChangeInterceptor, 88MasterSpringMvcApplication, 24, 71MasterSpringMvcApplicationTests, 24MBean, 38MessageSource, 112MockHttpSession, 190MultipartProperties, 101PictureUploadController, 106, 124ProfileController, 93, 100, 126ProviderSignInController, 174RedirectAttributes, 69RedisConfig, 177SearchApiController, 137, 156, 195SearchCache, 244SearchControllerMockTest, 193SearchParamsBuilder, 227SearchService, 141, 193SessionLocaleResolver, 87SignupController, 175SimpMessagingTemplate, 242SocialWebAutoConfiguration, 174StubConfiguration, 194Tweet, 140TwitterSearch, 230, 234UrlResource, 124UserApiController, 156, 200UserProfileSession, 113, 115, 128UserRepository, 144, 198WebConfiguration, 79, 110, 128, 143WebMvcConfigurerAdapter, 79WebSecurityConfiguration, 166, 168

klasy konfiguracyjne, 181, 244klient, 137

REST, 139kodowanie znaków, 40kody

b dów, 148HTTP, 136stanu, 147

kompilowanie kodu, 28, 184kompresja gzip, 224komunikat o b dzie, 78, 82, 112

400, 77konfiguracja

aplikacji, 254elementów aplikacji, 35interpretera widoków, 39

adowania plików, 104obs ugi b dów, 40protoko u SSL, 44systemu Gradle, 202uwierzytelnienia spo eczno ciowego, 170wbudowanego serwletu, 42

kontrola pami ci podr cznej, 224kontroler, 48

PictureUploadController, 128ProviderSignInController, 174SearchApiController, 193SearchController, 128, 193TweetController, 128

kontrolki hipermediów, 134

Llista w formularzu, 91logowanie, 165lokalizacja, 39

adowanieobrazu, 102plików, 99, 104, 108

Mmagazyn kluczy, keystore, 179metadane, 76metoda

asyncFetch, 235await, 235CountDownLatch, 235DELETE, 133, 199GET, 133getInputStream, 101HEAD, 133HttpServletResponse.sendError, 149onUpload, 107OPTIONS, 133PATCH, 133POST, 133PUT, 133search, 138toString, 76TwitterTemplate, 229

Poleć książkęKup książkę

Page 44: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

270

metodyasynchroniczne, 233HTTP, 133

MIME, 103model, 48

dojrza o ci Richardsona, 132MVC, model-view-controller, 47

Nnarz dzia konsolowe Cloud Foundry, 247narz dzie

AssertJ, 187BackboneJS, 265DbUnit, 187Ember, 265geb, 20Gradle, 19, 28–30, 254httpie, 139JUnit, 187Maven, 19Mockito, 187, 191React, 265Spock, 187

Oobiekt

DTO, 75Map, 144ObjectMapper, 143POJO, 76ResponseEntity, 148

obiektyMBean, 33obiekty stron, 209, 217

obs ugaadresów URL, 73b dów, 40, 103, 149b dów adowania plików, 108formularzy, 73sesji rozproszonych, 176wyj tków, 147, 152

odczytywanie danych, 56odga zienie, branch, 254opcje konfiguracyjne, 45OpenShift, 246operacja

forward, 69operacja redirect, 69

operacjeCRUD, 146POST, 94

optymalizacja zapyta , 223

PPaaS, Platform as a Service, 245pakiet

authentication, 168, 182config, 177ConfigurationProperties, 105GDK, 212hibernate-validator, 81java.util.concurrent.Executor, 233JDK, 179, 250org.springframework.web, 78utils, 199

pami podr czna, 224aplikacji, 226rozproszona, 232uniewa nianie danych, 231

parametrproxyMode, 115search, 67

platformaDocker, 263MVC 1-0-1, 50Spring, 261Spring Boot, 19, 263Swagger, 153

plikapplication.properties, 24, 71, 78, 84, 104, 181application-cloud.properties, 252build.gradle, 30, 60, 142, 203default.html, 164JAR, 249JSESSIONID, 113messages_pl.properties, 86Procfile, 255profilePage.html, 76resultPage.html, 142, 239searchPage.html, 127TweetController.java, 127

plikiJAR, 23WAR, 23

POJO, Plain Old Java Object, 76

Poleć książkęKup książkę

Page 45: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Skorowidz

271

poleceniebrew, 253git add, 29heroku login, 253

port HTTP, 44produkcyjny profil aplikacji, 223profil

aplikacji, 223async, 237Heroku, 255prod, 252redis, 252u ytkownika, 198

programkeytool, 179PhantomJS, 206

programowanie zorientowane na testy, 185projekt

React, 265Spring Batch, 263Spring Integration, 263Spring Reactor, 263Spring Social, 60

projektowanie domenowe, 49protokó

SSL, 44, 178, 181WebSocket, 241, 242

przekazywanie danych do widoku, 55przekierowanie, 69prze adowywanie widoków, 53PWS, Pivotal Web Services, 247

Rrdze platformy Spring, 262Redis, 252, 258rejestracja aplikacji, 58rejestrowanie informacji, 78repozytorium Git, 254REST, Representational State Transfer, 131rozproszenie pami ci, 232

Sserializacja, 140, 155serwer

Redis, 244Tomcat, 29, 42

serwisGetting Started Content, 22start.Spring.io, 26Twitter, 60

serwlet DispatcherServlet, 54sesje

przyklejane, 132rozproszone, 176

skrypt materialize, 239SpEL, Spring Expression Language, 56sprawdzanie uprawnie u ytkownika, 165Spring

core, rdze , 262data, dane, 262execution, uruchamianie, 262

Spring Boot, 19, 34Spring Boot Plugin, 31Spring Initializr, 25Spring Social, 60Spring Tool Suite, 20SSL, Secure Sockets Layer, 178strona

login.html, 167, 168profilePage.html, 124, 129resultPage.html, 243

strumienie, 62STS, Spring Tool Suite, 20styl material design, 63Swagger, 153system

Git, 20, 27Gradle, 202Thymeleaf, 53

szablon Thymeleaf, 51, 164, 241

cie kaclasspath, 197twitterSearch, 242

rodowiskoIDE, 20IntelliJ, 25

Ttagi ETag, 237, 238test, 183, 184

FluentLenium, 204

Poleć książkęKup książkę

Page 46: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe

Spring MVC 4. Projektowanie zaawansowanych aplikacji WWW

272

testowaniemetody DELETE, 199uwierzytelnienia, 201

testyintegracyjne, 187, 215jednostkowe, 186, 212jednostkowe kontrolerów REST, 195

t umaczenie tekstów aplikacji, 89tweety, 235, 239Twitter, 60, 170tworzenie

aplikacji Spring, 19atrap, 193odpowiedzi XML, 154profilu, 198strony, 52testów integracyjnych, 202testów jednostkowych, 188testów w j zyku Groovy, 212

typListenableFuture, 234ProfileForm, 77

Uudost pnianie aplikacji, 245, 253uk ady stron, 66ulepszanie aplikacji, 259uprawnione adresy URL, 163URI, unified resource identifier, 132uruchomienie aplikacji, 256us uga

Cloud Foundry, 246Heroku, 247, 253OpenShift, 246PWS, 247, 248Redis, 252, 258REST, 131

ustawienia regionalne, 38, 87uwierzytelnienie, 201

podstawowe, 159przez Twitter, 170

u ycie parametru, 56u ytkownik

anonimowy, 169upowa niony, 160

Wwdro enie aplikacji, 248, 263weryfikacja danych, 75, 80, 85

po stronie klienta, 94weryfikatory, matcher, 189widok, 48wiersz polece , 26w asny podpis, 179wst pne przetwarzanie wyra enia, 92wstrzykiwanie pól, 115wtyczka Groovy-Eclipse, 20wyj tek

ArrayOutOfBoundException, 61EntityNotFoundException, 149–152IOException, 109MultipartException, 102, 109, 110

wykonywalny plik JAR, 32wyniki wyszukiwania, 208wyszukiwanie tweetów, 71wy wietlanie

komunikatów, 116tweetów, 67za adowanego obrazu, 107

Zzabezpieczanie aplikacji, 159zapisywanie

danych w sesji, 114hase , 180profilu u ytkownika, 112

zapytanieGET, 123POST, 123

zarz dzaniecertyfikatami, 179zasobami u ytkowników, 144

zasoby, 132statyczne, 38

zg aszanie wyj tków, 109zmiana ustawie regionalnych, 87zmienne

rodowiskowe, 180tablicowe, 117

znaczniki bezpiecze stwa, 164zwrot kodów stanu, 148, 149

Poleć książkęKup książkę

Page 48: Tytuł oryginału: Mastering Spring MVC 4 · 2019-05-15 · Spring Boot od wewnÈtrz 34 Dyspozytor i konfiguracja elementów aplikacji 35 Interpreter widoków, ... Testy jednostkowe