Revize f3d8e7de
Přidáno uživatelem Ondřej Váně před asi 5 roky(ů)
README.md | ||
---|---|---|
1 | 1 |
# Indexace a fulltextové vyhledávání v historických obrazových dokumentech - ANONYMOUS |
2 | 2 |
|
3 | 3 |
## Frontend - Angular |
4 |
### Suštění lokálně |
|
4 |
### Spuštění lokálně
|
|
5 | 5 |
- naistalovat a nastavit lokální prostředí [návod zde](https://angular.io/guide/setup-local). |
6 | 6 |
- přesunout se do složky ./fe/fulltextsearch |
7 | 7 |
- spustit příkaz `ng serve -o` |
... | ... | |
10 | 10 |
|
11 | 11 |
### Spuštění v dockeru |
12 | 12 |
- nainstalovat docker [návod zde](https://docs.docker.com/docker-for-windows/install/) |
13 |
- nastartovat docker `docker-machine start` |
|
13 | 14 |
- přesunout se do složky ./fe/fulltextsearch |
14 | 15 |
- spustit příkaz pro vytvoření docker image `docker build -t dockerangular .` |
15 | 16 |
- spustit příkaz pro nastartování kontejneru `docker run -p4200:80 dockerangular` |
be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/IndexController.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.aswi.fulltextsearch; |
2 | 2 |
|
3 |
import cz.zcu.kiv.aswi.fulltextsearch.model.Query; |
|
4 |
import cz.zcu.kiv.aswi.fulltextsearch.model.QueryResponse; |
|
5 |
import org.springframework.web.bind.annotation.CrossOrigin; |
|
3 | 6 |
import org.springframework.web.bind.annotation.PostMapping; |
7 |
import org.springframework.web.bind.annotation.RequestBody; |
|
4 | 8 |
import org.springframework.web.bind.annotation.RestController; |
5 | 9 |
|
10 |
@CrossOrigin(origins = "*", allowedHeaders = "*") |
|
6 | 11 |
@RestController |
7 | 12 |
public class IndexController { |
8 | 13 |
|
9 | 14 |
@PostMapping("/") |
10 |
public String index() { |
|
11 |
return "index"; |
|
15 |
public QueryResponse index(@RequestBody Query query) { |
|
16 |
return new QueryResponse("Hello, here is spring\n" + |
|
17 |
"Query was: " + query.getQuery() + "\n" + |
|
18 |
"Query sent: " + query.getDate().toString()); |
|
12 | 19 |
} |
13 | 20 |
|
14 | 21 |
} |
be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/model/Query.java | ||
---|---|---|
1 |
package cz.zcu.kiv.aswi.fulltextsearch.model; |
|
2 |
|
|
3 |
import com.fasterxml.jackson.annotation.JsonClassDescription; |
|
4 |
|
|
5 |
import java.util.Date; |
|
6 |
|
|
7 |
@JsonClassDescription("query") |
|
8 |
public class Query { |
|
9 |
|
|
10 |
private String query; |
|
11 |
private Date date; |
|
12 |
|
|
13 |
public Query(String query, Date date) { |
|
14 |
this.query = query; |
|
15 |
this.date = date; |
|
16 |
} |
|
17 |
|
|
18 |
public String getQuery() { |
|
19 |
return query; |
|
20 |
} |
|
21 |
|
|
22 |
public void setQuery(String query) { |
|
23 |
this.query = query; |
|
24 |
} |
|
25 |
|
|
26 |
public Date getDate() { |
|
27 |
return date; |
|
28 |
} |
|
29 |
|
|
30 |
public void setDate(Date date) { |
|
31 |
this.date = date; |
|
32 |
} |
|
33 |
} |
be/fulltextsearch/src/main/java/cz/zcu/kiv/aswi/fulltextsearch/model/QueryResponse.java | ||
---|---|---|
1 |
package cz.zcu.kiv.aswi.fulltextsearch.model; |
|
2 |
|
|
3 |
public class QueryResponse { |
|
4 |
|
|
5 |
private String response; |
|
6 |
|
|
7 |
public QueryResponse(String response) { |
|
8 |
this.response = response; |
|
9 |
} |
|
10 |
|
|
11 |
public String getResponse() { |
|
12 |
return response; |
|
13 |
} |
|
14 |
|
|
15 |
public void setResponse(String response) { |
|
16 |
this.response = response; |
|
17 |
} |
|
18 |
} |
be/fulltextsearch/src/test/java/cz/zcu/kiv/aswi/fulltextsearch/IndexControllerTest.java | ||
---|---|---|
1 | 1 |
package cz.zcu.kiv.aswi.fulltextsearch; |
2 | 2 |
|
3 |
import cz.zcu.kiv.aswi.fulltextsearch.model.Query; |
|
4 |
import org.apache.coyote.Request; |
|
3 | 5 |
import org.junit.jupiter.api.Test; |
4 | 6 |
import org.springframework.beans.factory.annotation.Autowired; |
5 | 7 |
import org.springframework.boot.test.context.SpringBootTest; |
... | ... | |
13 | 15 |
|
14 | 16 |
import java.net.URI; |
15 | 17 |
import java.net.URISyntaxException; |
18 |
import java.util.Date; |
|
16 | 19 |
|
17 | 20 |
import static org.junit.jupiter.api.Assertions.assertEquals; |
18 | 21 |
|
... | ... | |
35 | 38 |
HttpHeaders headers = new HttpHeaders(); |
36 | 39 |
headers.setContentType(MediaType.APPLICATION_JSON); |
37 | 40 |
|
38 |
String string = ""; |
|
39 |
HttpEntity<String> request = new HttpEntity<>(string, headers); |
|
41 |
Date date = new Date(); |
|
42 |
Query testQuery = new Query("Test query", date); |
|
43 |
HttpEntity<Query> request = new HttpEntity<>(testQuery, headers); |
|
44 |
|
|
40 | 45 |
|
41 | 46 |
ResponseEntity<String> result = restTemplate.postForEntity(uri, request, String.class); |
42 | 47 |
|
43 | 48 |
assertEquals(200, result.getStatusCodeValue()); |
44 |
assertEquals("index", result.getBody());
|
|
49 |
assertEquals("{\"response\":\"Hello, here is spring\\nQuery was: Test query\\nQuery sent: "+date.toString()+"\"}", result.getBody());
|
|
45 | 50 |
} |
46 | 51 |
|
47 | 52 |
|
48 |
} |
|
53 |
} |
fe/fulltextsearch/e2e/src/app.e2e-spec.ts | ||
---|---|---|
10 | 10 |
|
11 | 11 |
it('should display welcome message', () => { |
12 | 12 |
page.navigateTo(); |
13 |
expect(page.getTitleText()).toEqual('Hello in fulltext search frontend');
|
|
13 |
expect(page.getTitleText()).toEqual('Hello in Fulltext search frontend');
|
|
14 | 14 |
}); |
15 | 15 |
|
16 | 16 |
afterEach(async () => { |
fe/fulltextsearch/src/app/app.component.css | ||
---|---|---|
1 |
.test { |
|
2 |
width: 80%; |
|
3 |
height: 80%; |
|
4 |
margin: 10%; |
|
5 |
border: 3px solid grey; |
|
6 |
padding: 10px; |
|
7 |
} |
fe/fulltextsearch/src/app/app.component.html | ||
---|---|---|
1 |
<h1 style="text-align: center">Hello in fulltext search frontend</h1> |
|
2 |
<h2>Test bootstrap</h2> |
|
3 |
<div class="alert alert-primary" role="alert"> |
|
4 |
This is a primary alert—check it out! |
|
1 |
<div class="test"> |
|
2 |
<h1 style="text-align: center">Hello in {{title}} frontend</h1> |
|
3 |
<form #queryForm="ngForm" (ngSubmit)="sendQuery(queryForm.value)"> |
|
4 |
<span><b>Object query:</b> </span>{{ queryForm.value | json }} |
|
5 |
<div class="input-group mb-3"> |
|
6 |
<input type="text" class="form-control" placeholder="Query" aria-describedby="basic-addon2" ngModel name="query"> |
|
7 |
<div class="input-group-append"> |
|
8 |
<button class="btn btn-outline-secondary" type="submit">Search</button> |
|
9 |
</div> |
|
10 |
</div> |
|
11 |
|
|
12 |
<div class="form-group"> |
|
13 |
<label for="exampleFormControlTextarea1">Response:</label> |
|
14 |
<textarea readonly class="form-control" id="exampleFormControlTextarea1" rows="10">{{response.response}}</textarea> |
|
15 |
</div> |
|
16 |
</form> |
|
5 | 17 |
</div> |
6 | 18 |
|
7 | 19 |
<!-- Routing --> |
fe/fulltextsearch/src/app/app.component.ts | ||
---|---|---|
1 | 1 |
import { Component } from '@angular/core'; |
2 |
import { Query } from './model/Query'; |
|
3 |
import { QueryService} from './services/query.service'; |
|
4 |
import { QueryResponse } from './model/QueryResponse'; |
|
2 | 5 |
|
3 | 6 |
@Component({ |
4 | 7 |
selector: 'app-root', |
... | ... | |
7 | 10 |
}) |
8 | 11 |
export class AppComponent { |
9 | 12 |
title = 'Fulltext search'; |
13 |
response: QueryResponse = new QueryResponse(); |
|
14 |
|
|
15 |
constructor(private queryService: QueryService) { } |
|
16 |
|
|
17 |
sendQuery(temp: Query) { |
|
18 |
console.log(temp); |
|
19 |
temp.date = new Date(); |
|
20 |
this.queryService.sendQuery(temp).subscribe( response => { |
|
21 |
this.response = response; |
|
22 |
}); |
|
23 |
} |
|
10 | 24 |
} |
fe/fulltextsearch/src/app/app.module.ts | ||
---|---|---|
1 | 1 |
import { BrowserModule } from '@angular/platform-browser'; |
2 | 2 |
import { NgModule } from '@angular/core'; |
3 |
import { HttpClientModule } from '@angular/common/http'; |
|
3 | 4 |
|
4 | 5 |
import { AppRoutingModule } from './app-routing.module'; |
5 | 6 |
import { AppComponent } from './app.component'; |
7 |
import { FormsModule } from '@angular/forms'; |
|
6 | 8 |
|
7 | 9 |
@NgModule({ |
8 | 10 |
declarations: [ |
... | ... | |
10 | 12 |
], |
11 | 13 |
imports: [ |
12 | 14 |
BrowserModule, |
13 |
AppRoutingModule |
|
15 |
AppRoutingModule, |
|
16 |
FormsModule, |
|
17 |
HttpClientModule |
|
14 | 18 |
], |
15 | 19 |
providers: [], |
16 | 20 |
bootstrap: [AppComponent] |
fe/fulltextsearch/src/app/model/Query.ts | ||
---|---|---|
1 |
export class Query { |
|
2 |
query: string; |
|
3 |
date: Date; |
|
4 |
|
|
5 |
constructor(query: string, date: Date) { |
|
6 |
this.query = query; |
|
7 |
this.date = date; |
|
8 |
} |
|
9 |
} |
fe/fulltextsearch/src/app/model/QueryResponse.ts | ||
---|---|---|
1 |
export class QueryResponse { |
|
2 |
response: string; |
|
3 |
} |
fe/fulltextsearch/src/app/services/query.service.spec.ts | ||
---|---|---|
1 |
import { TestBed } from '@angular/core/testing'; |
|
2 |
|
|
3 |
import { QueryService } from './query.service'; |
|
4 |
import {HttpClientModule} from '@angular/common/http'; |
|
5 |
|
|
6 |
describe('QueryService', () => { |
|
7 |
beforeEach(() => TestBed.configureTestingModule({ |
|
8 |
imports: [HttpClientModule] |
|
9 |
})); |
|
10 |
|
|
11 |
it('should be created', () => { |
|
12 |
const service: QueryService = TestBed.get(QueryService); |
|
13 |
expect(service).toBeTruthy(); |
|
14 |
}); |
|
15 |
}); |
fe/fulltextsearch/src/app/services/query.service.ts | ||
---|---|---|
1 |
import { Injectable } from '@angular/core'; |
|
2 |
import { HttpClient } from '@angular/common/http'; |
|
3 |
import {Observable} from 'rxjs'; |
|
4 |
import { QueryResponse } from '../model/QueryResponse'; |
|
5 |
import {Query} from '../model/Query'; |
|
6 |
|
|
7 |
@Injectable({ |
|
8 |
providedIn: 'root' |
|
9 |
}) |
|
10 |
export class QueryService { |
|
11 |
|
|
12 |
backendUrl = 'http://localhost:8080/'; |
|
13 |
|
|
14 |
|
|
15 |
constructor( private httpClient: HttpClient) {} |
|
16 |
|
|
17 |
sendQuery(query: Query): Observable<QueryResponse> { |
|
18 |
return this.httpClient.post<QueryResponse>(this.backendUrl, query); |
|
19 |
} |
|
20 |
} |
Také k dispozici: Unified diff
Re #7656: Integrace frontendu a backendu
- propojení fe a be jedním post voláním
- vytvoření service na fe, která volá be
- na be je odeslán objekt dotazu v jsonu
- opraveny testy na be