Skip to content

Commit 661c9c8

Browse files
committed
Merge branch 'main' into GP-67_new_hello-spring-framework_(for_web)_exercise_MAIN
# Conflicts: # java-web-course-util/pom.xml
2 parents ecb63ee + da63885 commit 661c9c8

File tree

18 files changed

+402
-17
lines changed

18 files changed

+402
-17
lines changed

2-0-servlet-api/2-0-1-hello-servlet-api/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111

12-
<artifactId>2-0-1-date-servlet-api</artifactId>
12+
<artifactId>2-0-1-hello-servlet-api</artifactId>
1313
<packaging>war</packaging>
1414

1515
<properties>

2-0-servlet-api/2-0-1-hello-servlet-api/src/test/java/com/bobocode/DateServletTest.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import org.mockito.junit.jupiter.MockitoExtension;
77
import org.reflections.Reflections;
88

9-
import javax.servlet.ServletOutputStream;
109
import javax.servlet.annotation.WebServlet;
1110
import javax.servlet.http.HttpServlet;
1211
import javax.servlet.http.HttpServletRequest;
@@ -17,11 +16,11 @@
1716
import java.lang.reflect.InvocationTargetException;
1817
import java.lang.reflect.Method;
1918
import java.time.LocalDate;
19+
import java.util.Arrays;
2020
import java.util.Optional;
2121
import java.util.Set;
2222

2323
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
24-
import static org.mockito.Mockito.verify;
2524
import static org.mockito.Mockito.when;
2625

2726

