Skip to content
This repository was archived by the owner on Jan 13, 2023. It is now read-only.

Completed solution #1

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7816dda
Complete the exercise "Hello ApplicationContext"
tboychuk Sep 22, 2018
f9c9298
Merge branch 'master' into exercise/completed
tboychuk Sep 22, 2018
8794de9
Merge branch 'master' into exercise/completed
tboychuk Sep 24, 2018
eaeef56
Merge branch 'master' into exercise/completed
tboychuk Sep 24, 2018
d84533d
Complete "Hello Spring MVC" exercise
tboychuk Sep 24, 2018
34e7028
Merge branch 'master' into exercise/completed
tboychuk Sep 26, 2018
8b5399c
Complete the exercise "Account JSP"
tboychuk Sep 26, 2018
4b612b8
Merge branch 'master' into exercise/completed
tboychuk Sep 27, 2018
f49df5b
Complete the exercise "Account REST API"
tboychuk Sep 27, 2018
f84b3be
Merge branch 'master' into exercise/completed
tboychuk Sep 28, 2018
bdb172e
Complete the exercise "Transactional User Service"
tboychuk Sep 28, 2018
3113d5d
Merge branch 'master' into exercise/completed
tboychuk Sep 28, 2018
5f62155
Merge branch 'master' into exercise/completed
tboychuk Sep 28, 2018
b7f5e50
Merge branch 'master' into exercise/completed
tboychuk Oct 22, 2018
144ac83
Merge branch 'master' into exercise/completed
tboychuk Dec 4, 2018
6e43f11
Merge branch 'master' into exercise/completed
tboychuk Dec 4, 2018
46babbc
Merge branch 'master' into exercise/completed
tboychuk Mar 8, 2019
fc7899a
Merge branch 'master' into exercise/completed
tboychuk May 25, 2019
580271f
Fix UserService.java
tboychuk May 25, 2019
a833c59
Merge branch 'master' into exercise/completed
tboychuk Jul 4, 2019
7a3a8c4
Merge branch 'master' into exercise/completed
tboychuk Sep 7, 2019
f81db83
Implement new inter-bean-dependencies exercise
tboychuk Sep 23, 2019
7f29f8d
Merge branch 'master' into exercise/completed
tboychuk Sep 23, 2019
d906157
Implement inter-bean dependencies exercise
tboychuk Sep 23, 2019
b0e51b7
Merge branch 'master' into exercise/completed
tboychuk Sep 23, 2019
ff80591
Merge branch 'master' into exercise/completed
tboychuk Sep 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@
public class AccountWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
throw new UnsupportedOperationException("It's your job to implement this method!");
return new Class[]{RootConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
throw new UnsupportedOperationException("It's your job to implement this method!");
return new Class[]{WebConfig.class};
}

@Override
protected String[] getServletMappings() {
throw new UnsupportedOperationException("It's your job to implement this method!");
return new String[]{"/"};
}
}

11 changes: 11 additions & 0 deletions account-jsp/src/main/java/com/bobocode/config/RootConfig.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.bobocode.config;

import com.bobocode.TestDataGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

