Merge branch 'master' into JAVA-3536-move-spring-rest-shell
This commit is contained in:
@@ -20,10 +20,17 @@
|
||||
<module>spring-mvc-basics-4</module>
|
||||
<module>spring-mvc-crash</module>
|
||||
<module>spring-mvc-forms-jsp</module>
|
||||
<module>spring-mvc-forms-thymeleaf</module>
|
||||
<module>spring-mvc-java</module>
|
||||
<module>spring-mvc-java-2</module>
|
||||
<module>spring-mvc-velocity</module>
|
||||
<module>spring-mvc-views</module>
|
||||
<module>spring-mvc-webflow</module>
|
||||
<module>spring-mvc-xml</module>
|
||||
<module>spring-rest-angular</module>
|
||||
<module>spring-rest-http</module>
|
||||
<module>spring-rest-http-2</module>
|
||||
<module>spring-rest-query-language</module>
|
||||
<module>spring-rest-shell</module>
|
||||
<module>spring-resttemplate-2</module>
|
||||
<module>spring-thymeleaf</module>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
## Spring MVC Forms Thymeleaf
|
||||
|
||||
This module contains articles about Spring MVC Forms using Thymeleaf
|
||||
|
||||
### Relevant articles
|
||||
|
||||
- [Session Attributes in Spring MVC](https://www.baeldung.com/spring-mvc-session-attributes)
|
||||
- [Binding a List in Thymeleaf](https://www.baeldung.com/thymeleaf-list)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-mvc-forms-thymeleaf</artifactId>
|
||||
<name>spring-mvc-forms-thymeleaf</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>spring forms examples using thymeleaf</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- runtime and test scoped -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
|
||||
<start-class>com.baeldung.sessionattrs.SessionAttrsApplication</start-class>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.baeldung.listbindingexample;
|
||||
|
||||
public class Book {
|
||||
|
||||
private long id;
|
||||
|
||||
private String title;
|
||||
|
||||
private String author;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((author == null) ? 0 : author.hashCode());
|
||||
result = prime * result + (int) (id ^ (id >>> 32));
|
||||
result = prime * result + ((title == null) ? 0 : title.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Book other = (Book) obj;
|
||||
if (author == null) {
|
||||
if (other.author != null)
|
||||
return false;
|
||||
} else if (!author.equals(other.author))
|
||||
return false;
|
||||
if (id != other.id)
|
||||
return false;
|
||||
if (title == null) {
|
||||
if (other.title != null)
|
||||
return false;
|
||||
} else if (!title.equals(other.title))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Book [id=" + id + ", title=" + title + ", author=" + author + "]";
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.baeldung.listbindingexample;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BookService {
|
||||
|
||||
List<Book> findAll();
|
||||
|
||||
void saveAll(List<Book> books);
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.listbindingexample;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BooksCreationDto {
|
||||
|
||||
private List<Book> books;
|
||||
|
||||
public BooksCreationDto() {
|
||||
this.books = new ArrayList<>();
|
||||
}
|
||||
|
||||
public BooksCreationDto(List<Book> books) {
|
||||
this.books = books;
|
||||
}
|
||||
|
||||
public List<Book> getBooks() {
|
||||
return books;
|
||||
}
|
||||
|
||||
public void setBooks(List<Book> books) {
|
||||
this.books = books;
|
||||
}
|
||||
|
||||
public void addBook(Book book) {
|
||||
this.books.add(book);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.listbindingexample;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
public class Config implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/")
|
||||
.setViewName("index");
|
||||
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ITemplateResolver templateResolver() {
|
||||
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
|
||||
resolver.setPrefix("templates/books/");
|
||||
resolver.setSuffix(".html");
|
||||
resolver.setTemplateMode(TemplateMode.HTML);
|
||||
resolver.setCharacterEncoding("UTF-8");
|
||||
return resolver;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.listbindingexample;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class InMemoryBookService implements BookService {
|
||||
|
||||
static Map<Long, Book> booksDB = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public List<Book> findAll() {
|
||||
return new ArrayList<>(booksDB.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAll(List<Book> books) {
|
||||
long nextId = getNextId();
|
||||
for (Book book : books) {
|
||||
if (book.getId() == 0) {
|
||||
book.setId(nextId++);
|
||||
}
|
||||
}
|
||||
|
||||
Map<Long, Book> bookMap = books.stream()
|
||||
.collect(Collectors.toMap(Book::getId, Function.identity()));
|
||||
|
||||
booksDB.putAll(bookMap);
|
||||
}
|
||||
|
||||
private Long getNextId() {
|
||||
return booksDB.keySet()
|
||||
.stream()
|
||||
.mapToLong(value -> value)
|
||||
.max()
|
||||
.orElse(0) + 1;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.listbindingexample;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
|
||||
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, DataSourceAutoConfiguration.class })
|
||||
public class ListBindingApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ListBindingApplication.class, args);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.baeldung.listbindingexample;
|
||||
|
||||
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.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/books")
|
||||
public class MultipleBooksController {
|
||||
|
||||
@Autowired
|
||||
private BookService bookService;
|
||||
|
||||
@GetMapping(value = "/all")
|
||||
public String showAll(Model model) {
|
||||
model.addAttribute("books", bookService.findAll());
|
||||
|
||||
return "allBooks";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/create")
|
||||
public String showCreateForm(Model model) {
|
||||
BooksCreationDto booksForm = new BooksCreationDto();
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
booksForm.addBook(new Book());
|
||||
}
|
||||
|
||||
model.addAttribute("form", booksForm);
|
||||
|
||||
return "createBooksForm";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/edit")
|
||||
public String showEditForm(Model model) {
|
||||
List<Book> books = new ArrayList<>();
|
||||
bookService.findAll()
|
||||
.iterator()
|
||||
.forEachRemaining(books::add);
|
||||
|
||||
model.addAttribute("form", new BooksCreationDto(books));
|
||||
|
||||
return "editBooksForm";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/save")
|
||||
public String saveBooks(@ModelAttribute BooksCreationDto form, Model model) {
|
||||
bookService.saveAll(form.getBooks());
|
||||
|
||||
model.addAttribute("books", bookService.findAll());
|
||||
|
||||
return "redirect:/books/all";
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
public class Config implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/").setViewName("index");
|
||||
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Scope(
|
||||
value = WebApplicationContext.SCOPE_SESSION,
|
||||
proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public TodoList todos() {
|
||||
return new TodoList();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ITemplateResolver templateResolver() {
|
||||
ClassLoaderTemplateResolver resolver
|
||||
= new ClassLoaderTemplateResolver();
|
||||
resolver.setPrefix("templates/sessionattrs/");
|
||||
resolver.setSuffix(".html");
|
||||
resolver.setTemplateMode(TemplateMode.HTML);
|
||||
resolver.setCharacterEncoding("UTF-8");
|
||||
return resolver;
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
|
||||
@SpringBootApplication(
|
||||
exclude = {SecurityAutoConfiguration.class,
|
||||
DataSourceAutoConfiguration.class})
|
||||
public class SessionAttrsApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SessionAttrsApplication.class, args);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/scopedproxy")
|
||||
public class TodoControllerWithScopedProxy {
|
||||
|
||||
private TodoList todos;
|
||||
|
||||
public TodoControllerWithScopedProxy(TodoList todos) {
|
||||
this.todos = todos;
|
||||
}
|
||||
|
||||
@GetMapping("/form")
|
||||
public String showForm(Model model) {
|
||||
if (!todos.isEmpty()) {
|
||||
model.addAttribute("todo", todos.peekLast());
|
||||
} else {
|
||||
model.addAttribute("todo", new TodoItem());
|
||||
}
|
||||
|
||||
return "scopedproxyform";
|
||||
}
|
||||
|
||||
@PostMapping("/form")
|
||||
public String create(@ModelAttribute TodoItem todo) {
|
||||
todo.setCreateDate(LocalDateTime.now());
|
||||
todos.add(todo);
|
||||
return "redirect:/scopedproxy/todos.html";
|
||||
}
|
||||
|
||||
@GetMapping("/todos.html")
|
||||
public String list(Model model) {
|
||||
model.addAttribute("todos", todos);
|
||||
return "scopedproxytodos";
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/sessionattributes")
|
||||
@SessionAttributes("todos")
|
||||
public class TodoControllerWithSessionAttributes {
|
||||
|
||||
@GetMapping("/form")
|
||||
public String showForm(
|
||||
Model model,
|
||||
@ModelAttribute("todos") TodoList todos) {
|
||||
if (!todos.isEmpty()) {
|
||||
model.addAttribute("todo", todos.peekLast());
|
||||
} else {
|
||||
model.addAttribute("todo", new TodoItem());
|
||||
}
|
||||
return "sessionattributesform";
|
||||
}
|
||||
|
||||
@PostMapping("/form")
|
||||
public RedirectView create(
|
||||
@ModelAttribute TodoItem todo,
|
||||
@ModelAttribute("todos") TodoList todos,
|
||||
RedirectAttributes attributes) {
|
||||
todo.setCreateDate(LocalDateTime.now());
|
||||
todos.add(todo);
|
||||
attributes.addFlashAttribute("todos", todos);
|
||||
return new RedirectView("/sessionattributes/todos.html");
|
||||
}
|
||||
|
||||
@GetMapping("/todos.html")
|
||||
public String list(
|
||||
Model model,
|
||||
@ModelAttribute("todos") TodoList todos) {
|
||||
model.addAttribute("todos", todos);
|
||||
return "sessionattributestodos";
|
||||
}
|
||||
|
||||
@ModelAttribute("todos")
|
||||
public TodoList todos() {
|
||||
return new TodoList();
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class TodoItem {
|
||||
|
||||
private String description;
|
||||
private LocalDateTime createDate;
|
||||
|
||||
public TodoItem(String description, LocalDateTime createDate) {
|
||||
this.description = description;
|
||||
this.createDate = createDate;
|
||||
}
|
||||
|
||||
public TodoItem() {
|
||||
// default no arg constructor
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreateDate() {
|
||||
return createDate;
|
||||
}
|
||||
|
||||
public void setCreateDate(LocalDateTime createDate) {
|
||||
this.createDate = createDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TodoItem [description=" + description + ", createDate=" + createDate + "]";
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class TodoList extends ArrayDeque<TodoItem>{
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
server.port=8081
|
||||
|
||||
logging.level.root=INFO
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>All Books</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1> Books </h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> Title </th>
|
||||
<th> Author </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:if="${books.empty}">
|
||||
<td colspan="2"> No Books Available </td>
|
||||
</tr>
|
||||
<tr th:each="book : ${books}">
|
||||
<td><span th:text="${book.title}"> Title </span></td>
|
||||
<td><span th:text="${book.author}"> Author </span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<a class="btn btn-success" href="#" th:href="@{/books/create}"> Add Books </a>
|
||||
<a class="btn btn-primary" href="#" th:href="@{/books/edit}" th:classappend="${books.empty} ? 'disabled' : ''"> Edit Books </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Add Books</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1> Add Books </h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<a class="btn btn-info" href="#" th:href="@{/books/all}"> Back to All Books </a>
|
||||
<form action="#" class="form-horizontal"
|
||||
th:action="@{/books/save}"
|
||||
th:object="${form}"
|
||||
method="post">
|
||||
<fieldset>
|
||||
<span class="pull-right">
|
||||
<input type="submit" id="submitButton" class="btn btn-success" th:value="Save">
|
||||
<input type="reset" id="resetButton" class="btn btn-danger" th:value="Reset"/>
|
||||
</span>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> Title</th>
|
||||
<th> Author</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="book, itemStat : *{books}">
|
||||
<td><input th:placeholder="Title + ' ' + ${itemStat.count}" th:field="*{books[__${itemStat.index}__].title}" required/></td>
|
||||
<td><input th:placeholder="Author + ' ' + ${itemStat.count}" th:field="*{books[__${itemStat.index}__].author}" required/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Edit Books</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1> Add Books </h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<a class="btn btn-info" href="#" th:href="@{/books/all}"> Back to All Books </a>
|
||||
<form action="#" class="form-horizontal"
|
||||
th:action="@{/books/save}"
|
||||
th:object="${form}"
|
||||
method="post">
|
||||
<fieldset>
|
||||
<span class="pull-right">
|
||||
<input type="submit" id="submitButton" class="btn btn-success" th:value="Save">
|
||||
<input type="reset" id="resetButton" class="btn btn-danger" th:value="Reset"/>
|
||||
</span>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th> Title</th>
|
||||
<th> Author</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="book, itemStat : ${form.books}">
|
||||
<td><input hidden th:name="|books[${itemStat.index}].id|" th:value="${book.getId()}"/></td>
|
||||
<td><input th:placeholder="Title + ' ' + ${itemStat.count}" th:name="|books[${itemStat.index}].title|" th:value="${book.getTitle()}"
|
||||
required/></td>
|
||||
<td><input th:placeholder="Author + ' ' + ${itemStat.count}" th:name="|books[${itemStat.index}].author|"
|
||||
th:value="${book.getAuthor()}" required/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4" lang="en">
|
||||
<head>
|
||||
<title>Binding a List in Thymeleaf</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p>
|
||||
<h3>Binding a List in Thymeleaf - Example</h3>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<a class="btn btn-info" href="#" th:href="@{/books/all}"> Books List </a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4" lang="en">
|
||||
<head>
|
||||
<title>Session Attributes in Spring MVC</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p>
|
||||
<h3>Session Scope in Spring MVC - Example</h3>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a href="/scopedproxy/form" class="btn btn-sm btn-primary btn-block float-right" role="button">Session Scoped Proxy Example</a></div>
|
||||
<div class="col">
|
||||
<a href="/sessionattributes/form" class="btn btn-sm btn-primary btn-block float-right" role="button">Session Attributes Example</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4" lang="en">
|
||||
<head>
|
||||
<title>Session Attributes in Spring MVC</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p>
|
||||
<h3>Scoped Proxy Example</h3>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h5>Enter a TODO</h5>
|
||||
<form action="#" th:action="@{/scopedproxy/form}" th:object="${todo}" method="post">
|
||||
<div class="input-group">
|
||||
<input type="text" th:field="*{description}" class="form-control" placeholder="TODO" required autofocus/>
|
||||
<button class="btn btn-sm btn-primary form-control text-center" type="submit" style="max-width: 80px;">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4" lang="en">
|
||||
<head>
|
||||
<title>Session Attributes in Spring MVC</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"
|
||||
crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p>
|
||||
<h3>Scoped Proxy Example</h3>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<br/>
|
||||
<div class="row">
|
||||
<a th:href="@{/scopedproxy/form}" class="btn btn-sm btn-primary btn-block" role="button"
|
||||
style="width: 10em;">Add New</a>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col card" style="padding: 1em;">
|
||||
<div class="card-block">
|
||||
<h5 class="card-title">TODO List</h5>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="75%">Description</th>
|
||||
<th width="25%" >Create Date</th>
|
||||
</tr>
|
||||
<tr th:each="todo : ${todos}">
|
||||
<td th:text="${todo.description}">Description</td>
|
||||
<td th:text="${#temporals.format(todo.createDate, 'MM-dd-yyyy HH:mm:ss')}">Create Date</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4" lang="en">
|
||||
<head>
|
||||
<title>Session Attributes in Spring MVC</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p>
|
||||
<h3>Session Attributes Example</h3>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h5>Enter a TODO</h5>
|
||||
<form action="#" th:action="@{/sessionattributes/form}" th:object="${todo}" method="post">
|
||||
<div class="input-group">
|
||||
<input type="text" th:field="*{description}" class="form-control" placeholder="TODO" required autofocus/>
|
||||
<button class="btn btn-sm btn-primary form-control text-center" type="submit" style="max-width: 80px;">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4" lang="en">
|
||||
<head>
|
||||
<title>Session Attributes in Spring MVC</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"
|
||||
rel="stylesheet"
|
||||
integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M"
|
||||
crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<p>
|
||||
<h3>Session Attributes Example</h3>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<br/>
|
||||
<div class="row">
|
||||
<a th:href="@{/sessionattributes/form}" class="btn btn-sm btn-primary btn-block" role="button"
|
||||
style="width: 10em;">Add New</a>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="row">
|
||||
<div class="col card" style="padding: 1em;">
|
||||
<div class="card-block">
|
||||
<h5 class="card-title">TODO List</h5>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="75%">Description</th>
|
||||
<th width="25%" >Create Date</th>
|
||||
</tr>
|
||||
<tr th:each="todo : ${todos}">
|
||||
<td th:text="${todo.description}">Description</td>
|
||||
<td th:text="${#temporals.format(todo.createDate, 'MM-dd-yyyy HH:mm:ss')}">Create Date</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.listbindingexample;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.listbindingexample.ListBindingApplication;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = {ListBindingApplication.class})
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
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 SessionAttrsApplicationIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.sessionattrs.SessionAttrsApplication;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = {SessionAttrsApplication.class})
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import org.springframework.beans.factory.config.CustomScopeConfigurer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.SimpleThreadScope;
|
||||
|
||||
@Configuration
|
||||
public class TestConfig {
|
||||
|
||||
@Bean
|
||||
public CustomScopeConfigurer customScopeConfigurer() {
|
||||
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
|
||||
configurer.addScope("session", new SimpleThreadScope());
|
||||
return configurer;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
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.MockMvcResultMatchers.model;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Before;
|
||||
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.context.annotation.Import;
|
||||
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.setup.MockMvcBuilders;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
|
||||
@AutoConfigureMockMvc
|
||||
@Import(TestConfig.class)
|
||||
public class TodoControllerWithScopedProxyIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext wac;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFirstRequest_thenContainsUnintializedTodo() throws Exception {
|
||||
MvcResult result = mockMvc.perform(get("/scopedproxy/form"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(model().attributeExists("todo"))
|
||||
.andReturn();
|
||||
|
||||
TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo");
|
||||
assertFalse(StringUtils.isEmpty(item.getDescription()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSubmit_thenSubsequentFormRequestContainsMostRecentTodo() throws Exception {
|
||||
mockMvc.perform(post("/scopedproxy/form")
|
||||
.param("description", "newtodo"))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andReturn();
|
||||
|
||||
MvcResult result = mockMvc.perform(get("/scopedproxy/form"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(model().attributeExists("todo"))
|
||||
.andReturn();
|
||||
TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo");
|
||||
assertEquals("newtodo", item.getDescription());
|
||||
}
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.baeldung.sessionattrs;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
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.MockMvcResultMatchers.model;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Before;
|
||||
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.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.FlashMap;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
|
||||
@AutoConfigureMockMvc
|
||||
public class TodoControllerWithSessionAttributesIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext wac;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFirstRequest_thenContainsUnintializedTodo() throws Exception {
|
||||
MvcResult result = mockMvc.perform(get("/sessionattributes/form"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(model().attributeExists("todo"))
|
||||
.andReturn();
|
||||
|
||||
TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo");
|
||||
assertTrue(StringUtils.isEmpty(item.getDescription()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSubmit_thenSubsequentFormRequestContainsMostRecentTodo() throws Exception {
|
||||
FlashMap flashMap = mockMvc.perform(post("/sessionattributes/form")
|
||||
.param("description", "newtodo"))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andReturn().getFlashMap();
|
||||
|
||||
MvcResult result = mockMvc.perform(get("/sessionattributes/form")
|
||||
.sessionAttrs(flashMap))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(model().attributeExists("todo"))
|
||||
.andReturn();
|
||||
TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo");
|
||||
assertEquals("newtodo", item.getDescription());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
@@ -0,0 +1,9 @@
|
||||
### Relevant Articles:
|
||||
|
||||
- [Cache Headers in Spring MVC](https://www.baeldung.com/spring-mvc-cache-headers)
|
||||
- [Working with Date Parameters in Spring](https://www.baeldung.com/spring-date-parameters)
|
||||
- [Spring MVC @PathVariable with a dot (.) gets truncated](https://www.baeldung.com/spring-mvc-pathvariable-dot)
|
||||
- [A Quick Guide to Spring MVC Matrix Variables](https://www.baeldung.com/spring-mvc-matrix-variables)
|
||||
- [Converting a Spring MultipartFile to a File](https://www.baeldung.com/spring-multipartfile-to-file)
|
||||
- [Testing a Spring Multipart POST Request](https://www.baeldung.com/spring-multipart-post-request-test)
|
||||
- [Spring @Pathvariable Annotation](https://www.baeldung.com/spring-pathvariable)
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-mvc-java-2</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>spring-mvc-java-2</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${javax.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${spring.mvc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>spring-mvc-java-2</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<javax.version>4.0.1</javax.version>
|
||||
<spring.mvc.version>5.2.2.RELEASE</spring.mvc.version>
|
||||
</properties>
|
||||
|
||||
|
||||
</project>
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
package com.baeldung.cache;
|
||||
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Controller
|
||||
public class CacheControlController {
|
||||
|
||||
@GetMapping(value = "/hello/{name}")
|
||||
public ResponseEntity<String> hello(@PathVariable String name) {
|
||||
CacheControl cacheControl = CacheControl.maxAge(60, TimeUnit.SECONDS)
|
||||
.noTransform()
|
||||
.mustRevalidate();
|
||||
return ResponseEntity.ok()
|
||||
.cacheControl(cacheControl)
|
||||
.body("Hello " + name);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/home/{name}")
|
||||
public String home(@PathVariable String name, final HttpServletResponse response) {
|
||||
response.addHeader("Cache-Control", "max-age=60, must-revalidate, no-transform");
|
||||
return "home";
|
||||
}
|
||||
|
||||
@GetMapping(value = "/login/{name}")
|
||||
public ResponseEntity<String> intercept(@PathVariable String name) {
|
||||
return ResponseEntity.ok().body("Hello " + name);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/productInfo/{name}")
|
||||
public ResponseEntity<String> validate(@PathVariable String name, WebRequest request) {
|
||||
|
||||
ZoneId zoneId = ZoneId.of("GMT");
|
||||
long lastModifiedTimestamp = LocalDateTime.of(2020, 02, 4, 19, 57, 45)
|
||||
.atZone(zoneId).toInstant().toEpochMilli();
|
||||
|
||||
if (request.checkNotModified(lastModifiedTimestamp)) {
|
||||
return ResponseEntity.status(304).build();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok().body("Hello " + name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.baeldung.cache;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.CacheControl;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.mvc.WebContentInterceptor;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = {"com.baeldung.cache"})
|
||||
public class CacheWebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
registry.addViewController("/").setViewName("index");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/")
|
||||
.setCacheControl(CacheControl.maxAge(60, TimeUnit.SECONDS)
|
||||
.noTransform()
|
||||
.mustRevalidate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
WebContentInterceptor interceptor = new WebContentInterceptor();
|
||||
interceptor.addCacheMapping(CacheControl.maxAge(60, TimeUnit.SECONDS)
|
||||
.noTransform()
|
||||
.mustRevalidate(), "/login/*");
|
||||
registry.addInterceptor(interceptor);
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.datetime;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.format.datetime.DateFormatter;
|
||||
import org.springframework.format.datetime.DateFormatterRegistrar;
|
||||
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
|
||||
import org.springframework.format.number.NumberFormatAnnotationFormatterFactory;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Configuration
|
||||
public class DateTimeConfig extends WebMvcConfigurationSupport {
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public FormattingConversionService mvcConversionService() {
|
||||
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);
|
||||
|
||||
conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
|
||||
|
||||
DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
|
||||
dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
|
||||
dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"));
|
||||
dateTimeRegistrar.registerFormatters(conversionService);
|
||||
|
||||
DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
|
||||
dateRegistrar.setFormatter(new DateFormatter("dd.MM.yyyy"));
|
||||
dateRegistrar.registerFormatters(conversionService);
|
||||
|
||||
return conversionService;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.datetime;
|
||||
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
@RestController
|
||||
public class DateTimeController {
|
||||
|
||||
@PostMapping("/date")
|
||||
public void date(@RequestParam("date") @DateTimeFormat(pattern = "dd.MM.yyyy") Date date) {
|
||||
// ...
|
||||
}
|
||||
|
||||
@PostMapping("/localdate")
|
||||
public void localDate(@RequestParam("localDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate localDate) {
|
||||
// ...
|
||||
}
|
||||
|
||||
@PostMapping("/localdatetime")
|
||||
public void dateTime(@RequestParam("localDateTime") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime localDateTime) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.matrix.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
@Configuration
|
||||
public class MatrixWebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void configurePathMatch(PathMatchConfigurer configurer) {
|
||||
final UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
urlPathHelper.setRemoveSemicolonContent(false);
|
||||
|
||||
configurer.setUrlPathHelper(urlPathHelper);
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.baeldung.matrix.controller;
|
||||
|
||||
import com.baeldung.matrix.model.Company;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Controller
|
||||
public class CompanyController {
|
||||
|
||||
Map<Long, Company> companyMap = new HashMap<>();
|
||||
|
||||
@RequestMapping(value = "/company", method = RequestMethod.GET)
|
||||
public ModelAndView showForm() {
|
||||
return new ModelAndView("companyHome", "company", new Company());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/company/{Id}", produces = { "application/json", "application/xml" }, method = RequestMethod.GET)
|
||||
public @ResponseBody Company getCompanyById(@PathVariable final long Id) {
|
||||
return companyMap.get(Id);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/addCompany", method = RequestMethod.POST)
|
||||
public String submit(@ModelAttribute("company") final Company company, final BindingResult result, final ModelMap model) {
|
||||
if (result.hasErrors()) {
|
||||
return "error";
|
||||
}
|
||||
model.addAttribute("name", company.getName());
|
||||
model.addAttribute("id", company.getId());
|
||||
|
||||
companyMap.put(company.getId(), company);
|
||||
|
||||
return "companyView";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/companyEmployee/{company}/employeeData/{employee}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, String>> getEmployeeDataFromCompany(@MatrixVariable(pathVar = "employee") final Map<String, String> matrixVars) {
|
||||
return new ResponseEntity<>(matrixVars, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/companyData/{company}/employeeData/{employee}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, String>> getCompanyName(@MatrixVariable(value = "name", pathVar = "company") final String name) {
|
||||
final Map<String, String> result = new HashMap<String, String>();
|
||||
result.put("name", name);
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package com.baeldung.matrix.controller;
|
||||
|
||||
|
||||
import com.baeldung.matrix.model.Employee;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@SessionAttributes("employees")
|
||||
@Controller
|
||||
public class EmployeeController {
|
||||
|
||||
public Map<Long, Employee> employeeMap = new HashMap<>();
|
||||
|
||||
@ModelAttribute("employees")
|
||||
public void initEmployees() {
|
||||
employeeMap.put(1L, new Employee(1L, "John", "223334411", "rh"));
|
||||
employeeMap.put(2L, new Employee(2L, "Peter", "22001543", "informatics"));
|
||||
employeeMap.put(3L, new Employee(3L, "Mike", "223334411", "admin"));
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/employee", method = RequestMethod.GET)
|
||||
public ModelAndView showForm() {
|
||||
return new ModelAndView("employeeHome", "employee", new Employee());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/employee/{Id}", produces = { "application/json", "application/xml" }, method = RequestMethod.GET)
|
||||
public @ResponseBody Employee getEmployeeById(@PathVariable final long Id) {
|
||||
return employeeMap.get(Id);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/addEmployee", method = RequestMethod.POST)
|
||||
public String submit(@ModelAttribute("employee") final Employee employee, final BindingResult result, final ModelMap model) {
|
||||
if (result.hasErrors()) {
|
||||
return "error";
|
||||
}
|
||||
model.addAttribute("name", employee.getName());
|
||||
model.addAttribute("contactNumber", employee.getContactNumber());
|
||||
model.addAttribute("workingArea", employee.getWorkingArea());
|
||||
model.addAttribute("id", employee.getId());
|
||||
|
||||
employeeMap.put(employee.getId(), employee);
|
||||
|
||||
return "employeeView";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/employees/{name}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public ResponseEntity<List<Employee>> getEmployeeByNameAndBeginContactNumber(@PathVariable final String name, @MatrixVariable final String beginContactNumber) {
|
||||
final List<Employee> employeesList = new ArrayList<Employee>();
|
||||
for (final Map.Entry<Long, Employee> employeeEntry : employeeMap.entrySet()) {
|
||||
final Employee employee = employeeEntry.getValue();
|
||||
if (employee.getName().equalsIgnoreCase(name) && employee.getContactNumber().startsWith(beginContactNumber)) {
|
||||
employeesList.add(employee);
|
||||
}
|
||||
}
|
||||
return new ResponseEntity<>(employeesList, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/employeesContacts/{contactNumber}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public ResponseEntity<List<Employee>> getEmployeeBycontactNumber(@MatrixVariable(required = true) final String contactNumber) {
|
||||
final List<Employee> employeesList = new ArrayList<Employee>();
|
||||
for (final Map.Entry<Long, Employee> employeeEntry : employeeMap.entrySet()) {
|
||||
final Employee employee = employeeEntry.getValue();
|
||||
if (employee.getContactNumber().equalsIgnoreCase(contactNumber)) {
|
||||
employeesList.add(employee);
|
||||
}
|
||||
}
|
||||
return new ResponseEntity<>(employeesList, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "employeeData/{employee}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public ResponseEntity<Map<String, String>> getEmployeeData(@MatrixVariable final Map<String, String> matrixVars) {
|
||||
return new ResponseEntity<>(matrixVars, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "employeeArea/{workingArea}", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public ResponseEntity<List<Employee>> getEmployeeByWorkingArea(@MatrixVariable final Map<String, LinkedList<String>> matrixVars) {
|
||||
final List<Employee> employeesList = new ArrayList<Employee>();
|
||||
final LinkedList<String> workingArea = matrixVars.get("workingArea");
|
||||
for (final Map.Entry<Long, Employee> employeeEntry : employeeMap.entrySet()) {
|
||||
final Employee employee = employeeEntry.getValue();
|
||||
for (final String area : workingArea) {
|
||||
if (employee.getWorkingArea().equalsIgnoreCase(area)) {
|
||||
employeesList.add(employee);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ResponseEntity<>(employeesList, HttpStatus.OK);
|
||||
}
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.matrix.model;
|
||||
|
||||
public class Company {
|
||||
|
||||
private long id;
|
||||
private String name;
|
||||
|
||||
public Company() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Company(final long id, final String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Company [id=" + id + ", name=" + name + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.baeldung.matrix.model;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@XmlRootElement
|
||||
public class Employee {
|
||||
|
||||
private long id;
|
||||
private String name;
|
||||
private String contactNumber;
|
||||
private String workingArea;
|
||||
|
||||
public Employee() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Employee(final long id, final String name, final String contactNumber, final String workingArea) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.contactNumber = contactNumber;
|
||||
this.workingArea = workingArea;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getContactNumber() {
|
||||
return contactNumber;
|
||||
}
|
||||
|
||||
public void setContactNumber(final String contactNumber) {
|
||||
this.contactNumber = contactNumber;
|
||||
}
|
||||
|
||||
public String getWorkingArea() {
|
||||
return workingArea;
|
||||
}
|
||||
|
||||
public void setWorkingArea(final String workingArea) {
|
||||
this.workingArea = workingArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Employee [id=" + id + ", name=" + name + ", contactNumber=" + contactNumber + ", workingArea=" + workingArea + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.multiparttesting;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@RestController
|
||||
public class MultipartPostRequestController {
|
||||
|
||||
@PostMapping(path = "/upload")
|
||||
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
|
||||
return file.isEmpty() ? new ResponseEntity<String>(HttpStatus.NOT_FOUND) : new ResponseEntity<String>(HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung.pathvariable.dottruncated;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
|
||||
@Configuration
|
||||
public class CustomWebMvcConfigurationSupport extends WebMvcConfigurationSupport {
|
||||
|
||||
@Override
|
||||
protected PathMatchConfigurer getPathMatchConfigurer() {
|
||||
PathMatchConfigurer pathMatchConfigurer = super.getPathMatchConfigurer();
|
||||
pathMatchConfigurer.setUseSuffixPatternMatch(false);
|
||||
|
||||
return pathMatchConfigurer;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.pathvariable.dottruncated;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/site")
|
||||
public class SiteController {
|
||||
|
||||
@GetMapping("/{firstValue}/{secondValue}")
|
||||
public String requestWithError(@PathVariable("firstValue") String firstValue,
|
||||
@PathVariable("secondValue") String secondValue) {
|
||||
|
||||
return firstValue + " - " + secondValue;
|
||||
}
|
||||
|
||||
@GetMapping("/{firstValue}/{secondValue:.+}")
|
||||
public String requestWithRegex(@PathVariable("firstValue") String firstValue,
|
||||
@PathVariable("secondValue") String secondValue) {
|
||||
|
||||
return firstValue + " - " + secondValue;
|
||||
}
|
||||
|
||||
@GetMapping("/{firstValue}/{secondValue}/")
|
||||
public String requestWithSlash(@PathVariable("firstValue") String firstValue,
|
||||
@PathVariable("secondValue") String secondValue) {
|
||||
|
||||
return firstValue + " - " + secondValue;
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package com.baeldung.pathvariable;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@RestController
|
||||
public class PathVariableAnnotationController {
|
||||
@GetMapping("/api/employees/{id}")
|
||||
@ResponseBody
|
||||
public String getEmployeesById(@PathVariable String id) {
|
||||
return "ID: " + id;
|
||||
}
|
||||
|
||||
@GetMapping("/api/employeeswithvariable/{id}")
|
||||
@ResponseBody
|
||||
public String getEmployeesByIdWithVariableName(@PathVariable("id") String employeeId) {
|
||||
return "ID: " + employeeId;
|
||||
}
|
||||
|
||||
@GetMapping("/api/employees/{id}/{name}")
|
||||
@ResponseBody
|
||||
public String getEmployeesByIdAndName(@PathVariable String id, @PathVariable String name) {
|
||||
return "ID: " + id + ", name: " + name;
|
||||
}
|
||||
|
||||
@GetMapping("/api/employeeswithmapvariable/{id}/{name}")
|
||||
@ResponseBody
|
||||
public String getEmployeesByIdAndNameWithMapVariable(@PathVariable Map<String, String> pathVarsMap) {
|
||||
String id = pathVarsMap.get("id");
|
||||
String name = pathVarsMap.get("name");
|
||||
if (id != null && name != null) {
|
||||
return "ID: " + id + ", name: " + name;
|
||||
} else {
|
||||
return "Missing Parameters";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(value = { "/api/employeeswithrequired", "/api/employeeswithrequired/{id}" })
|
||||
@ResponseBody
|
||||
public String getEmployeesByIdWithRequired(@PathVariable String id) {
|
||||
return "ID: " + id;
|
||||
}
|
||||
|
||||
@GetMapping(value = { "/api/employeeswithrequiredfalse", "/api/employeeswithrequiredfalse/{id}" })
|
||||
@ResponseBody
|
||||
public String getEmployeesByIdWithRequiredFalse(@PathVariable(required = false) String id) {
|
||||
if (id != null) {
|
||||
return "ID: " + id;
|
||||
} else {
|
||||
return "ID missing";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(value = { "/api/employeeswithoptional", "/api/employeeswithoptional/{id}" })
|
||||
@ResponseBody
|
||||
public String getEmployeesByIdWithOptional(@PathVariable Optional<String> id) {
|
||||
if (id.isPresent()) {
|
||||
return "ID: " + id.get();
|
||||
} else {
|
||||
return "ID missing";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(value = { "/api/defaultemployeeswithoptional", "/api/defaultemployeeswithoptional/{id}" })
|
||||
@ResponseBody
|
||||
public String getDefaultEmployeesByIdWithOptional(@PathVariable Optional<String> id) {
|
||||
if (id.isPresent()) {
|
||||
return "ID: " + id.get();
|
||||
} else {
|
||||
return "ID: Default Employee";
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(value = { "/api/employeeswithmap/{id}", "/api/employeeswithmap" })
|
||||
@ResponseBody
|
||||
public String getEmployeesByIdWithMap(@PathVariable Map<String, String> pathVarsMap) {
|
||||
String id = pathVarsMap.get("id");
|
||||
if (id != null) {
|
||||
return "ID: " + id;
|
||||
} else {
|
||||
return "ID missing";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Hello World
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/mvc
|
||||
http://www.springframework.org/schema/mvc/spring-mvc.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<!-- <mvc:annotation-driven/>-->
|
||||
|
||||
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
|
||||
<property name="prefix">
|
||||
<value>/WEB-INF/view/</value>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<value>.jsp</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<context:component-scan base-package="com.baeldung"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,31 @@
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
|
||||
pageEncoding="ISO-8859-1" %>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Form Example - Register a Company</title>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Welcome, Enter The Company Details</h3>
|
||||
|
||||
<form:form method="POST" action="/spring-mvc-java/addCompany"
|
||||
modelAttribute="company">
|
||||
<table>
|
||||
<tr>
|
||||
<td><form:label path="name">Name</form:label></td>
|
||||
<td><form:input path="name"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="id">Id</form:label></td>
|
||||
<td><form:input path="id"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="submit" value="Submit"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form:form>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,20 @@
|
||||
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
|
||||
<html>
|
||||
<head>
|
||||
<title>Spring MVC Form Handling</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Submitted Company Information</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name :</td>
|
||||
<td>${name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID :</td>
|
||||
<td>${id}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||
<title>Form Example - Register an Employee</title>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Welcome, Enter The Employee Details</h3>
|
||||
|
||||
<form:form method="POST" action="/spring-mvc-basics/addEmployee" modelAttribute="employee">
|
||||
<table>
|
||||
<tr>
|
||||
<td><form:label path="name">Name</form:label></td>
|
||||
<td><form:input path="name" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="id">Id</form:label></td>
|
||||
<td><form:input path="id" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="contactNumber">Contact Number</form:label></td>
|
||||
<td><form:input path="contactNumber" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><form:label path="workingArea">Working Area</form:label></td>
|
||||
<td><form:input path="workingArea" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="submit" value="Submit" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form:form>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
|
||||
<html>
|
||||
<head>
|
||||
<title>Spring MVC Form Handling</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Submitted Employee Information</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Name :</td>
|
||||
<td>${name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ID :</td>
|
||||
<td>${id}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Contact Number :</td>
|
||||
<td>${contactNumber}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee"
|
||||
xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
|
||||
<display-name>Spring MVC Application 2</display-name>
|
||||
<!-- Add Spring MVC DispatcherServlet as front controller -->
|
||||
<servlet>
|
||||
<servlet-name>mvc</servlet-name>
|
||||
<servlet-class>
|
||||
org.springframework.web.servlet.DispatcherServlet
|
||||
</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>/WEB-INF/mvc-servlet.xml</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>mvc</servlet-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package com.baeldung.cache;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.http.HttpHeaders.IF_UNMODIFIED_SINCE;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = {CacheWebConfig.class, CacheWebConfig.class})
|
||||
public class CacheControlControllerIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext wac;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenResponseBody_thenReturnCacheHeader() throws Exception {
|
||||
this.mockMvc.perform(MockMvcRequestBuilders.get("/hello/baeldung"))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andExpect(MockMvcResultMatchers.header()
|
||||
.string("Cache-Control","max-age=60, must-revalidate, no-transform"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenViewName_thenReturnCacheHeader() throws Exception {
|
||||
this.mockMvc.perform(MockMvcRequestBuilders.get("/home/baeldung"))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andExpect(MockMvcResultMatchers.header().string("Cache-Control","max-age=60, must-revalidate, no-transform"))
|
||||
.andExpect(MockMvcResultMatchers.view().name("home"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenStaticResources_thenReturnCacheHeader() throws Exception {
|
||||
this.mockMvc.perform(MockMvcRequestBuilders.get("/resources/hello.css"))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andExpect(MockMvcResultMatchers.header().string("Cache-Control","max-age=60, must-revalidate, no-transform"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenInterceptor_thenReturnCacheHeader() throws Exception {
|
||||
this.mockMvc.perform(MockMvcRequestBuilders.get("/login/baeldung"))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andExpect(MockMvcResultMatchers.header().string("Cache-Control","max-age=60, must-revalidate, no-transform"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenValidate_thenReturnCacheHeader() throws Exception {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add(IF_UNMODIFIED_SINCE, "Tue, 04 Feb 2020 19:57:25 GMT");
|
||||
this.mockMvc.perform(MockMvcRequestBuilders.get("/productInfo/baeldung").headers(headers))
|
||||
.andDo(MockMvcResultHandlers.print())
|
||||
.andExpect(MockMvcResultMatchers.status().is(304));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.matrix;
|
||||
|
||||
import com.baeldung.matrix.config.MatrixWebConfig;
|
||||
import com.baeldung.matrix.controller.EmployeeController;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = { MatrixWebConfig.class, EmployeeController.class })
|
||||
public class EmployeeMvcIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext webAppContext;
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenEmployeeGETisPerformed_thenRetrievedStatusAndViewNameAndAttributeAreCorrect() throws Exception {
|
||||
mockMvc.perform(get("/employee")).andExpect(status().isOk()).andExpect(view().name("employeeHome")).andExpect(model().attributeExists("employee")).andDo(print());
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.baeldung.matrix;
|
||||
|
||||
import com.baeldung.matrix.config.MatrixWebConfig;
|
||||
import com.baeldung.matrix.controller.EmployeeController;
|
||||
import com.baeldung.matrix.model.Employee;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = { MatrixWebConfig.class, EmployeeController.class })
|
||||
public class EmployeeNoMvcIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private EmployeeController employeeController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
employeeController.initEmployees();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Test
|
||||
public void whenInitEmployees_thenVerifyValuesInitiation() {
|
||||
Employee employee1 = employeeController.employeeMap.get(1L);
|
||||
Employee employee2 = employeeController.employeeMap.get(2L);
|
||||
Employee employee3 = employeeController.employeeMap.get(3L);
|
||||
|
||||
Assert.assertTrue(employee1.getId() == 1L);
|
||||
Assert.assertTrue(employee1.getName().equals("John"));
|
||||
Assert.assertTrue(employee1.getContactNumber().equals("223334411"));
|
||||
Assert.assertTrue(employee1.getWorkingArea().equals("rh"));
|
||||
|
||||
Assert.assertTrue(employee2.getId() == 2L);
|
||||
Assert.assertTrue(employee2.getName().equals("Peter"));
|
||||
Assert.assertTrue(employee2.getContactNumber().equals("22001543"));
|
||||
Assert.assertTrue(employee2.getWorkingArea().equals("informatics"));
|
||||
|
||||
Assert.assertTrue(employee3.getId() == 3L);
|
||||
Assert.assertTrue(employee3.getName().equals("Mike"));
|
||||
Assert.assertTrue(employee3.getContactNumber().equals("223334411"));
|
||||
Assert.assertTrue(employee3.getWorkingArea().equals("admin"));
|
||||
}
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
package com.baeldung.multipart.file;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public class ConvertMultipartFileUnitTest {
|
||||
|
||||
/**
|
||||
* Example of converting a {@link MultipartFile} to a {@link File} using {@link MultipartFile#getBytes()}.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void whenGetBytes_thenOK() throws IOException {
|
||||
MultipartFile multipartFile = new MockMultipartFile("sourceFile.tmp", "Hello World".getBytes());
|
||||
|
||||
File file = new File("src/main/resources/targetFile.tmp");
|
||||
|
||||
try (OutputStream os = new FileOutputStream(file)) {
|
||||
os.write(multipartFile.getBytes());
|
||||
}
|
||||
|
||||
assertThat(FileUtils.readFileToString(new File("src/main/resources/targetFile.tmp"), "UTF-8")).isEqualTo("Hello World");
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of converting a {@link MultipartFile} to a {@link File} using {@link MultipartFile#getInputStream()}.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void whenGetInputStream_thenOK() throws IOException {
|
||||
MultipartFile multipartFile = new MockMultipartFile("sourceFile.tmp", "Hello World".getBytes());
|
||||
|
||||
InputStream initialStream = multipartFile.getInputStream();
|
||||
byte[] buffer = new byte[initialStream.available()];
|
||||
initialStream.read(buffer);
|
||||
|
||||
File targetFile = new File("src/main/resources/targetFile.tmp");
|
||||
|
||||
try (OutputStream outStream = new FileOutputStream(targetFile)) {
|
||||
outStream.write(buffer);
|
||||
}
|
||||
|
||||
assertThat(FileUtils.readFileToString(new File("src/main/resources/targetFile.tmp"), "UTF-8")).isEqualTo("Hello World");
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of converting a {@link MultipartFile} to a {@link File} using {@link MultipartFile#transferTo(File)}.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void whenTransferTo_thenOK() throws IllegalStateException, IOException {
|
||||
MultipartFile multipartFile = new MockMultipartFile("sourceFile.tmp", "Hello World".getBytes());
|
||||
|
||||
File file = new File("src/main/resources/targetFile.tmp");
|
||||
|
||||
multipartFile.transferTo(file);
|
||||
|
||||
assertThat(FileUtils.readFileToString(new File("src/main/resources/targetFile.tmp"), "UTF-8")).isEqualTo("Hello World");
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.multiparttesting;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import com.baeldung.matrix.config.MatrixWebConfig;
|
||||
|
||||
@WebAppConfiguration
|
||||
@ContextConfiguration(classes = { MatrixWebConfig.class, MultipartPostRequestController.class })
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MultipartPostRequestControllerUnitTest {
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
@Test
|
||||
public void whenFileUploaded_thenVerifyStatus() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile("file", "hello.txt", MediaType.TEXT_PLAIN_VALUE, "Hello, World!".getBytes());
|
||||
|
||||
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
|
||||
mockMvc.perform(multipart("/upload").file(file)).andExpect(status().isOk());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
@@ -0,0 +1,16 @@
|
||||
## Spring MVC with Java Configuration
|
||||
|
||||
This module contains articles about Spring MVC with Java configuration
|
||||
|
||||
### The Course
|
||||
|
||||
The "REST With Spring" Classes: https://bit.ly/restwithspring
|
||||
|
||||
### Relevant Articles:
|
||||
- [Integration Testing in Spring](https://www.baeldung.com/integration-testing-in-spring)
|
||||
- [File Upload with Spring MVC](https://www.baeldung.com/spring-file-upload)
|
||||
- [Introduction to HtmlUnit](https://www.baeldung.com/htmlunit)
|
||||
- [Upload and Display Excel Files with Spring MVC](https://www.baeldung.com/spring-mvc-excel-files)
|
||||
- [web.xml vs Initializer with Spring](https://www.baeldung.com/spring-xml-vs-java-config)
|
||||
- [A Java Web Application Without a web.xml](https://www.baeldung.com/java-web-app-without-web-xml)
|
||||
- [Accessing Spring MVC Model Objects in JavaScript](https://www.baeldung.com/spring-mvc-model-objects-js)
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,270 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-mvc-java</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>spring-mvc-java</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../parent-boot-2</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>${javax.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet.jsp</groupId>
|
||||
<artifactId>javax.servlet.jsp-api</artifactId>
|
||||
<version>${javax-servlet-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-jasper</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- common -->
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>${htmlunit.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
<version>${commons-fileupload.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Thymeleaf -->
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-spring4</artifactId>
|
||||
<version>${thymeleaf.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>${thymeleaf.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>${json-path.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- excel -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Validation -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<version>${hibernate-validator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>javax.el</artifactId>
|
||||
<version>${javax.el.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>spring-mvc-java</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>${maven-resources-plugin.version}</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>${maven-war-plugin.version}</version>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.codehaus.cargo</groupId>
|
||||
<artifactId>cargo-maven2-plugin</artifactId>
|
||||
<version>${cargo-maven2-plugin.version}</version>
|
||||
<configuration>
|
||||
<wait>true</wait>
|
||||
<container>
|
||||
<containerId>jetty8x</containerId>
|
||||
<type>embedded</type>
|
||||
<systemProperties>
|
||||
<!-- <provPersistenceTarget>cargo</provPersistenceTarget> -->
|
||||
</systemProperties>
|
||||
</container>
|
||||
<configuration>
|
||||
<properties>
|
||||
<cargo.servlet.port>8082</cargo.servlet.port>
|
||||
</properties>
|
||||
</configuration>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*IntTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*LiveTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.cargo</groupId>
|
||||
<artifactId>cargo-maven2-plugin</artifactId>
|
||||
<configuration>
|
||||
<wait>false</wait>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>start-server</id>
|
||||
<phase>pre-integration-test</phase>
|
||||
<goals>
|
||||
<goal>start</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>stop-server</id>
|
||||
<phase>post-integration-test</phase>
|
||||
<goals>
|
||||
<goal>stop</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
|
||||
|
||||
<!-- persistence -->
|
||||
<hibernate.version>6.0.10.Final</hibernate.version>
|
||||
<mysql-connector-java.version>5.1.40</mysql-connector-java.version>
|
||||
|
||||
<!-- various -->
|
||||
<hibernate-validator.version>6.0.10.Final</hibernate-validator.version>
|
||||
|
||||
<!-- util -->
|
||||
<guava.version>19.0</guava.version>
|
||||
<commons-lang3.version>3.5</commons-lang3.version>
|
||||
<commons-fileupload.version>1.3.2</commons-fileupload.version>
|
||||
<commons-io.version>2.5</commons-io.version>
|
||||
<commons-fileupload.version>1.4</commons-fileupload.version>
|
||||
<jsonpath.version>2.2.0</jsonpath.version>
|
||||
|
||||
<!-- testing -->
|
||||
<httpcore.version>4.4.5</httpcore.version>
|
||||
<httpclient.version>4.5.2</httpclient.version>
|
||||
<rest-assured.version>3.0.7</rest-assured.version>
|
||||
<net.sourceforge.htmlunit>2.23</net.sourceforge.htmlunit>
|
||||
|
||||
<!-- maven plugins -->
|
||||
<maven-war-plugin.version>3.2.2</maven-war-plugin.version>
|
||||
<maven-resources-plugin.version>2.7</maven-resources-plugin.version>
|
||||
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
|
||||
<maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
|
||||
|
||||
<!-- AspectJ -->
|
||||
<aspectj.version>1.9.1</aspectj.version>
|
||||
|
||||
<!-- excel -->
|
||||
<poi.version>3.16-beta1</poi.version>
|
||||
|
||||
<javax.el.version>3.0.1-b09</javax.el.version>
|
||||
<javax.version>4.0.1</javax.version>
|
||||
<javax-servlet-api.version>2.3.3</javax-servlet-api.version>
|
||||
<htmlunit.version>2.32</htmlunit.version>
|
||||
<json-path.version>2.4.0</json-path.version>
|
||||
<start-class>com.baeldung.SpringMVCApplication</start-class>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringMVCApplication extends SpringBootServletInitializer {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringMVCApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.accessparamsjs;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class App {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(App.class, args);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.accessparamsjs;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sample rest controller for the tutorial article
|
||||
* "Access Spring MVC Model object in JavaScript".
|
||||
*
|
||||
* @author Andrew Shcherbakov
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
public class Controller {
|
||||
|
||||
/**
|
||||
* Define two model objects (one integer and one string) and pass them to the view.
|
||||
*
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping("/index")
|
||||
public ModelAndView thymeleafView(Map<String, Object> model) {
|
||||
model.put("number", 1234);
|
||||
model.put("message", "Hello from Spring MVC");
|
||||
return new ModelAndView("thymeleaf/index");
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.cache;
|
||||
|
||||
import com.baeldung.model.Book;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class BookService {
|
||||
|
||||
@Cacheable(value="books", keyGenerator="customKeyGenerator")
|
||||
public List<Book> getBooks() {
|
||||
List<Book> books = new ArrayList<Book>();
|
||||
books.add(new Book(1, "The Counterfeiters", "André Gide"));
|
||||
books.add(new Book(2, "Peer Gynt and Hedda Gabler", "Henrik Ibsen"));
|
||||
return books;
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.cache;
|
||||
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class CustomKeyGenerator implements KeyGenerator {
|
||||
|
||||
public Object generate(Object target, Method method, Object... params) {
|
||||
return target.getClass().getSimpleName() + "_" + method.getName() + "_"
|
||||
+ StringUtils.arrayToDelimitedString(params, "_");
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
package com.baeldung.excel;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
|
||||
import org.apache.poi.xssf.usermodel.XSSFColor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFFont;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFont;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.ss.usermodel.DateUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class ExcelPOIHelper {
|
||||
|
||||
public Map<Integer, List<MyCell>> readExcel(String fileLocation) throws IOException {
|
||||
|
||||
Map<Integer, List<MyCell>> data = new HashMap<>();
|
||||
FileInputStream fis = new FileInputStream(new File(fileLocation));
|
||||
|
||||
if (fileLocation.endsWith(".xls")) {
|
||||
data = readHSSFWorkbook(fis);
|
||||
} else if (fileLocation.endsWith(".xlsx")) {
|
||||
data = readXSSFWorkbook(fis);
|
||||
}
|
||||
|
||||
int maxNrCols = data.values().stream()
|
||||
.mapToInt(List::size)
|
||||
.max()
|
||||
.orElse(0);
|
||||
|
||||
data.values().stream()
|
||||
.filter(ls -> ls.size() < maxNrCols)
|
||||
.forEach(ls -> {
|
||||
IntStream.range(ls.size(), maxNrCols)
|
||||
.forEach(i -> ls.add(new MyCell("")));
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private String readCellContent(Cell cell) {
|
||||
String content;
|
||||
switch (cell.getCellTypeEnum()) {
|
||||
case STRING:
|
||||
content = cell.getStringCellValue();
|
||||
break;
|
||||
case NUMERIC:
|
||||
if (DateUtil.isCellDateFormatted(cell)) {
|
||||
content = cell.getDateCellValue() + "";
|
||||
} else {
|
||||
content = cell.getNumericCellValue() + "";
|
||||
}
|
||||
break;
|
||||
case BOOLEAN:
|
||||
content = cell.getBooleanCellValue() + "";
|
||||
break;
|
||||
case FORMULA:
|
||||
content = cell.getCellFormula() + "";
|
||||
break;
|
||||
default:
|
||||
content = "";
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private Map<Integer, List<MyCell>> readHSSFWorkbook(FileInputStream fis) throws IOException {
|
||||
Map<Integer, List<MyCell>> data = new HashMap<>();
|
||||
HSSFWorkbook workbook = null;
|
||||
try {
|
||||
workbook = new HSSFWorkbook(fis);
|
||||
|
||||
HSSFSheet sheet = workbook.getSheetAt(0);
|
||||
for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
|
||||
HSSFRow row = sheet.getRow(i);
|
||||
data.put(i, new ArrayList<>());
|
||||
if (row != null) {
|
||||
for (int j = 0; j < row.getLastCellNum(); j++) {
|
||||
HSSFCell cell = row.getCell(j);
|
||||
if (cell != null) {
|
||||
HSSFCellStyle cellStyle = cell.getCellStyle();
|
||||
|
||||
MyCell myCell = new MyCell();
|
||||
|
||||
HSSFColor bgColor = cellStyle.getFillForegroundColorColor();
|
||||
if (bgColor != null) {
|
||||
short[] rgbColor = bgColor.getTriplet();
|
||||
myCell.setBgColor("rgb(" + rgbColor[0] + "," + rgbColor[1] + "," + rgbColor[2] + ")");
|
||||
}
|
||||
HSSFFont font = cell.getCellStyle()
|
||||
.getFont(workbook);
|
||||
myCell.setTextSize(font.getFontHeightInPoints() + "");
|
||||
if (font.getBold()) {
|
||||
myCell.setTextWeight("bold");
|
||||
}
|
||||
HSSFColor textColor = font.getHSSFColor(workbook);
|
||||
if (textColor != null) {
|
||||
short[] rgbColor = textColor.getTriplet();
|
||||
myCell.setTextColor("rgb(" + rgbColor[0] + "," + rgbColor[1] + "," + rgbColor[2] + ")");
|
||||
}
|
||||
myCell.setContent(readCellContent(cell));
|
||||
data.get(i)
|
||||
.add(myCell);
|
||||
} else {
|
||||
data.get(i)
|
||||
.add(new MyCell(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (workbook != null) {
|
||||
workbook.close();
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private Map<Integer, List<MyCell>> readXSSFWorkbook(FileInputStream fis) throws IOException {
|
||||
XSSFWorkbook workbook = null;
|
||||
Map<Integer, List<MyCell>> data = new HashMap<>();
|
||||
try {
|
||||
|
||||
workbook = new XSSFWorkbook(fis);
|
||||
XSSFSheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
for (int i = sheet.getFirstRowNum(); i <= sheet.getLastRowNum(); i++) {
|
||||
XSSFRow row = sheet.getRow(i);
|
||||
data.put(i, new ArrayList<>());
|
||||
if (row != null) {
|
||||
for (int j = 0; j < row.getLastCellNum(); j++) {
|
||||
XSSFCell cell = row.getCell(j);
|
||||
if (cell != null) {
|
||||
XSSFCellStyle cellStyle = cell.getCellStyle();
|
||||
|
||||
MyCell myCell = new MyCell();
|
||||
XSSFColor bgColor = cellStyle.getFillForegroundColorColor();
|
||||
if (bgColor != null) {
|
||||
byte[] rgbColor = bgColor.getRGB();
|
||||
myCell.setBgColor("rgb(" + (rgbColor[0] < 0 ? (rgbColor[0] + 0xff) : rgbColor[0]) + "," + (rgbColor[1] < 0 ? (rgbColor[1] + 0xff) : rgbColor[1]) + "," + (rgbColor[2] < 0 ? (rgbColor[2] + 0xff) : rgbColor[2]) + ")");
|
||||
}
|
||||
XSSFFont font = cellStyle.getFont();
|
||||
myCell.setTextSize(font.getFontHeightInPoints() + "");
|
||||
if (font.getBold()) {
|
||||
myCell.setTextWeight("bold");
|
||||
}
|
||||
XSSFColor textColor = font.getXSSFColor();
|
||||
if (textColor != null) {
|
||||
byte[] rgbColor = textColor.getRGB();
|
||||
myCell.setTextColor("rgb(" + (rgbColor[0] < 0 ? (rgbColor[0] + 0xff) : rgbColor[0]) + "," + (rgbColor[1] < 0 ? (rgbColor[1] + 0xff) : rgbColor[1]) + "," + (rgbColor[2] < 0 ? (rgbColor[2] + 0xff) : rgbColor[2]) + ")");
|
||||
}
|
||||
myCell.setContent(readCellContent(cell));
|
||||
data.get(i)
|
||||
.add(myCell);
|
||||
} else {
|
||||
data.get(i)
|
||||
.add(new MyCell(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (workbook != null) {
|
||||
workbook.close();
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.baeldung.excel;
|
||||
|
||||
public class MyCell {
|
||||
private String content;
|
||||
private String textColor;
|
||||
private String bgColor;
|
||||
private String textSize;
|
||||
private String textWeight;
|
||||
|
||||
public MyCell() {
|
||||
}
|
||||
|
||||
public MyCell(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getTextColor() {
|
||||
return textColor;
|
||||
}
|
||||
|
||||
public void setTextColor(String textColor) {
|
||||
this.textColor = textColor;
|
||||
}
|
||||
|
||||
public String getBgColor() {
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
public void setBgColor(String bgColor) {
|
||||
this.bgColor = bgColor;
|
||||
}
|
||||
|
||||
public String getTextSize() {
|
||||
return textSize;
|
||||
}
|
||||
|
||||
public void setTextSize(String textSize) {
|
||||
this.textSize = textSize;
|
||||
}
|
||||
|
||||
public String getTextWeight() {
|
||||
return textWeight;
|
||||
}
|
||||
|
||||
public void setTextWeight(String textWeight) {
|
||||
this.textWeight = textWeight;
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.filters;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import java.io.IOException;
|
||||
|
||||
@WebFilter(urlPatterns = "/uppercase")
|
||||
public class EmptyParamFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
|
||||
FilterChain filterChain) throws IOException, ServletException {
|
||||
String inputString = servletRequest.getParameter("input");
|
||||
|
||||
if (inputString != null && inputString.matches("[A-Za-z0-9]+")) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
} else {
|
||||
servletResponse.getWriter().println("Missing input parameter");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.listeners;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.annotation.WebListener;
|
||||
|
||||
@WebListener
|
||||
public class AppListener implements ServletContextListener {
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent event) {
|
||||
ServletContext context = event.getServletContext();
|
||||
context.setAttribute("counter", 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent event) {
|
||||
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.listeners;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRequestEvent;
|
||||
import javax.servlet.ServletRequestListener;
|
||||
import javax.servlet.annotation.WebListener;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@WebListener
|
||||
public class RequestListener implements ServletRequestListener {
|
||||
|
||||
@Override
|
||||
public void requestInitialized(ServletRequestEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDestroyed(ServletRequestEvent event) {
|
||||
HttpServletRequest request = (HttpServletRequest)event.getServletRequest();
|
||||
if (!request.getServletPath().equals("/counter")) {
|
||||
ServletContext context = event.getServletContext();
|
||||
context.setAttribute("counter", (int)context.getAttribute("counter") + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.model;
|
||||
|
||||
public class Article {
|
||||
|
||||
public static final Article DEFAULT_ARTICLE = new Article(12);
|
||||
|
||||
private Integer id;
|
||||
|
||||
public Article(Integer articleId) {
|
||||
this.id = articleId;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Article [id=" + id + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.baeldung.model;
|
||||
|
||||
public class Book {
|
||||
|
||||
private int id;
|
||||
private String author;
|
||||
private String title;
|
||||
|
||||
public Book() {
|
||||
}
|
||||
|
||||
public Book(int id, String author, String title) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.model;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
public class FormDataWithFile {
|
||||
|
||||
private String name;
|
||||
private String email;
|
||||
private MultipartFile file;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public MultipartFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(MultipartFile file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.model;
|
||||
|
||||
public class Greeting {
|
||||
private int id;
|
||||
private String message;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.model;
|
||||
|
||||
public class User {
|
||||
private String firstname;
|
||||
private String lastname;
|
||||
private String emailId;
|
||||
|
||||
public String getFirstname() {
|
||||
return firstname;
|
||||
}
|
||||
|
||||
public void setFirstname(final String firstname) {
|
||||
this.firstname = firstname;
|
||||
}
|
||||
|
||||
public String getLastname() {
|
||||
return lastname;
|
||||
}
|
||||
|
||||
public void setLastname(final String lastname) {
|
||||
this.lastname = lastname;
|
||||
}
|
||||
|
||||
public String getEmailId() {
|
||||
return emailId;
|
||||
}
|
||||
|
||||
public void setEmailId(final String emailId) {
|
||||
this.emailId = emailId;
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.servlets;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
@WebServlet(urlPatterns = "/counter", name = "counterServlet")
|
||||
public class CounterServlet extends HttpServlet {
|
||||
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
int count = (int)request.getServletContext().getAttribute("counter");
|
||||
|
||||
out.println("Request counter: " + count);
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.servlets;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
@WebServlet(urlPatterns = "/uppercase", name = "uppercaseServlet")
|
||||
public class UppercaseServlet extends HttpServlet {
|
||||
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
String inputString = request.getParameter("input").toUpperCase();
|
||||
|
||||
PrintWriter out = response.getWriter();
|
||||
|
||||
out.println(inputString);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.spring.web.config;
|
||||
|
||||
import com.baeldung.cache.CustomKeyGenerator;
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCache;
|
||||
import org.springframework.cache.interceptor.KeyGenerator;
|
||||
import org.springframework.cache.support.SimpleCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@EnableCaching
|
||||
@Configuration
|
||||
public class ApplicationCacheConfig extends CachingConfigurerSupport {
|
||||
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
SimpleCacheManager cacheManager = new SimpleCacheManager();
|
||||
Cache booksCache = new ConcurrentMapCache("books");
|
||||
cacheManager.setCaches(Arrays.asList(booksCache));
|
||||
return cacheManager;
|
||||
}
|
||||
|
||||
@Bean("customKeyGenerator")
|
||||
public KeyGenerator keyGenerator() {
|
||||
return new CustomKeyGenerator();
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.spring.web.config;
|
||||
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRegistration;
|
||||
|
||||
import org.springframework.web.WebApplicationInitializer;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
public class MainWebAppInitializer implements WebApplicationInitializer {
|
||||
|
||||
private String TMP_FOLDER = "/tmp";
|
||||
private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024;
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext sc) throws ServletException {
|
||||
|
||||
ServletRegistration.Dynamic appServlet = sc.addServlet("mvc", new DispatcherServlet(
|
||||
new GenericWebApplicationContext()));
|
||||
|
||||
appServlet.setLoadOnStartup(1);
|
||||
|
||||
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(TMP_FOLDER,
|
||||
MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2);
|
||||
|
||||
appServlet.setMultipartConfig(multipartConfigElement);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
package com.baeldung.spring.web.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Description;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
import org.thymeleaf.spring4.SpringTemplateEngine;
|
||||
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
|
||||
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
|
||||
import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||
|
||||
import com.baeldung.excel.ExcelPOIHelper;
|
||||
|
||||
@EnableWebMvc
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = { "com.baeldung.web.controller" })
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
registry.addViewController("/").setViewName("index");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ViewResolver thymeleafViewResolver() {
|
||||
final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
|
||||
viewResolver.setTemplateEngine(templateEngine());
|
||||
viewResolver.setOrder(1);
|
||||
return viewResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ViewResolver viewResolver() {
|
||||
final InternalResourceViewResolver bean = new InternalResourceViewResolver();
|
||||
bean.setViewClass(JstlView.class);
|
||||
bean.setPrefix("/WEB-INF/view/");
|
||||
bean.setSuffix(".jsp");
|
||||
bean.setOrder(0);
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Description("Thymeleaf template resolver serving HTML 5")
|
||||
public ITemplateResolver templateResolver() {
|
||||
final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
|
||||
templateResolver.setPrefix("/WEB-INF/templates/");
|
||||
templateResolver.setSuffix(".html");
|
||||
templateResolver.setTemplateMode("HTML");
|
||||
return templateResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Description("Thymeleaf template engine with Spring integration")
|
||||
public SpringTemplateEngine templateEngine() {
|
||||
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
|
||||
templateEngine.setTemplateResolver(templateResolver());
|
||||
return templateEngine;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Description("Spring message resolver")
|
||||
public MessageSource messageSource() {
|
||||
final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
|
||||
messageSource.setBasename("messages");
|
||||
return messageSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extendMessageConverters(final List<HttpMessageConverter<?>> converters) {
|
||||
converters.add(byteArrayHttpMessageConverter());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
|
||||
final ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
|
||||
arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
|
||||
|
||||
return arrayHttpMessageConverter;
|
||||
}
|
||||
|
||||
private List<MediaType> getSupportedMediaTypes() {
|
||||
final List<MediaType> list = new ArrayList<MediaType>();
|
||||
list.add(MediaType.IMAGE_JPEG);
|
||||
list.add(MediaType.IMAGE_PNG);
|
||||
list.add(MediaType.APPLICATION_OCTET_STREAM);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configurePathMatch(final PathMatchConfigurer configurer) {
|
||||
final UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
urlPathHelper.setRemoveSemicolonContent(false);
|
||||
|
||||
configurer.setUrlPathHelper(urlPathHelper);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ExcelPOIHelper excelPOIHelper() {
|
||||
return new ExcelPOIHelper();
|
||||
}
|
||||
|
||||
@Bean(name = "multipartResolver")
|
||||
public CommonsMultipartResolver multipartResolver() {
|
||||
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
|
||||
multipartResolver.setMaxUploadSize(100000);
|
||||
return multipartResolver;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class BeanA {
|
||||
|
||||
@Autowired
|
||||
private BeanB b;
|
||||
|
||||
public BeanA() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.web;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class BeanB {
|
||||
|
||||
public BeanB() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import com.baeldung.excel.*;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Controller
|
||||
public class ExcelController {
|
||||
|
||||
private String fileLocation;
|
||||
|
||||
@Resource(name = "excelPOIHelper")
|
||||
private ExcelPOIHelper excelPOIHelper;
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/excelProcessing")
|
||||
public String getExcelProcessingPage() {
|
||||
return "excel";
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/uploadExcelFile")
|
||||
public String uploadFile(Model model, MultipartFile file) throws IOException {
|
||||
InputStream in = file.getInputStream();
|
||||
File currDir = new File(".");
|
||||
String path = currDir.getAbsolutePath();
|
||||
fileLocation = path.substring(0, path.length() - 1) + file.getOriginalFilename();
|
||||
FileOutputStream f = new FileOutputStream(fileLocation);
|
||||
int ch = 0;
|
||||
while ((ch = in.read()) != -1) {
|
||||
f.write(ch);
|
||||
}
|
||||
f.flush();
|
||||
f.close();
|
||||
model.addAttribute("message", "File: " + file.getOriginalFilename() + " has been uploaded successfully!");
|
||||
return "excel";
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/readPOI")
|
||||
public String readPOI(Model model) throws IOException {
|
||||
|
||||
if (fileLocation != null) {
|
||||
if (fileLocation.endsWith(".xlsx") || fileLocation.endsWith(".xls")) {
|
||||
Map<Integer, List<MyCell>> data = excelPOIHelper.readExcel(fileLocation);
|
||||
model.addAttribute("data", data);
|
||||
} else {
|
||||
model.addAttribute("message", "Not a valid excel file!");
|
||||
}
|
||||
} else {
|
||||
model.addAttribute("message", "File missing! Please upload an excel file.");
|
||||
}
|
||||
return "excel";
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.baeldung.model.FormDataWithFile;
|
||||
|
||||
@Controller
|
||||
public class FileUploadController {
|
||||
|
||||
@RequestMapping(value = "/fileUpload", method = RequestMethod.GET)
|
||||
public String displayForm() {
|
||||
|
||||
return "fileUploadForm";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
|
||||
public String submit(@RequestParam("file") final MultipartFile file, final ModelMap modelMap) {
|
||||
|
||||
modelMap.addAttribute("file", file);
|
||||
return "fileUploadView";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/uploadMultiFile", method = RequestMethod.POST)
|
||||
public String submit(@RequestParam("files") final MultipartFile[] files, final ModelMap modelMap) {
|
||||
|
||||
modelMap.addAttribute("files", files);
|
||||
return "fileUploadView";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/uploadFileWithAddtionalData", method = RequestMethod.POST)
|
||||
public String submit(@RequestParam final MultipartFile file, @RequestParam final String name, @RequestParam final String email, final ModelMap modelMap) {
|
||||
|
||||
modelMap.addAttribute("name", name);
|
||||
modelMap.addAttribute("email", email);
|
||||
modelMap.addAttribute("file", file);
|
||||
return "fileUploadView";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/uploadFileModelAttribute", method = RequestMethod.POST)
|
||||
public String submit(@ModelAttribute final FormDataWithFile formDataWithFile, final ModelMap modelMap) {
|
||||
|
||||
modelMap.addAttribute("formDataWithFile", formDataWithFile);
|
||||
return "fileUploadView";
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import com.baeldung.model.Greeting;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Controller
|
||||
public class GreetController {
|
||||
|
||||
@RequestMapping(value = "/homePage", method = RequestMethod.GET)
|
||||
public String index() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/greet", method = RequestMethod.GET, produces = "application/json")
|
||||
@ResponseBody
|
||||
public Greeting greet() {
|
||||
Greeting greeting = new Greeting();
|
||||
greeting.setId(1);
|
||||
greeting.setMessage("Hello World!!!");
|
||||
return greeting;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/greetWithPathVariable/{name}", method = RequestMethod.GET, produces = "application/json")
|
||||
@ResponseBody
|
||||
public Greeting greetWithPathVariable(@PathVariable("name") String name) {
|
||||
Greeting greeting = new Greeting();
|
||||
greeting.setId(1);
|
||||
greeting.setMessage("Hello World " + name + "!!!");
|
||||
return greeting;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/greetWithQueryVariable", method = RequestMethod.GET, produces = "application/json")
|
||||
@ResponseBody
|
||||
public Greeting greetWithQueryVariable(@RequestParam("name") String name) {
|
||||
Greeting greeting = new Greeting();
|
||||
greeting.setId(1);
|
||||
greeting.setMessage("Hello World " + name + "!!!");
|
||||
return greeting;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/greetWithPost", method = RequestMethod.POST, produces = "application/json")
|
||||
@ResponseBody
|
||||
public Greeting greetWithPost() {
|
||||
Greeting greeting = new Greeting();
|
||||
greeting.setId(1);
|
||||
greeting.setMessage("Hello World!!!");
|
||||
return greeting;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/greetWithPostAndFormData", method = RequestMethod.POST, produces = "application/json")
|
||||
@ResponseBody
|
||||
public Greeting greetWithPostAndFormData(@RequestParam("id") int id, @RequestParam("name") String name) {
|
||||
Greeting greeting = new Greeting();
|
||||
greeting.setId(id);
|
||||
greeting.setMessage("Hello World " + name + "!!!");
|
||||
return greeting;
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
@Controller
|
||||
public class ImageController {
|
||||
|
||||
@Autowired
|
||||
ServletContext servletContext;
|
||||
|
||||
@RequestMapping(value = "/image-byte-array", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
|
||||
public @ResponseBody byte[] getImageAsByteArray() throws IOException {
|
||||
final InputStream in = servletContext.getResourceAsStream("/WEB-INF/images/image-example.jpg");
|
||||
return IOUtils.toByteArray(in);
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Controller
|
||||
public class MultipartFileUploadStubController {
|
||||
|
||||
@PostMapping("/stub/multipart")
|
||||
public ResponseEntity<UploadResultResource> uploadFile(MultipartFile file, String text, String text1, String text2, MultipartFile upstream) {
|
||||
UploadResultResource result = new UploadResultResource(file, text, text1, text2, upstream);
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
|
||||
public static class UploadResultResource {
|
||||
|
||||
private final String file;
|
||||
private final String text;
|
||||
private final String text1;
|
||||
private final String text2;
|
||||
private final String upstream;
|
||||
|
||||
public UploadResultResource(MultipartFile file, String text, String text1, String text2, MultipartFile upstream) {
|
||||
this.file = format(file);
|
||||
this.text = text;
|
||||
this.text1 = text1;
|
||||
this.text2 = text2;
|
||||
this.upstream = format(upstream);
|
||||
}
|
||||
|
||||
private static String format(MultipartFile file) {
|
||||
return file == null ? null : file.getOriginalFilename() + " (size: " + file.getSize() + " bytes)";
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String getText1() {
|
||||
return text1;
|
||||
}
|
||||
|
||||
public String getText2() {
|
||||
return text2;
|
||||
}
|
||||
|
||||
public String getUpstream() {
|
||||
return upstream;
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class SampleController {
|
||||
@GetMapping("/sample")
|
||||
public String showForm() {
|
||||
return "sample";
|
||||
}
|
||||
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.web.controller;
|
||||
|
||||
import com.baeldung.model.User;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/")
|
||||
public class UserController {
|
||||
|
||||
@GetMapping("/")
|
||||
public String showForm(final Model model) {
|
||||
final User user = new User();
|
||||
user.setFirstname("John");
|
||||
user.setLastname("Roy");
|
||||
user.setEmailId("John.Roy@gmail.com");
|
||||
model.addAttribute("user", user);
|
||||
return "index";
|
||||
}
|
||||
|
||||
@PostMapping("/processForm")
|
||||
public String processForm(@ModelAttribute(value = "user") final User user, final Model model) {
|
||||
// Insert User into DB
|
||||
model.addAttribute("name", user.getFirstname() + " " + user.getLastname());
|
||||
return "hello";
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.web.controller.message;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/message")
|
||||
public class MessageController {
|
||||
|
||||
@RequestMapping(value = "/showForm", method = RequestMethod.GET)
|
||||
public String showForm() {
|
||||
return "message";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/processForm", method = RequestMethod.POST)
|
||||
public String processForm(@RequestParam("message") final String message, final Model model) {
|
||||
model.addAttribute("message", message);
|
||||
return "message";
|
||||
}
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.web.controller.optionalpathvars;
|
||||
|
||||
import static com.baeldung.model.Article.DEFAULT_ARTICLE;
|
||||
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.model.Article;
|
||||
|
||||
@RestController
|
||||
public class ArticleViewerController {
|
||||
|
||||
@RequestMapping(value = {"/article", "/article/{id}"})
|
||||
public Article getArticle(@PathVariable(name = "id") Integer articleId) {
|
||||
|
||||
if (articleId != null) {
|
||||
return new Article(articleId);
|
||||
} else {
|
||||
return DEFAULT_ARTICLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.web.controller.optionalpathvars;
|
||||
|
||||
import static com.baeldung.model.Article.DEFAULT_ARTICLE;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.model.Article;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "/mapParam")
|
||||
public class ArticleViewerWithMapParamController {
|
||||
|
||||
@RequestMapping(value = {"/article", "/article/{id}"})
|
||||
public Article getArticle(@PathVariable Map<String, String> pathVarsMap) {
|
||||
|
||||
String articleId = pathVarsMap.get("id");
|
||||
|
||||
if (articleId != null) {
|
||||
return new Article(Integer.valueOf(articleId));
|
||||
} else {
|
||||
return DEFAULT_ARTICLE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.web.controller.optionalpathvars;
|
||||
|
||||
import static com.baeldung.model.Article.DEFAULT_ARTICLE;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.model.Article;;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/optionalParam")
|
||||
public class ArticleViewerWithOptionalParamController {
|
||||
|
||||
@RequestMapping(value = {"/article", "/article/{id}"})
|
||||
public Article getArticle(@PathVariable(name = "id") Optional<Integer> optionalArticleId) {
|
||||
|
||||
if(optionalArticleId.isPresent()) {
|
||||
Integer articleId = optionalArticleId.get();
|
||||
return new Article(articleId);
|
||||
}else {
|
||||
return DEFAULT_ARTICLE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user