@@ -35,9 +34,6 @@ public class DateServletTest {
3534
@Mock
3635
private HttpServletResponse response;
3736

38-
@Mock
39-
private ServletOutputStream outputStream;
40-
4137
private Object dateServletObject;
4238
private Class<?> dateServletClass;
4339

@@ -55,12 +51,14 @@ public void init() throws ClassNotFoundException, IllegalAccessException, Invoca
5551

5652
@Test
5753
@Order(1)
54+
@DisplayName("DateServlet class exists")
5855
void dateServletClassExists() throws ClassNotFoundException {
5956
Class.forName(SERVLET_PACKAGE + "." + DATE_SERVLET);
6057
}
6158

6259
@Test
6360
@Order(2)
61+
@DisplayName("DateServlet class extends HttpServlet")
6462
void dateServletExtendsHttpServlet() {
6563

6664
Set<Class<? extends HttpServlet>> httpServlets =
@@ -75,6 +73,7 @@ void dateServletExtendsHttpServlet() {
7573

7674
@Test
7775
@Order(3)
76+
@DisplayName("DateServlet class is marked as @WebServlet")
7877
void dateServletIsMarkedAsWebServlet() {
7978
Set<Class<?>> servlets =
8079
reflections.getTypesAnnotatedWith(WebServlet.class);
@@ -87,6 +86,7 @@ void dateServletIsMarkedAsWebServlet() {
8786

8887
@Test
8988
@Order(4)
89+
@DisplayName("DateServlet is mapped with \"/date\" path")
9090
void dateServletIsMarkedWithProperPath() throws ClassNotFoundException {
9191
String[] value = Class.forName(SERVLET_PACKAGE + "." + DATE_SERVLET)
9292
.getAnnotation(WebServlet.class).value();
@@ -95,7 +95,8 @@ void dateServletIsMarkedWithProperPath() throws ClassNotFoundException {
9595

9696
@Test
9797
@Order(5)
98-
void dateServletReturnsDateInResponse() throws IOException, NoSuchMethodException, InvocationTargetException,
98+
@DisplayName("DateServlet returns current date in a response")
99+
void dateServletReturnsDateInResponse() throws IOException, InvocationTargetException,
99100
IllegalAccessException {
100101
Method doGetMethod = getDoGetMethod();
101102

@@ -107,8 +108,12 @@ void dateServletReturnsDateInResponse() throws IOException, NoSuchMethodExceptio
107108
assertThat(stringWriter.getBuffer().toString()).contains(LocalDate.now().toString());
108109
}
109110

110-
private Method getDoGetMethod() throws NoSuchMethodException {
111-
return dateServletClass
112-
.getMethod("doGet", HttpServletRequest.class, HttpServletResponse.class);
111+
private Method getDoGetMethod() {
112+
var method = Arrays.stream(dateServletClass.getDeclaredMethods())
113+
.filter(m -> m.getName().equals("doGet"))
114+
.findAny()
115+
.orElseThrow();
116+
method.setAccessible(true);
117+
return method;
113118
}
114119
}
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
package com.bobocode.mvc.data;
22

3-
43
import com.bobocode.mvc.model.Note;
54
import org.springframework.stereotype.Component;
65

76
import java.time.LocalDate;
7+
import java.time.LocalDateTime;
88
import java.util.*;
99

1010
@Component
1111
public class Notes {
12-
private final Map<UUID, Note> notes = new LinkedHashMap<>();
12+
private final Map<UUID, Note> notesMap = new HashMap<>();
1313

1414
public List<Note> getAll(){
15-
return new ArrayList<>(notes.values());
15+
var noteList = new ArrayList<>(notesMap.values());
16+
noteList.sort(Comparator.comparing(Note::getCreatedOn));
17+
return noteList;
1618
}
1719

1820
public void add(Note note) {
1921
note.setId(UUID.randomUUID());
20-
note.setCreationDate(LocalDate.now());
21-
notes.put(note.getId(), note);
22+
note.setCreatedOn(LocalDateTime.now());
23+
notesMap.put(note.getId(), note);
2224
}
2325
}

3-0-spring-framework/3-0-1-hello-spring-mvc/src/main/java/com/bobocode/mvc/model/Note.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.NonNull;
66

77
import java.time.LocalDate;
8+
import java.time.LocalDateTime;
89
import java.util.UUID;
910

1011
@Data
@@ -15,7 +16,7 @@ public class Note {
1516
private String title;
1617
@NonNull
1718
private String text;
18-
private LocalDate creationDate;
19+
private LocalDateTime createdOn;
1920

2021
public Note(String title, String text) {
2122
this.title = title;

3-0-spring-framework/3-0-1-hello-spring-mvc/src/main/resources/templates/notes.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ <h1 class="title">My notes</h1>
3131
<div class="note" th:each="theNote : ${noteList}">
3232
<div class="title_note" th:text="${theNote.title}">The title</div>
3333
<div class="text_note" th:text="${theNote.text}">The text of very long story, or just shopping list</div>
34-
<div class="date_note" th:text="${theNote.creationDate}">23.04.2021</div>
34+
<div class="date_note" th:text="${theNote.createdOn.toLocalDate()}">23.04.2021</div>
3535
</div>
3636
</div>
3737

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# <img src="https://raw.githubusercontent.com/bobocode-projects/resources/master/image/logo_transparent_background.png" height=50/>Hello Spring MVC exercise
2+
Improve your *Spring MVC* configuration skills 💪
3+
### Task
4+
The task is to **configure a typical *Spring MVC* application** separating web and root configs. Your job is to follow
5+
the instructions in the *todo* section and **implement a proper configuration.**
6+
7+
To verify your configuration, run `WelcomeWebAppTest.java`
8+
9+
10+
### Pre-conditions ❗
11+
You're supposed to be familiar with *Spring MVC*
12+
13+
### How to start ❓
14+
* Just clone the repository and start implementing the **todo** section, verify your changes by running tests
15+
* If you don't have enough knowledge about this domain, check out the [links below](#Related-materials-ℹ)
16+
* Don't worry if you got stuck, checkout the **exercise/completed** branch and see the final implementation
17+
18+
### Related materials ℹ
19+
todo
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>3-0-spring-framework</artifactId>
7+
<groupId>com.bobocode</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>3-1-1-dispatcher-servlet-initializer</artifactId>
13+
<packaging>war</packaging>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.springframework</groupId>
18+
<artifactId>spring-webmvc</artifactId>
19+
<version>5.2.12.RELEASE</version>
20+
</dependency>
21+
<dependency>
22+
<groupId>javax.servlet</groupId>
23+
<artifactId>javax.servlet-api</artifactId>
24+
<version>4.0.1</version>
25+
<scope>provided</scope>
26+
</dependency>
27+
<dependency>
28+
<groupId>com.bobocode</groupId>
29+
<artifactId>java-web-util</artifactId>
30+
<version>1.0-SNAPSHOT</version>
31+
<scope>compile</scope>
32+
</dependency>
33+
</dependencies>
34+
35+
<build>
36+
<plugins>
37+
38+
<plugin>
39+
<groupId>org.apache.maven.plugins</groupId>
40+
<artifactId>maven-war-plugin</artifactId>
41+
<version>2.6</version>
42+
<configuration>
43+
<failOnMissingWebXml>false</failOnMissingWebXml>
44+
</configuration>
45+
</plugin>
46+
47+
</plugins>
48+
</build>
49+
</project>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.bobocode.config;
2+
3+
import org.springframework.context.annotation.ComponentScan;
4+
import org.springframework.context.annotation.ComponentScan.Filter;
5+
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.stereotype.Controller;
7+
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
8+
9+
/**
10+
* This class provides application root (non-web) configuration for a basic spring application context
11+
* (containing middle-tire services, datasource, etc.).
12+
* The configuration must exclude the web layer of the application.
13+
* <p>
14+
* todo: mark this class as config
15+
* todo: enable component scanning for all packages in "com.bobocode"
16+
* todo: ignore all web related config and beans (ignore @{@link Controller}, ignore {@link EnableWebMvc}) using exclude filter
17+
*/
18+
public class RootConfig {
19+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.bobocode.config;
2+
3+
import com.bobocode.util.ExerciseNotCompletedException;
4+
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
5+
6+
/**
7+
* This class is used to configure DispatcherServlet and links it with application config classes
8+
*/
9+
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
10+
@Override
11+
protected Class<?>[] getRootConfigClasses() {
12+
throw new ExerciseNotCompletedException(); //todo: use {@link RootConfig} as root application config class
13+
}
14+
15+
@Override
16+
protected Class<?>[] getServletConfigClasses() {
17+
throw new ExerciseNotCompletedException(); //todo: use {@link WebConfig} as ServletConfig class
18+
}
19+
20+
@Override
21+
protected String[] getServletMappings() {
22+
throw new ExerciseNotCompletedException(); //todo: provide default servlet mapping ("/")
23+
}
24+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.bobocode.config;
2+
3+
import org.springframework.context.annotation.ComponentScan;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
6+
7+
/**
8+
* This class provides web (servlet) related configuration. In the Web MVC framework,
9+
* each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined
10+
* in the root ApplicationContext.
11+
* <p>
12+
* todo: mark this class as Spring config class
13+
* todo: enable web mvc using annotation
14+
* todo: enable component scanning for package "web"
15+
*/
16+
17+
public class WebConfig {
18+
}

0 commit comments

Comments
 (0)