Java Web系列:Spring Boot 基础
Spring Boot 项目(参考1) 提供了一个类似ASP.NET MVC的默认模板一样的标准样板,直接集成了一系列的组件并使用了默认的配置。使用Spring Boot 不会降低学习成本,甚至增加了学习成本,但显著降低了使用成本并提高了开发效率。如果没有Spring基础不建议直接上手。
1.基础项目
这里只关注基于Maven的项目构建,使用Spring Boot CLI命令行工具和Gradle构建方式请参考官网。
(1)创建项目:
创建类型为quickstart的Maven项目,删除默认生成的.java文件保持默认的Maven目录即可。
(2)修改/ pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <groupId>com.example</groupId> 6 <artifactId>myproject</artifactId> 7 <version>0.0.1-SNAPSHOT</version> 8 <properties> 9 <java.version>1.8</java.version> 10 </properties> 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>1.3.1.RELEASE</version> 15 </parent> 16 <dependencies> 17 <dependency> 18 <groupId>org.springframework.boot</groupId> 19 <artifactId>spring-boot-starter-web</artifactId> 20 </dependency> 21 </dependencies> 22 </project>
(3)添加/src/main/sample/controller/ HomeController.java 文件:
1 package simple.controller; 2 3 import org.springframework.web.bind.annotation.*; 4 5 @RestController 6 public class HomeController { 7 8 @RequestMapping("/") 9 public String index() { 10 return "Hello World!"; 11 } 12 }
(4)添加/src/main/sample/ Application.java 文件:
1 package simple; 2 3 import org.springframework.boot.*; 4 import org.springframework.boot.autoconfigure.*; 5 import simple.controller.*; 6 7 @EnableAutoConfiguration 8 public class Application { 9 10 public static void main(String[] args) throws Exception { 11 SpringApplication.run(new Object[] { Application.class, HomeController.class }, args); 12 } 13 14 }
在浏览器中输入http://localhost:8080/,即可直接看到"Hello World"运行结果 。
2. 添加数据访问支持
(1)修改pom,添加 spring-boot-starter-data-jpa 和 h2 依赖:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <groupId>com.example</groupId> 6 <artifactId>myproject</artifactId> 7 <version>0.0.1-SNAPSHOT</version> 8 <properties> 9 <java.version>1.8</java.version> 10 </properties> 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>1.3.1.RELEASE</version> 15 </parent> 16 <dependencies> 17 <dependency> 18 <groupId>org.springframework.boot</groupId> 19 <artifactId>spring-boot-starter-web</artifactId> 20 </dependency> 21 <dependency> 22 <groupId>org.springframework.boot</groupId> 23 <artifactId>spring-boot-starter-data-jpa</artifactId> 24 </dependency> 25 <dependency> 26 <groupId>com.h2database</groupId> 27 <artifactId>h2</artifactId> 28 <scope>runtime</scope> 29 </dependency> 30 </dependencies> 31 </project>
如果需要在控制台查看生成SQL语句,可以添加/src/main/resources/application.properties
1 spring.h2.console.enabled=true 2 logging.level.org.hibernate.SQL=debug
(2)添加实体
添加User、Role、Category和Post实体。
User:
1 package simple.domain; 2 3 import java.util.*; 4 5 import javax.persistence.*; 6 7 @Entity 8 public class User { 9 @Id 10 @GeneratedValue 11 private Long id; 12 13 private String userName; 14 15 private String password; 16 17 private String Email; 18 19 @javax.persistence.Version 20 private Long Version; 21 22 @ManyToMany(cascade = CascadeType.ALL) 23 private List<Role> roles = new ArrayList<Role>(); 24 25 public Long getId() { 26 return id; 27 } 28 29 public void setId(Long id) { 30 this.id = id; 31 } 32 33 public String getUserName() { 34 return userName; 35 } 36 37 public void setUserName(String userName) { 38 this.userName = userName; 39 } 40 41 public String getPassword() { 42 return password; 43 } 44 45 public void setPassword(String password) { 46 this.password = password; 47 } 48 49 public String getEmail() { 50 return Email; 51 } 52 53 public void setEmail(String email) { 54 Email = email; 55 } 56 57 public List<Role> getRoles() { 58 return roles; 59 } 60 61 public void setRoles(List<Role> roles) { 62 this.roles = roles; 63 } 64 65 public Long getVersion() { 66 return Version; 67 } 68 69 public void setVersion(Long version) { 70 Version = version; 71 } 72 } View Code
Role:
1 package simple.domain; 2 3 import java.util.*; 4 5 import javax.persistence.*; 6 7 @Entity 8 public class Role { 9 @Id 10 @GeneratedValue 11 private Long id; 12 13 private String roleName; 14 15 @ManyToMany(cascade = CascadeType.ALL) 16 private List<User> users = new ArrayList<User>(); 17 18 public Long getId() { 19 return id; 20 } 21 22 public void setId(Long id) { 23 this.id = id; 24 } 25 26 public String getRoleName() { 27 return roleName; 28 } 29 30 public void setRoleName(String roleName) { 31 this.roleName = roleName; 32 } 33 34 public List<User> getUsers() { 35 return users; 36 } 37 38 public void setUsers(List<User> users) { 39 this.users = users; 40 } 41 } View Code
Category:
1 package simple.domain; 2 3 import java.util.*; 4 5 import javax.persistence.*; 6 7 @Entity 8 public class Category { 9 @Id 10 @GeneratedValue 11 private Long id; 12 13 private String Name; 14 15 @OneToMany 16 private List<Post> posts = new ArrayList<Post>(); 17 18 public Long getId() { 19 return id; 20 } 21 22 public void setId(Long id) { 23 this.id = id; 24 } 25 26 public String getName() { 27 return Name; 28 } 29 30 public void setName(String name) { 31 Name = name; 32 } 33 34 public List<Post> getPosts() { 35 return posts; 36 } 37 38 public void setPosts(List<Post> posts) { 39 this.posts = posts; 40 } 41 } View Code
Post:
1 package simple.domain; 2 3 import java.util.*; 4 5 import javax.persistence.*; 6 7 @Entity 8 public class Post { 9 @Id 10 @GeneratedValue 11 private Long id; 12 13 private String Name; 14 15 private String Html; 16 17 private String Text; 18 19 private Date CreateAt; 20 21 @ManyToOne 22 private Category category; 23 24 public Long getId() { 25 return id; 26 } 27 28 public void setId(Long id) { 29 this.id = id; 30 } 31 32 public String getName() { 33 return Name; 34 } 35 36 public void setName(String name) { 37 Name = name; 38 } 39 40 public String getHtml() { 41 return Html; 42 } 43 44 public void setHtml(String html) { 45 Html = html; 46 } 47 48 public String getText() { 49 return Text; 50 } 51 52 public void setText(String text) { 53 Text = text; 54 } 55 56 public Date getCreateAt() { 57 return CreateAt; 58 } 59 60 public void setCreateAt(Date createAt) { 61 CreateAt = createAt; 62 } 63 64 public Category getCategory() { 65 return category; 66 } 67 68 public void setCategory(Category category) { 69 this.category = category; 70 } 71 } View Code
(3)添加资源库
添加UserRepository、RoleRepository、CategoryRepository和PostRepository接口,无需实现。
UserRepository:
1 package simple.repository; 2 3 import org.springframework.data.repository.*; 4 5 import simple.domain.*; 6 7 public interface UserRepository extends CrudRepository<User, Long> { 8 9 }
RoleRepository
1 package simple.repository; 2 3 import org.springframework.data.repository.*; 4 5 import simple.domain.*; 6 7 public interface RoleRepository extends CrudRepository<Role, Long> { 8 9 }
CategoryRepository
1 package simple.repository; 2 3 import org.springframework.data.repository.*; 4 5 import simple.domain.*; 6 7 public interface CategoryRepository extends CrudRepository<Category, Long> { 8 9 }
PostRepository
package simple.repository; import org.springframework.data.repository.*; import simple.domain.*; public interface PostRepository extends CrudRepository<User, Long> { }
(4)在控制器中注入资源库接口
1 package simple.controller; 2 3 import org.springframework.beans.factory.annotation.*; 4 import org.springframework.web.bind.annotation.*; 5 6 import simple.repository.*; 7 8 @RestController 9 public class HomeController { 10 11 private UserRepository userRepository; 12 private RoleRepository roleRepository; 13 private CategoryRepository categoryRepository; 14 private PostRepository postReppository; 15 16 @Autowired 17 public HomeController(UserRepository userRepository, RoleRepository roleRepository, 18 CategoryRepository categoryRepository, PostRepository postReppository) { 19 this.userRepository = userRepository; 20 this.roleRepository = roleRepository; 21 this.categoryRepository = categoryRepository; 22 this.postReppository = postReppository; 23 } 24 25 26 @RequestMapping("/") 27 public long index() { 28 return userRepository.count(); 29 } 30 }
使用事务时在方法上应用注解@Transactional
3.添加验证和授权支持
(1)添加 spring-boot-starter-security 依赖
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <groupId>com.example</groupId> 6 <artifactId>myproject</artifactId> 7 <version>0.0.1-SNAPSHOT</version> 8 <properties> 9 <java.version>1.8</java.version> 10 </properties> 11 <parent> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-starter-parent</artifactId> 14 <version>1.3.1.RELEASE</version> 15 </parent> 16 <dependencies> 17 <dependency> 18 <groupId>org.springframework.boot</groupId> 19 <artifactId>spring-boot-starter-web</artifactId> 20 </dependency> 21 <dependency> 22 <groupId>org.springframework.boot</groupId> 23 <artifactId>spring-boot-starter-data-jpa</artifactId> 24 </dependency> 25 <dependency> 26 <groupId>com.h2database</groupId> 27 <artifactId>h2</artifactId> 28 <scope>runtime</scope> 29 </dependency> 30 <dependency> 31 <groupId>org.springframework.boot</groupId> 32 <artifactId>spring-boot-starter-security</artifactId> 33 </dependency> 34 </dependencies> 35 </project>
(2)修改Application.java
1 package simple; 2 3 import org.springframework.boot.*; 4 import org.springframework.boot.autoconfigure.*; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.security.config.annotation.method.configuration.*; 7 import org.springframework.security.config.annotation.web.builders.HttpSecurity; 8 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 9 import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; 10 11 import simple.controller.*; 12 13 @EnableAutoConfiguration 14 @EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true) 15 public class Application { 16 17 public static void main(String[] args) throws Exception { 18 SpringApplication.run(new Object[] { Application.class, HomeController.class }, args); 19 } 20 21 @Bean 22 public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter() { 23 return new MyWebSecurityConfigurer(); 24 } 25 26 public static class MyWebSecurityConfigurer extends WebSecurityConfigurerAdapter { 27 @Override 28 protected void configure(HttpSecurity http) throws Exception { 29 http.csrf().disable(); 30 http.authorizeRequests().antMatchers("/account**", "/admin**").authenticated(); 31 http.formLogin().usernameParameter("userName").passwordParameter("password").loginPage("/login") 32 .loginProcessingUrl("/login").successHandler(new SavedRequestAwareAuthenticationSuccessHandler()) 33 .and().logout().logoutUrl("/logout").logoutSuccessUrl("/"); 34 http.rememberMe().rememberMeParameter("rememberMe"); 35 36 } 37 } 38 }
访问http://localhost:8080/account会自动跳转到login登录页。Spring Security的具体使用前文已有所述。
参考:
(1)https://github.com/spring-projects/spring-boot
(2)http://projects.spring.io/spring-boot/