Browse Source

提供多数据源

sunlightcs 7 years ago
parent
commit
79d5acb877

+ 8 - 0
pom-war.xml

@ -170,6 +170,14 @@
170 170
                    <fork>true</fork>
171 171
                </configuration>
172 172
            </plugin>
173
            <!-- 跳过单元测试 -->
174
            <plugin>
175
                <groupId>org.apache.maven.plugins</groupId>
176
                <artifactId>maven-surefire-plugin</artifactId>
177
                <configuration>
178
                    <skipTests>true</skipTests>
179
                </configuration>
180
            </plugin>
173 181
        </plugins>
174 182
    </build>
175 183

+ 10 - 8
pom.xml

@ -4,14 +4,14 @@
4 4
	<modelVersion>4.0.0</modelVersion>
5 5
	<groupId>io.renren</groupId>
6 6
	<artifactId>renren-fast</artifactId>
7
	<version>1.0.0</version>
7
	<version>1.2.0</version>
8 8
	<packaging>jar</packaging>
9 9
	<description>renren-fast</description>
10 10
11 11
	<parent>
12 12
		<groupId>org.springframework.boot</groupId>
13 13
		<artifactId>spring-boot-starter-parent</artifactId>
14
		<version>1.5.4.RELEASE</version>
14
		<version>1.5.6.RELEASE</version>
15 15
	</parent>
16 16
17 17
	<properties>
@ -28,7 +28,6 @@
28 28
		<commons.codec.version>1.10</commons.codec.version>
29 29
		<commons.configuration.version>1.10</commons.configuration.version>
30 30
		<shiro.version>1.3.2</shiro.version>
31
		<kaptcha.version>0.0.9</kaptcha.version>
32 31
		<qiniu.version>[7.2.0, 7.2.99]</qiniu.version>
33 32
		<aliyun.oss.version>2.5.0</aliyun.oss.version>
34 33
		<qcloud.cos.version>4.4</qcloud.cos.version>
@ -134,11 +133,6 @@
134 133
			<artifactId>shiro-spring</artifactId>
135 134
			<version>${shiro.version}</version>
136 135
		</dependency>
137
		<dependency>
138
			<groupId>com.github.axet</groupId>
139
			<artifactId>kaptcha</artifactId>
140
			<version>${kaptcha.version}</version>
141
		</dependency>
142 136
		<dependency>
143 137
			<groupId>com.qiniu</groupId>
144 138
			<artifactId>qiniu-java-sdk</artifactId>
@ -178,6 +172,14 @@
178 172
					<fork>true</fork>
179 173
				</configuration>
180 174
			</plugin>
175
			<!-- 跳过单元测试 -->
176
			<plugin>
177
				<groupId>org.apache.maven.plugins</groupId>
178
				<artifactId>maven-surefire-plugin</artifactId>
179
				<configuration>
180
					<skipTests>true</skipTests>
181
				</configuration>
182
			</plugin>
181 183
			<plugin>
182 184
				<groupId>org.codehaus.mojo</groupId>
183 185
				<artifactId>wagon-maven-plugin</artifactId>

+ 3 - 3
src/main/java/io/renren/common/utils/Constant.java