Expand All @@ -12,5 +16,12 @@
* todo: 3. Exclude web related config and beans (ignore @{@link Controller}, ignore {@link EnableWebMvc})
* todo: 4. Configure {@link TestDataGenerator} bean with name "dataGenerator" (don't specify name explicitly)
*/
@Configuration
@ComponentScan(basePackages = "com.bobocode", excludeFilters = {@Filter(EnableWebMvc.class), @Filter(Controller.class)})
public class RootConfig {
@Bean
public TestDataGenerator dataGenerator() {
return new TestDataGenerator();
}
}

18 changes: 18 additions & 0 deletions account-jsp/src/main/java/com/bobocode/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package com.bobocode.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
* This class provides web (servlet) related configuration.
* <p>
Expand All @@ -8,6 +15,17 @@
* todo: 3. Enable component scanning for package "web" using annotation value
* todo: 4. Configure JPS internal view resolver with prefix = "/WEB-INF/views/" and suffix ".jsp"
*/
@Configuration
@ComponentScan("com.bobocode.web")
@EnableWebMvc
public class WebConfig {

@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

import com.bobocode.TestDataGenerator;
import com.bobocode.model.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
* This controller provides endpoint that generates a list of {@link Account} and passes it to the view.
Expand All @@ -13,6 +24,17 @@
* todo: 5. Provide a default value "10" for parameter "size"
* todo: 6. Pass the list of accounts to the view using model attribute with name "accountList"
*/
@Controller
@RequestMapping("/accounts")
public class AccountController {
@Autowired
private TestDataGenerator dataGenerator;

@GetMapping
public String getAccounts(@RequestParam(name = "size", defaultValue = "10") int size, Model model) {
List<Account> accounts = Stream.generate(dataGenerator::generateAccount).limit(size).collect(toList());
model.addAttribute("accountList", accounts);
return "accounts";
}
}

Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
package com.bobocode.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
* Welcome controller that consists of one method that handles get request to "/" and "/welcome" and respond with a message.
* <p>
* todo: 1. Mark this class as Spring controller
* todo: 2. Configure HTTP GET mapping "/" and "/welcome" for method {@link WelcomeController#welcome()}
* todo: 3. Forward the request to "welcome.jsp" view
*/
@Controller
public class WelcomeController {

@GetMapping({"/", "/welcome"})
public String welcome() {
return "welcome";
}

}

Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.bobocode.config;

import com.bobocode.TestDataGenerator;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

Expand All @@ -10,5 +14,8 @@
* todo: 2. Enable component scanning for all packages in "com.bobocode" using annotation property "basePackages"
* todo: 3. Exclude web related config and beans (ignore @{@link Controller}, ignore {@link EnableWebMvc})
*/
@Configuration
@ComponentScan(basePackages = "com.bobocode", excludeFilters = {@Filter(EnableWebMvc.class), @Filter(Controller.class)})
public class RootConfig {
}

Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package com.bobocode.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

/**
* This class provides web (servlet) related configuration.
* <p>
* todo: 1. Mark this class as Spring config class
* todo: 2. Enable web mvc using annotation
* todo: 3. Enable component scanning for package "web" using annotation value
*/
@EnableWebMvc
@Configuration
@ComponentScan("com.bobocode.web")
public class WebConfig {

}

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.bobocode.dao.AccountDao;
import com.bobocode.exception.EntityNotFountException;
import com.bobocode.model.Account;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -14,6 +15,7 @@
* <p>
* todo: 1. Configure a component with name "accountDao"
*/
@Component("accountDao")
public class InMemoryAccountDao implements AccountDao {
private Map<Long, Account> accountMap = new HashMap<>();
private long idSequence = 1L;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package com.bobocode.web.controller;

import com.bobocode.dao.AccountDao;
import com.bobocode.model.Account;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
* <p>
Expand All @@ -16,6 +22,46 @@
* todo: 7. Implement method that handles DELETE request with id as path variable removes an account by id
* todo: Configure HTTP response status code 204 - NO CONTENT
*/
@RestController
@RequestMapping("/accounts")
public class AccountRestController {
private final AccountDao accountDao;

public AccountRestController(AccountDao accountDao) {
this.accountDao = accountDao;
}

@GetMapping
public List<Account> getAll() {
return accountDao.findAll();
}

@GetMapping("/{id}")
public Account getOne(@PathVariable long id) {
return accountDao.findById(id);
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Account create(@RequestBody Account account) {
return accountDao.save(account);
}

@PutMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void update(@PathVariable long id, @RequestBody Account account) {
if (!Objects.equals(id, account.getId())) {
throw new IllegalStateException("Id parameter does not match account body value");
}
accountDao.save(account);
}

@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void remove(@PathVariable long id) {
Account account = accountDao.findById(id);
accountDao.remove(account);
}

}

Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.bobocode.config;

import com.bobocode.TestDataGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
* This class application context configuration.
Expand All @@ -10,6 +13,12 @@
* todo: provide explicit configuration for a bean of type {@link TestDataGenerator} with name "dataGenerator" in this class.
* todo: Don't specify bean name "dataGenerator" explicitly
*/
@Configuration
@ComponentScan(basePackages = {"com.bobocode.dao","com.bobocode.service"})
public class AppConfig {

@Bean
public TestDataGenerator dataGenerator() {
return new TestDataGenerator();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.bobocode.TestDataGenerator;
import com.bobocode.model.Account;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Stream;
Expand All @@ -15,9 +16,11 @@
* todo: configure this class as Spring component with bean name "accountDao"
* todo: use explicit (with {@link Autowired} annotation) constructor-based dependency injection
*/
@Component("accountDao")
public class FakeAccountDao implements AccountDao {
private List<Account> accounts;

@Autowired
public FakeAccountDao(TestDataGenerator testDataGenerator) {
this.accounts = Stream.generate(testDataGenerator::generateAccount)
.limit(20)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.bobocode.dao.AccountDao;
import com.bobocode.model.Account;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
Expand All @@ -12,6 +13,7 @@
* todo: configure {@link AccountService} bean implicitly using special annotation for service classes
* todo: use implicit constructor-based dependency injection (don't use {@link org.springframework.beans.factory.annotation.Autowired})
*/
@Service
public class AccountService {
private final AccountDao accountDao;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.bobocode.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

Expand All @@ -10,5 +13,7 @@
* todo: enable component scanning for all packages in "com.bobocode"
* todo: ignore all web related config and beans (ignore @{@link Controller}, ignore {@link EnableWebMvc}) using exclude filter
*/
@Configuration
@ComponentScan(basePackages = "com.bobocode", excludeFilters = {@Filter(EnableWebMvc.class), @Filter(Controller.class)})
public class RootConfig {
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
throw new UnsupportedOperationException("Method is not implemented yet!");
return new Class[]{RootConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
throw new UnsupportedOperationException("Method is not implemented yet!");
return new Class[]{WebConfig.class};

}

@Override
protected String[] getServletMappings() {
throw new UnsupportedOperationException("Method is not implemented yet!");
return new String[]{"/"};
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package com.bobocode.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

/**
* This class provides web (servlet) related configuration.
* <p>
* todo: mark this class as Spring config class
* todo: enable web mvc using annotation
* todo: enable component scanning for package "web"
*/
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.bobocode.web")
public class WebConfig {
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package com.bobocode.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* Welcome controller that consists of one method that handles get request to "/welcome" and respond with a message.
* <p>
* todo: mark this class as Spring controller
* todo: configure HTTP GET mapping "/welcome" for method {@link WelcomeController#welcome()}
* todo: tell Spring that {@link WelcomeController#welcome()} method provides response body
*/
@Controller
public class WelcomeController {

@ResponseBody
@GetMapping("/welcome")
public String welcome() {
return "Welcome to Spring MVC!";
}
Expand Down
Loading