findAll();
/**
* 新增 Book
*
* @param book {@link Book}
*/
Book insertByBook(Book book);
/**
* 更新 Book
*
* @param book {@link Book}
*/
Book update(Book book);
/**
* 删除 Book
*
* @param id 编号
*/
Book delete(Long id);
/**
* 获取 Book
*
* @param id 编号
*/
Book findById(Long id);
/**
* 查找书是否存在
* @param book
* @return
*/
boolean exists(Book book);
/**
* 根据书名获取书籍
* @param name
* @return
*/
Book findByName(String name);
}
================================================
FILE: chapter-3-spring-boot-web/src/main/java/demo/springboot/service/impl/BookServiceImpl.java
================================================
package demo.springboot.service.impl;
import demo.springboot.domain.Book;
import demo.springboot.service.BookService;
import demo.springboot.web.BookController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
/**
* Book 业务层实现
*
* Created by bysocket on 27/09/2017.
*/
@Service
public class BookServiceImpl implements BookService {
private static final AtomicLong counter = new AtomicLong();
/**
* 使用集合模拟数据库
*/
private static List books = new ArrayList<>(
Arrays.asList(
new Book(counter.incrementAndGet(), "book")));
// 模拟数据库,存储 Book 信息
// 第五章《数据存储》会替换成 MySQL 存储
private static Map BOOK_DB = new HashMap<>();
@Override
public List findAll() {
return new ArrayList<>(BOOK_DB.values());
}
@Override
public Book insertByBook(Book book) {
book.setId(BOOK_DB.size() + 1L);
BOOK_DB.put(book.getId().toString(), book);
return book;
}
@Override
public Book update(Book book) {
BOOK_DB.put(book.getId().toString(), book);
return book;
}
@Override
public Book delete(Long id) {
return BOOK_DB.remove(id.toString());
}
@Override
public Book findById(Long id) {
return BOOK_DB.get(id.toString());
}
@Override
public boolean exists(Book book) {
return findByName(book.getName()) != null;
}
@Override
public Book findByName(String name) {
for (Book book : books) {
if (book.getName().equals(name)) {
return book;
}
}
return null;
}
}
================================================
FILE: chapter-3-spring-boot-web/src/main/java/demo/springboot/web/BookController.java
================================================
package demo.springboot.web;
import demo.springboot.domain.Book;
import demo.springboot.service.BookService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.List;
/**
* Book 控制层
*
* Created by bysocket on 27/09/2017.
*/
@RestController
@RequestMapping(value = "/book")
public class BookController {
private final Logger LOG = LoggerFactory.getLogger(BookController.class);
@Autowired
BookService bookService;
/**
* 获取 Book 列表
* 处理 "/book" 的 GET 请求,用来获取 Book 列表
*/
@RequestMapping(method = RequestMethod.GET)
public List getBookList() {
return bookService.findAll();
}
/**
* 获取 Book
* 处理 "/book/{id}" 的 GET 请求,用来获取 Book 信息
*/
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Book getBook(@PathVariable Long id) {
return bookService.findById(id);
}
/**
* 创建 Book
* 处理 "/book/create" 的 POST 请求,用来新建 Book 信息
* 通过 @RequestBody 绑定实体参数,也通过 @RequestParam 传递参数
*/
@RequestMapping(value = "/create", method = RequestMethod.POST)
public ResponseEntity postBook(@RequestBody Book book, UriComponentsBuilder ucBuilder) {
LOG.info("creating new book: {}", book);
if (book.getName().equals("conflict")){
LOG.info("a book with name " + book.getName() + " already exists");
return new ResponseEntity<>(HttpStatus.CONFLICT);
}
bookService.insertByBook(book);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/book/{id}").buildAndExpand(book.getId()).toUri());
return new ResponseEntity<>(headers, HttpStatus.CREATED);
}
/**
* 更新 Book
* 处理 "/update" 的 PUT 请求,用来更新 Book 信息
*/
@RequestMapping(value = "/update", method = RequestMethod.PUT)
public Book putBook(@RequestBody Book book) {
return bookService.update(book);
}
/**
* 删除 Book
* 处理 "/book/{id}" 的 GET 请求,用来删除 Book 信息
*/
@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
public Book deleteBook(@PathVariable Long id) {
return bookService.delete(id);
}
}
================================================
FILE: chapter-3-spring-boot-web/src/main/resources/application.properties
================================================
================================================
FILE: chapter-3-spring-boot-web/src/test/java/demo/springboot/WebApplicationTests.java
================================================
package demo.springboot;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class WebApplicationTests {
@Test
public void contextLoads() {
}
}
================================================
FILE: chapter-3-spring-boot-web/src/test/java/demo/springboot/web/BookControllerTest.java
================================================
package demo.springboot.web;
import com.fasterxml.jackson.databind.ObjectMapper;
import demo.springboot.WebApplication;
import demo.springboot.domain.Book;
import demo.springboot.service.BookService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WebApplication.class)
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application.properties")
public class BookControllerTest {
private MockMvc mockMvc;
@Mock
private BookService bookService;
@InjectMocks
private BookController bookController;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders
.standaloneSetup(bookController)
//.addFilters(new CORSFilter())
.build();
}
@Test
public void getBookList() throws Exception {
mockMvc.perform(get("/book")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$", hasSize(0)));
}
@Test
public void test_create_book_success() throws Exception {
Book book = createOneBook();
when(bookService.insertByBook(book)).thenReturn(book);
mockMvc.perform(
post("/book/create")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(book)))
.andExpect(status().isCreated())
.andExpect(header().string("location", containsString("/book/1")));
}
@Test
public void test_create_book_fail_404_not_found() throws Exception {
Book book = new Book(99L, "conflict");
when(bookService.exists(book)).thenReturn(true);
mockMvc.perform(
post("/book/create")
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(book)))
.andExpect(status().isConflict());
}
@Test
public void test_get_book_success() throws Exception {
Book book = new Book(1L, "测试获取一本书", "strongant作者", "社区 www.spring4all.com 出版社出版");
when(bookService.findById(1L)).thenReturn(book);
mockMvc.perform(get("/book/{id}", 1L))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$.id", is(1)))
.andExpect(jsonPath("$.name", is("测试获取一本书")));
verify(bookService, times(1)).findById(1L);
verifyNoMoreInteractions(bookService);
}
@Test
public void test_get_by_id_fail_null_not_found() throws Exception {
when(bookService.findById(1L)).thenReturn(null);
//TODO: 查找不到应该抛出 404 状态码, Demo 待优化
mockMvc.perform(get("/book/{id}", 1L))
.andExpect(status().isOk())
.andExpect(content().string(""));
verify(bookService, times(1)).findById(1L);
verifyNoMoreInteractions(bookService);
}
@Test
public void test_update_book_success() throws Exception {
Book book = createOneBook();
when(bookService.findById(book.getId())).thenReturn(book);
doReturn(book).when(bookService).update(book);
mockMvc.perform(
put("/book/update", book)
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(book)))
.andExpect(status().isOk());
}
@Test
public void test_update_book_fail_not_found() throws Exception {
Book book = new Book(999L, "测试书名1");
when(bookService.findById(book.getId())).thenReturn(null);
mockMvc.perform(
put("/book/update", book)
.contentType(MediaType.APPLICATION_JSON)
.content(asJsonString(book)))
.andExpect(status().isOk())
.andExpect(content().string(""));
}
// =========================================== Delete Book ============================================
@Test
public void test_delete_book_success() throws Exception {
Book book = new Book(1L, "这本书会被删除啦");
when(bookService.findById(book.getId())).thenReturn(book);
doReturn(book).when(bookService).delete(book.getId());
mockMvc.perform(
delete("/book/delete/{id}", book.getId())
).andExpect(status().isOk());
}
@Test
public void test_delete_book_fail_404_not_found() throws Exception {
Book book = new Book(1L, "这本书会被删除啦");
when(bookService.findById(book.getId())).thenReturn(null);
mockMvc.perform(
delete("/book/delete/{id}", book.getId()))
.andExpect(status().isOk());
}
public static String asJsonString(final Object obj) {
try {
final ObjectMapper mapper = new ObjectMapper();
return mapper.writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Book createOneBook() {
Book book = new Book();
book.setId(1L);
book.setName("测试书名1");
book.setIntroduction("这是一本 www.spring4all.com 社区出版的很不错的一本书籍");
book.setWriter("strongant");
return book;
}
}
================================================
FILE: chapter-3-spring-boot-web/src/test/resources/application.properties
================================================
server.port=9090
================================================
FILE: chapter-4-spring-boot-validating-form-input/pom.xml
================================================
4.0.0
spring.boot.core
chapter-4-spring-boot-validating-form-input
0.0.1-SNAPSHOT
jar
chapter-4-spring-boot-validating-form-input
第四章表单校验案例
org.springframework.boot
spring-boot-starter-parent
2.0.0.M4
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-validation
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-data-jpa
com.h2database
h2
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-maven-plugin
2.1.3.RELEASE
spring-milestones
Spring Milestones
https://repo.spring.io/libs-milestone
false
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/ValidatingFormInputApplication.java
================================================
package spring.boot.core;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import spring.boot.core.domain.User;
import spring.boot.core.domain.UserRepository;
@SpringBootApplication
public class ValidatingFormInputApplication implements CommandLineRunner {
private Logger LOG = LoggerFactory.getLogger(ValidatingFormInputApplication.class);
@Autowired
private UserRepository userRepository;
public static void main(String[] args) {
SpringApplication.run(ValidatingFormInputApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
User user1 = new User("Sergey", 24, "1994-01-01");
User user2 = new User("Ivan", 26, "1994-01-01");
User user3 = new User("Adam", 31, "1994-01-01");
LOG.info("Inserting data in DB.");
userRepository.save(user1);
userRepository.save(user2);
userRepository.save(user3);
LOG.info("User count in DB: {}", userRepository.count());
LOG.info("User with ID 1: {}", userRepository.findById(1L));
LOG.info("Deleting user with ID 2L form DB.");
userRepository.deleteById(2L);
LOG.info("User count in DB: {}", userRepository.count());
}
}
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/domain/User.java
================================================
package spring.boot.core.domain;
import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
/**
* 用户实体类
*
* Created by bysocket on 21/07/2017.
*/
@Entity
public class User implements Serializable {
/**
* 编号
*/
@Id
@GeneratedValue
private Long id;
/**
* 名称
*/
@NotEmpty(message = "姓名不能为空")
@Size(min = 2, max = 8, message = "姓名长度必须大于 2 且小于 20 字")
private String name;
/**
* 年龄
*/
@NotNull(message = "年龄不能为空")
@Min(value = 0, message = "年龄大于 0")
@Max(value = 300, message = "年龄不大于 300")
private Integer age;
/**
* 出生时间
*/
@NotEmpty(message = "出生时间不能为空")
private String birthday;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public User(String name, Integer age, String birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
public User() {}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
'}';
}
}
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/domain/UserRepository.java
================================================
package spring.boot.core.domain;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* 用户持久层操作接口
*
* Created by bysocket on 21/07/2017.
*/
public interface UserRepository extends JpaRepository {
}
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/service/UserService.java
================================================
package spring.boot.core.service;
import spring.boot.core.domain.User;
import java.util.List;
/**
* User 业务层接口
*
* Created by bysocket on 24/07/2017.
*/
public interface UserService {
List findAll();
User insertByUser(User user);
User update(User user);
User delete(Long id);
User findById(Long id);
}
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/service/impl/UserServiceImpl.java
================================================
package spring.boot.core.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import spring.boot.core.domain.User;
import spring.boot.core.domain.UserRepository;
import spring.boot.core.service.UserService;
import java.util.List;
/**
* User 业务层实现
*
* Created by bysocket on 24/07/2017.
*/
@Service
public class UserServiceImpl implements UserService {
private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
@Autowired
UserRepository userRepository;
@Override
public List findAll() {
return userRepository.findAll();
}
@Override
public User insertByUser(User user) {
LOGGER.info("新增用户:" + user.toString());
return userRepository.save(user);
}
@Override
public User update(User user) {
LOGGER.info("更新用户:" + user.toString());
return userRepository.save(user);
}
@Override
public User delete(Long id) {
User user = userRepository.findById(id).get();
userRepository.delete(user);
LOGGER.info("删除用户:" + user.toString());
return user;
}
@Override
public User findById(Long id) {
LOGGER.info("获取用户 ID :" + id);
return userRepository.findById(id).get();
}
}
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/java/spring/boot/core/web/UserController.java
================================================
package spring.boot.core.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import spring.boot.core.domain.User;
import spring.boot.core.service.UserService;
import javax.validation.Valid;
/**
* 用户控制层
*
* Created by bysocket on 24/07/2017.
*/
@Controller
@RequestMapping(value = "/users") // 通过这里配置使下面的映射都在 /users
public class UserController {
@Autowired
UserService userService; // 用户服务层
/**
* 获取用户列表
* 处理 "/users" 的 GET 请求,用来获取用户列表
* 通过 @RequestParam 传递参数,进一步实现条件查询或者分页查询
*/
@RequestMapping(method = RequestMethod.GET)
public String getUserList(ModelMap map) {
map.addAttribute("userList", userService.findAll());
return "userList";
}
/**
* 显示创建用户表单
*
* @param map
* @return
*/
@RequestMapping(value = "/create", method = RequestMethod.GET)
public String createUserForm(ModelMap map) {
map.addAttribute("user", new User());
map.addAttribute("action", "create");
return "userForm";
}
/**
* 创建用户
* 处理 "/users" 的 POST 请求,用来获取用户列表
* 通过 @ModelAttribute 绑定参数,也通过 @RequestParam 从页面中传递参数
*/
@RequestMapping(value = "/create", method = RequestMethod.POST)
public String postUser(ModelMap map,
@ModelAttribute @Valid User user,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
map.addAttribute("action", "create");
return "userForm";
}
userService.insertByUser(user);
return "redirect:/users/";
}
/**
* 显示需要更新用户表单
* 处理 "/users/{id}" 的 GET 请求,通过 URL 中的 id 值获取 User 信息
* URL 中的 id ,通过 @PathVariable 绑定参数
*/
@RequestMapping(value = "/update/{id}", method = RequestMethod.GET)
public String getUser(@PathVariable Long id, ModelMap map) {
map.addAttribute("user", userService.findById(id));
map.addAttribute("action", "update");
return "userForm";
}
/**
* 处理 "/users/{id}" 的 PUT 请求,用来更新 User 信息
*
*/
@RequestMapping(value = "/update", method = RequestMethod.POST)
public String putUser(ModelMap map,
@ModelAttribute @Valid User user,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
map.addAttribute("action", "update");
return "userForm";
}
userService.update(user);
return "redirect:/users/";
}
/**
* 处理 "/users/{id}" 的 GET 请求,用来删除 User 信息
*/
@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
public String deleteUser(@PathVariable Long id) {
userService.delete(id);
return "redirect:/users/";
}
}
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/resources/application.properties
================================================
## 开启 H2 数据库
spring.h2.console.enabled=true
## 配置 H2 数据库连接信息
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
## 是否显示 SQL 语句
spring.jpa.show-sql=true
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.hbm2ddl.auto=create
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/resources/static/css/default.css
================================================
/* contentDiv */
.contentDiv {padding:20px 60px;}
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/resources/templates/userForm.html
================================================
用户管理
《 Spring Boot 2.x 核心技术实战》第二章快速入门案例
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/main/resources/templates/userList.html
================================================
用户列表
《 Spring Boot 2.x 核心技术实战》第二章快速入门案例
| 用户编号 |
名称 |
年龄 |
出生时间 |
管理 |
|
|
|
|
删除 |
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/test/java/spring/boot/core/ValidatingFormInputApplicationTests.java
================================================
package spring.boot.core;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ValidatingFormInputApplicationTests {
@Test
public void contextLoads() {
}
}
================================================
FILE: chapter-4-spring-boot-validating-form-input/src/test/java/spring/boot/core/web/UserControllerTest.java
================================================
package spring.boot.core.web;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import spring.boot.core.ValidatingFormInputApplication;
import spring.boot.core.domain.User;
import spring.boot.core.service.UserService;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ValidatingFormInputApplication.class)
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application.properties")
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private UserService userService;
@Autowired
private ObjectMapper objectMapper;
@Test
public void getUserList() throws Exception {
mockMvc.perform(get("/users"))
.andExpect(view().name("userList"))
.andExpect(status().isOk())
.andDo(print());
}
private User createUser() {
User user = new User();
user.setName("测试用户");
user.setAge(100);
user.setBirthday("1994-01-01");
return userService.insertByUser(user);
}
@Test
public void createUserForm() throws Exception {
mockMvc.perform(get("/users/create"))
.andDo(print())
.andExpect(view().name("userForm"))
.andExpect(request().attribute("action", "create"))
.andDo(print())
.andReturn();
}
@Test
public void postUser() throws Exception {
User user = createUser();
assertNotNull(user);
MultiValueMap parameters = new LinkedMultiValueMap();
Map maps = objectMapper.convertValue(user, new TypeReference