首先上整體的項目文件路徑:
Spring Security是爲基於Spring的應用程序提供聲明式安全保護的安全性框架。Spring Security提供了完整的安全性解決方案,它能夠在Web請求級別和方法調用級別處理身份認證和授權。因爲基於Spring框架,所以Spring Security充分利用了依賴注入(dependency injection,DI)和麪向切面的技術。Spring Security藉助一系列Servlet Filter來提供各種安全性功能,但是我們只需要配置一個Filter就可以了,DelegatingFilterProxy是一個特殊的Servlet Filter,它本身所做的工作並不多。只是將工作委託給一個javax.servlet.Filter實現類,這個實現類作爲一個<bean>註冊在Spring應用的上下文中。
要使用springSecurity要添加相關的jar包
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
AbstractSecurityWebApplicationInitializer實現了WebApplicationInitializer,因此Spring會發現它,並用它在Web容器中註冊DelegatingFilterProxy。儘管我們可以重載它的appendFilters()或insertFilters()方法來註冊自己選擇的Filter,但是要註冊DelegatingFilterProxy的話,我們並不需要重載任何方法。
package spittr.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
/**
* AbstractSecurityWebApplicationInitializer實現了WebApplicationInitializer
* 因此Spring會發現它,並用它在Web容器中註冊DelegatingFilterProxy
*/
public class SecurityWebInitializer extends AbstractSecurityWebApplicationInitializer {
}
DelegatingFilterProxy會攔截髮往應用中的請求,並將請求委託給ID爲springSecurityFilterChain bean。springSecurityFilterChain本身是另一個特殊的Filter,它也被稱爲FilterChainProxy。它可以鏈接任意一個或多個其他的Filter。Spring Security依賴一系列Servlet Filter來提供不同的安全特性。但是,你幾乎不需要知道這些細節,因爲你不需要顯式聲明springSecurityFilterChain以及它所鏈接在一起的其他Filter。當我們啓用Web安全性的時候,會自動創建這些Filter。
啓用Web安全性功能的最簡單配置,這裏只是在內存中模擬數據庫用戶數據
package spittr.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication() //啓用內存用戶存儲
// withUser()方法爲內存用戶存儲添加新的用戶
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
}
jdbc使用數據源連接池
在pom.xmlh中引入jar包
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.42</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
這裏使用DBCP,c3p0和這個設置差不多
配置數據源、使用JDBC模板
package spittr.config;
import java.io.IOException;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan("spittr")
// 自動掃描包spittr.web下的所有控制器
public class WebConfig extends WebMvcConfigurerAdapter {
// 配置jsp視圖解析器
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
// 配置靜態資源的處理
@Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
// 配置StandardServletMultipartResolver 上傳文件用
@Bean
public MultipartResolver multipartResolver() throws IOException {
return new StandardServletMultipartResolver();
}
// 使用dbcp連接池
@Bean
public BasicDataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); // com.mysql.jdbc.Driver,也可以用這個
ds.setUrl("jdbc:mysql://localhost:3306/springTest?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true");
ds.setUsername("root");
ds.setPassword("root");
ds.setInitialSize(5);
ds.setMaxTotal(10);
ds.setMaxIdle(3000);
return ds;
}
// 配置JDBC模板
@Bean
public JdbcTemplate jdbcTemplate(BasicDataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
注意:如果引入mysql-connector-java的版本是6.XX的那麼需要在jdbc的url後加上時區的參數,serverTimezone=UTC
不然會報錯:
The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone.
但是也引入了一個問題,添加了時區,但是utc默認是0時區,而北京市東八區,如果寫成serverTimezone=utc+8,也不行,這樣就導致存入數據庫的時間會比北京時間少八小時,我看網上有說是修改本地MySQL的時區爲東八區,SET GLOBAL time_zone='+8:00', 或者修改MySQL的初始化配置文件my.ini在裏邊[mysqld]下添加:default-time-zone=+8:00
還有一個辦法是就是直接把mysql-connector-java的版本改爲5.X的,然後去掉url後邊serverTimezone的參數!
userInte 接口文件package spittr.inte;
import java.util.List;
import spittr.models.User;
public interface UserInte {
List<User> findUsers(int count);
/**
* @param user
* @return the number of rows affected
*/
int add(User user);
User findById(Integer id);
}
userImpl 實現類,實現類中注入userDao
package spittr.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import spittr.dao.UserDao;
import spittr.inte.UserInte;
import spittr.models.User;
@Component
public class UserImpl implements UserInte {
@Autowired
private UserDao userDao;
@Override
public List<User> findUsers(int count) {
List<User> list = new ArrayList<User>();
for(int i=0; i<count; i++){
User user = new User("user_"+i, i+"", new Date());
list.add(user);
}
return list;
}
@Override
public int add(User user) {
return userDao.add(user);
}
@Override
public User findById(Integer id) {
return userDao.findById(id);
}
}
userDao dao中注入JdbcOperation
package spittr.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import spittr.models.User;
@Component
public class UserDao {
@Autowired
private JdbcOperations jdbcOperations;
public int add(User user) {
String sql = "INSERT INTO USER(NAME,PASSWORD,TIME) VALUES(?, ?, ?)";
int updateResult = jdbcOperations.update(sql, user.getName(), user.getPassword(), new Date());
return updateResult;
}
/**
* 把查找數據映射爲對象
* @param id
* @return
*/
public User findById(Integer id) {
String sql = "SELECT id,NAME,PASSWORD,TIME FROM USER WHERE id=?";
User user = jdbcOperations.queryForObject(sql, new UserRowMapper(), id);
return user;
}
private static final class UserRowMapper implements RowMapper<User>{
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(rs.getInt("id"), rs.getString("name"),rs.getString("password"),rs.getDate("time"));
}
}
}
userController中添加和查找用戶的action
@RequestMapping(value="/add", method=RequestMethod.GET)
public String add(){
User user = new User();
user.setName("test666");
user.setPassword("666");
int addResult = userInte.add(user);
System.out.println(addResult);
return "users";
}
@RequestMapping(value="/findById", method=RequestMethod.GET)
public String findById(@RequestParam(value="id", defaultValue="1") int id){
User user = userInte.findById(id);
System.out.println(user);
return "users";
}