Upewnij się że wszystkie moduły są poprawnie zainstalowane. W tym celu w katalogu głównym wykonaj komendę
mvn clean install -fae
|
Note
|
Flaga -fae oznacza że proces budowania zakończy się mimo że niektóre testy nie będą działac poprawnie (kompilować się). Poprawienie testów będzie celem ćwiczeń.
|
Celem ćwiczenie jest utworzenie serwisu zwracający informację czy dana fraza zawiera przekleństwa (w języku angielskim). W tym celu stworzymy serwis REST, korzystający z istniejącej już biblioteki która dokonuje weryfikacji przesłanej frazy.
Aby sprawdzić poprawność frazy należy wywołać usługę pod adresem http://localhost:8081/profranity/{fraza}. Serwis zwróci dokument o następującej strukturze (przykład):
{
"containsProfranity": false,
"input": "home",
"output": null
}|
Tip
|
Aby stworzyć serwis możesz wykorzystać istniejącą klasę ProfanityCheckClient która obsługuje komunikację z zewnętrznym serwisem obsługującym weryfikacje.
|
Tym razem budujemy serwis którego zadaniem będzie tłumaczeniem pojedynczych słów z angielskiego na polski.
Słówka tłumaczymy wykorzystując jedną z implementacji klasy DictionaryClient (DictDictionaryClient lub BablaDictionaryClient). Która klasa będzie wykorzystana definiujemy poprzez nagłówek HTTP "X-Dictionary", podając albo dict albo babla
Tłumaczenie odbywa się poprzez wywołanie URLa http://localhost:8081/translate/{fraza}, który zwraca listę tłumaczeń w następującej formie:
[
{
"englishWord": "home",
"polishWord": "dom"
},
//...
]Metoda /translate/{fraza} powinna umożliwiać także hurtowe tłumaczenie słów. Zaimplementuj dodatkową metodą przyjmującą poprzez HTTP POST listę słów (jako JSON) oraz zwracająca listę pierwszych tłumaczeń dla każdego ze słów.
Weryfikacja implementacji znajduje się w teście TranslationResourceBatchTest
|
Tip
|
pierwsze tłumaczenia można uzyskać wykorzystując metodę DictionaryClient#firstTranslationFor(phrase)
|
We wszystkich dotychczasowych ćwiczeniach w klasach testowych operowaliśmy na niskopoziomowych klasach obsługujących JSONa. Wykorzystując test TranslationResourceMappingTest stwórz mechanizmy konwertujące JSONa na klasy DictionaryWord
|
Note
|
Konwersja nie jest możliwa automatycznie, ponieważ klasa DictionaryWord nie posiada domyślnego konstruktora. Należy stworzyć dedykowany mechanizm dla tej konkretnej klasy albo poprzez implementację interfejsu MessageBodyReader<T> albo projektując odpowiednią klasę typu MixIn dostarczoną przez framework Jackson
|
Wracamy do serwisu Profanity. Nasz serwis, dotychczas, zawsze zwracał pełną reprezentację obiektu:
{
"containsProfranity": false,
"input": "This is shit",
"output": "This is ****"
}Jednak dla słów (bądź wyrażeń) które nie zawierają przekleństw taki dokument JSON jest nadmiarowy i element output jest nadmiarowy:
{
"containsProfranity": false,
"input": "This is ok",
"output": null
}Za pomocą odpowiedniej deklaracji klasy JsonSerializer<IsSwearWord> bądź klasy typu MixIn, bądź MessageBodyWriter<IsSwearWord> dodaj do aplikacji element konwertujący JSONa w odpowiedni sposób.
|
Tip
|
Najprostszym rozwiązaniem jest dodanie klasy MixIn (znanej z poprzednich ćwiczeń) i oznaczenie jej adnotacją @JsonInclude(JsonInclude.Include.NON_EMPTY). W pozostałych przypadkach konwersję należy przeprowadzić ręcznie
|
Dotychczas skupialiśmy się na pisaniu serwisów dostarczających usługi, podczas gdy klasy "kliencie" używane były tylko w testach. Teraz napiszemy klienta do zewnętrznej usługi Google Translate, dostępnej pod adresem: https://translation.googleapis.com/language/translate/v2.
|
Tip
|
Stworzenie nowego klienta odbywa się poprzez Client client = ClientBuilder.newClient();
|
Usługa Google wymaga wywołania zadanego adresu URL metodą POST, wraz z kluczem usługi przesłanym jako argument key (query parameter). Fraza do tłumaczenia przesyłana jest jako request body i może mieć następującą postać
{
'q': 'The quick brown fox jumped over the lazy dog.',
'source': 'en',
'target': 'es',
'format': 'text'
}{
'q': [
'The quick brown fox jumped over the lazy dog.',
'Another sentence to translate'
],
'source': 'en',
'target': 'es',
'format': 'text'
}|
Tip
|
Payload można utworzyć ręcznie (jako String) lub użyć do tego klasy JsonObject (JsonObject object = Json.createObjectBuilder()) - a następnie wysłać metodą post(Entity.json(str)).
|
Pod adresem http://api-rest-apikeys.herokuapp.com/services/ApiKeys?wsdl znajduje się serwis udostępniający w czasie rzeczywistym klucze potrzebne do skorzystania z serwisy tłumaczącego Google.
Do korzystania z serwisu konieczne jest wygenerowanie klas na podstawie pliku WSDL, np. używając odpowiedniego pluginu Maven.
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.1.9</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<sourceRoot>${project.build.directory}/generated-sources/</sourceRoot>
<wsdlOptions>
<wsdlOption>
<wsdl>http://api-rest-apikeys.herokuapp.com/services/ApiKeys?wsdl</wsdl>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>Czas zebrać wszystkie usługi w całośc:
Jako dane wejściowe podłuży nam następujące zdanie: "This code is a piece of shitty crap". Natomiast na wyjściu spodziwamy się następującej struktury
{
"profanityCheck": {
"containsProfranity": true,
"input": "{zdanie}",
"output": "{zdanie_poprawione}"
},
"transations": "{tłumaczenie całej frazy z Google Translate}",
"profanityTranslation": {
"englishWord": "{slowo oznaczone jako profanity}",
"polishWord": "{tlumaczenie}"
}
}|
Tip
|
Słowo które jest przekleństwe możemy odnaleźć poprzez np.s1.substring(s2.indexOf(""), s2.lastIndexOf("")+1)
|
-
W pierwszy kroku musimy zweryfikować czy zdanie zawiera przekleń - wywołując serwis
http://api-rest-profanity.herokuapp.com/profanity/{fraza} -
Następnie tłumaczymy przekleństwo na polski (wykorzystując słownik dict.pl) (poprzez
https://api-rest-translation.herokuapp.com/translate/{fraza}/first) -
Pobierając aktualny klucz dostępu do serwisu Google, możemy dokonać tłumaczenie pełnego zdania
Rozwiązanie może polegać na wyświetleniu wyniku działania w konsoli (nie ma konieczności budowania kolejnej usługi).
Implementacja może się obyć w projekcie final-exercise