@ -34,7 +34,7 @@ public class Constant {
34 34
35 35
        private int value;
36 36
37
        private MenuType(int value) {
37
        MenuType(int value) {
38 38
            this.value = value;
39 39
        }
40 40
@ -62,7 +62,7 @@ public class Constant {
62 62
63 63
        private int value;
64 64
65
        private ScheduleStatus(int value) {
65
        ScheduleStatus(int value) {
66 66
            this.value = value;
67 67
        }
68 68
        
@ -90,7 +90,7 @@ public class Constant {
90 90
91 91
        private int value;
92 92
93
        private CloudService(int value) {
93
        CloudService(int value) {
94 94
            this.value = value;
95 95
        }
96 96

+ 1 - 1
src/main/java/io/renren/common/xss/XssHttpServletRequestWrapper.java

@ -34,7 +34,7 @@ public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
34 34
    @Override
35 35
    public ServletInputStream getInputStream() throws IOException {
36 36
        //非json类型,直接返回
37
        if(!super.getHeader(HttpHeaders.CONTENT_TYPE).equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)){
37
        if(!MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(super.getHeader(HttpHeaders.CONTENT_TYPE))){
38 38
            return super.getInputStream();
39 39
        }
40 40

+ 0 - 32
src/main/java/io/renren/config/KaptchaConfig.java

@ -1,32 +0,0 @@
1
package io.renren.config;
2
3
import com.google.code.kaptcha.impl.DefaultKaptcha;
4
import com.google.code.kaptcha.util.Config;
5
import org.springframework.context.annotation.Bean;
6
import org.springframework.context.annotation.Configuration;
7
8
import java.util.Properties;
9
10
11
/**
12
 * 生成验证码配置
13
 *
14
 * @author chenshun
15
 * @email sunlightcs@gmail.com
16
 * @date 2017-04-20 19:22
17
 */
18
@Configuration
19
public class KaptchaConfig {
20
21
    @Bean
22
    public DefaultKaptcha producer() {
23
        Properties properties = new Properties();
24
        properties.put("kaptcha.border", "no");
25
        properties.put("kaptcha.textproducer.font.color", "black");
26
        properties.put("kaptcha.textproducer.char.space", "5");
27
        Config config = new Config(properties);
28
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
29
        defaultKaptcha.setConfig(config);
30
        return defaultKaptcha;
31
    }
32
}

+ 1 - 3
src/main/java/io/renren/config/ShiroConfig.java

@ -32,8 +32,7 @@ public class ShiroConfig {
32 32
    public SessionManager sessionManager(){
33 33
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
34 34
        sessionManager.setSessionValidationSchedulerEnabled(true);
35
        //sessionManager.setSessionIdUrlRewritingEnabled(false);
36
        //sessionManager.setSessionIdCookieEnabled(false);
35
        sessionManager.setSessionIdCookieEnabled(false);
37 36
        return sessionManager;
38 37
    }
39 38
@ -68,7 +67,6 @@ public class ShiroConfig {
68 67
        filterMap.put("/plugins/**", "anon");
69 68
        filterMap.put("/swagger/**", "anon");
70 69
        filterMap.put("/favicon.ico", "anon");
71
        filterMap.put("/captcha.jpg", "anon");
72 70
        filterMap.put("/", "anon");
73 71
        filterMap.put("/**", "oauth2");
74 72
        shiroFilter.setFilterChainDefinitionMap(filterMap);

+ 23 - 0
src/main/java/io/renren/dynamicdatasource/DataSourceContext.java

@ -0,0 +1,23 @@
1
package io.renren.dynamicdatasource;
2
3
/**
4
 * 增加多数据源,在此配置
5
 *
6
 * @author chenshun
7
 * @email sunlightcs@gmail.com
8
 * @date 2017/8/18 23:46
9
 */
10
public enum DataSourceContext {
11
    FIRST("first"),
12
    SECOND("second");
13
14
    private String name;
15
16
    DataSourceContext(String name) {
17
        this.name = name;
18
    }
19
20
    public String getName() {
21
        return name;
22
    }
23
}

+ 41 - 0
src/main/java/io/renren/dynamicdatasource/DynamicDataSource.java

@ -0,0 +1,41 @@
1
package io.renren.dynamicdatasource;
2
3
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
4
5
import javax.sql.DataSource;
6
import java.util.HashMap;
7
import java.util.Map;
8
9
/**
10
 * 动态数据源
11
 * @author chenshun
12
 * @email sunlightcs@gmail.com
13
 * @date 2017/8/19 1:03
14
 */
15
public class DynamicDataSource extends AbstractRoutingDataSource {
16
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
17
18
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) {
19
        super.setDefaultTargetDataSource(defaultTargetDataSource);
20
        super.setTargetDataSources(new HashMap<>(targetDataSources));
21
        super.afterPropertiesSet();
22
    }
23
24
    @Override
25
    protected Object determineCurrentLookupKey() {
26
        return getDataSource();
27
    }
28
29
    public static void setDataSource(String dataSource) {
30
        contextHolder.set(dataSource);
31
    }
32
33
    public static String getDataSource() {
34
        return contextHolder.get();
35
    }
36
37
    public static void clearDataSource() {
38
        contextHolder.remove();
39
    }
40
41
}

+ 42 - 0
src/main/java/io/renren/dynamicdatasource/DynamicDataSourceConfig.java

@ -0,0 +1,42 @@
1
package io.renren.dynamicdatasource;
2
3
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
4
import org.springframework.boot.context.properties.ConfigurationProperties;
5
import org.springframework.context.annotation.Bean;
6
import org.springframework.context.annotation.Configuration;
7
import org.springframework.context.annotation.Primary;
8
9
import javax.sql.DataSource;
10
import java.util.HashMap;
11
import java.util.Map;
12
13
/**
14
 * 配置多数据源
15
 * @author chenshun
16
 * @email sunlightcs@gmail.com
17
 * @date 2017/8/19 0:41
18
 */
19
@Configuration
20
public class DynamicDataSourceConfig {
21
22
    @Bean
23
    @ConfigurationProperties("spring.datasource.druid.first")
24
    public DataSource firstDataSource(){
25
        return DruidDataSourceBuilder.create().build();
26
    }
27
28
    @Bean
29
    @ConfigurationProperties("spring.datasource.druid.second")
30
    public DataSource secondDataSource(){
31
        return DruidDataSourceBuilder.create().build();
32
    }
33
34
    @Bean
35
    @Primary
36
    public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {
37
        Map<String, DataSource> targetDataSources = new HashMap<>();
38
        targetDataSources.put(DataSourceContext.FIRST.getName(), firstDataSource);
39
        targetDataSources.put(DataSourceContext.SECOND.getName(), secondDataSource);
40
        return new DynamicDataSource(firstDataSource, targetDataSources);
41
    }
42
}

+ 1 - 34
src/main/java/io/renren/modules/sys/controller/SysLoginController.java

@ -1,24 +1,15 @@
1 1
package io.renren.modules.sys.controller;
2 2
3
import com.google.code.kaptcha.Constants;
4
import com.google.code.kaptcha.Producer;
5 3
import io.renren.common.utils.R;
6
import io.renren.common.utils.ShiroUtils;
7 4
import io.renren.modules.sys.entity.SysUserEntity;
8 5
import io.renren.modules.sys.service.SysUserService;
9 6
import io.renren.modules.sys.service.SysUserTokenService;
10
import org.apache.commons.io.IOUtils;
11 7
import org.apache.shiro.crypto.hash.Sha256Hash;
12 8
import org.springframework.beans.factory.annotation.Autowired;
13 9
import org.springframework.web.bind.annotation.RequestMapping;
14 10
import org.springframework.web.bind.annotation.RequestMethod;
15 11
import org.springframework.web.bind.annotation.RestController;
16 12
17
import javax.imageio.ImageIO;
18
import javax.servlet.ServletException;
19
import javax.servlet.ServletOutputStream;
20
import javax.servlet.http.HttpServletResponse;
21
import java.awt.image.BufferedImage;
22 13
import java.io.IOException;
23 14
import java.util.Map;
24 15
@ -31,40 +22,16 @@ import java.util.Map;
31 22
 */
32 23
@RestController
33 24
public class SysLoginController extends AbstractController {
34
	@Autowired
35
	private Producer producer;
36 25
	@Autowired
37 26
	private SysUserService sysUserService;
38 27
	@Autowired
39 28
	private SysUserTokenService sysUserTokenService;
40 29
41
	@RequestMapping("captcha.jpg")
42
	public void captcha(HttpServletResponse response)throws ServletException, IOException {
43
		response.setHeader("Cache-Control", "no-store, no-cache");
44
		response.setContentType("image/jpeg");
45
46
		//生成文字验证码
47
		String text = producer.createText();
48
		//生成图片验证码
49
		BufferedImage image = producer.createImage(text);
50
		//保存到shiro session
51
		ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);
52
53
		ServletOutputStream out = response.getOutputStream();
54
		ImageIO.write(image, "jpg", out);
55
		IOUtils.closeQuietly(out);
56
	}
57
58 30
	/**
59 31
	 * 登录
60 32
	 */
61 33
	@RequestMapping(value = "/sys/login", method = RequestMethod.POST)
62
	public Map<String, Object> login(String username, String password, String captcha)throws IOException {
63
		String kaptcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY);
64
		if(!captcha.equalsIgnoreCase(kaptcha)){
65
			return R.error("验证码不正确");
66
		}
67
34
	public Map<String, Object> login(String username, String password)throws IOException {
68 35
		//用户信息
69 36
		SysUserEntity user = sysUserService.queryByUserName(username);
70 37

+ 8 - 3
src/main/resources/application-dev.yml

@ -2,10 +2,15 @@ spring:
2 2
    datasource:
3 3
        type: com.alibaba.druid.pool.DruidDataSource
4 4
        driverClassName: com.mysql.jdbc.Driver
5
        url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
6
        username: renren
7
        password: 123456
8 5
        druid:
6
            first:  #数据源1
7
                url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
8
                username: renren
9
                password: 123456
10
            second:  #数据源2
11
                url: jdbc:mysql://localhost:3306/bdshop?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
12
                username: renren
13
                password: 123456
9 14
            initial-size: 10
10 15
            max-active: 100
11 16
            min-idle: 10

+ 8 - 3
src/main/resources/application-pro.yml

@ -2,10 +2,15 @@ spring:
2 2
    datasource:
3 3
        type: com.alibaba.druid.pool.DruidDataSource
4 4
        driverClassName: com.mysql.jdbc.Driver
5
        url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
6
        username: renren
7
        password: 123456
8 5
        druid:
6
            first:
7
                url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
8
                username: renren
9
                password: 123456
10
            second:
11
                url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
12
                username: renren
13
                password: 123456
9 14
            initial-size: 10
10 15
            max-active: 100
11 16
            min-idle: 10

+ 8 - 3
src/main/resources/application-test.yml

@ -2,10 +2,15 @@ spring:
2 2
    datasource:
3 3
        type: com.alibaba.druid.pool.DruidDataSource
4 4
        driverClassName: com.mysql.jdbc.Driver
5
        url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
6
        username: renren
7
        password: 123456
8 5
        druid:
6
            first:
7
                url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
8
                username: renren
9
                password: 123456
10
            second:
11
                url: jdbc:mysql://localhost:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
12
                username: renren
13
                password: 123456
9 14
            initial-size: 10
10 15
            max-active: 100
11 16
            min-idle: 10

+ 2 - 2
src/main/resources/application.yml

@ -5,9 +5,9 @@ server:
5 5
        max-threads: 1000
6 6
        min-spare-threads: 30
7 7
    port: 80
8
    #servlet-path: /renren-fast
8
    #打开注释,则通过【http://localhost/renren-fast】访问
9
    #context-path: /renren-fast
9 10
10
# mysql
11 11
spring:
12 12
    # 环境 dev|test|pro
13 13
    profiles:

+ 1 - 1
src/main/resources/views/index.html

@ -88,7 +88,7 @@
88 88
89 89
  <footer class="main-footer">
90 90
    <div class="pull-right hidden-xs">
91
      Version 1.0.0
91
      Version 1.2.0
92 92
    </div>
93 93
    Copyright &copy; 2017 <a href="http://www.renren.io" target="_blank">renren.io</a> All Rights Reserved
94 94
  </footer>

+ 3 - 18
src/main/resources/views/login.html

@ -37,17 +37,9 @@
37 37
          <span class="glyphicon glyphicon-user form-control-feedback"></span>
38 38
      </div>
39 39
      <div class="form-group has-feedback">
40
          <input type="password" class="form-control" v-model="password" placeholder="密码">
40
          <input type="password" class="form-control" v-model="password" @keyup.enter="login" placeholder="密码">
41 41
          <span class="glyphicon glyphicon-lock form-control-feedback"></span>
42 42
      </div>
43
      <div class="form-group has-feedback">
44
          <input type="text" class="form-control" v-model="captcha" @keyup.enter="login" placeholder="验证码">
45
          <span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>
46
      </div>
47
      <div class="form-group has-feedback">
48
          <img alt="如果看不清楚,请单击图片刷新!" class="pointer" :src="src" @click="refreshCode">
49
          &nbsp;&nbsp;&nbsp;&nbsp;<a href="javascript:;" @click="refreshCode">点击刷新</a>
50
      </div>
51 43
52 44
      <div class="row">
53 45
        <div class="col-xs-8">
@ -78,10 +70,8 @@ var vm = new Vue({
78 70
	data:{
79 71
		username: '',
80 72
		password: '',
81
        captcha: '',
82 73
		error: false,
83
		errorMsg: '',
84
        src: 'captcha.jpg'
74
		errorMsg: ''
85 75
	},
86 76
	beforeCreate: function(){
87 77
		if(self != top){
@ -89,11 +79,8 @@ var vm = new Vue({
89 79
		}
90 80
	},
91 81
	methods: {
92
        refreshCode: function(){
93
            this.src = "captcha.jpg?t=" + $.now();
94
        },
95 82
		login: function () {
96
            var data = "username="+vm.username+"&password="+vm.password+"&captcha="+vm.captcha;
83
            var data = "username="+vm.username+"&password="+vm.password;
97 84
			$.ajax({
98 85
				type: "POST",
99 86
			    url: baseURL + "sys/login",
@ -106,8 +93,6 @@ var vm = new Vue({
106 93
					}else{
107 94
						vm.error = true;
108 95
						vm.errorMsg = r.msg;
109
110
                        vm.refreshCode();
111 96
					}
112 97
				}
113 98
			});

+ 31 - 0
src/test/java/io/renren/DynamicDataSourceTest.java

@ -0,0 +1,31 @@
1
package io.renren;
2
3
import io.renren.dynamicdatasource.DataSourceContext;
4
import io.renren.dynamicdatasource.DynamicDataSource;
5
import io.renren.modules.api.entity.UserEntity;
6
import io.renren.modules.api.service.UserService;
7
import org.apache.commons.lang.builder.ToStringBuilder;
8
import org.junit.Test;
9
import org.junit.runner.RunWith;
10
import org.springframework.beans.factory.annotation.Autowired;
11
import org.springframework.boot.test.context.SpringBootTest;
12
import org.springframework.test.context.junit4.SpringRunner;
13
14
15
@RunWith(SpringRunner.class)
16
@SpringBootTest
17
public class DynamicDataSourceTest {
18
    @Autowired
19
    private UserService userService;
20
21
    @Test
22
    public void test(){
23
        UserEntity user = userService.queryObject(1L);
24
        System.out.println(ToStringBuilder.reflectionToString(user));
25
26
        //切换数据源
27
        DynamicDataSource.setDataSource(DataSourceContext.SECOND.getName());
28
        UserEntity user2 = userService.queryObject(1L);
29
        System.out.println(ToStringBuilder.reflectionToString(user2));
30
    }
31
}

+ 1 - 1
src/test/java/io/renren/RenrenApplicationTests.java

@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringRunner;
11 11
12 12
@RunWith(SpringRunner.class)
13 13
@SpringBootTest
14
public class RenrenApplicationTests {
14
public class RedisTest {
15 15
	@Autowired
16 16
	private RedisUtils redisUtils;
17 17