diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..249d5b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,72 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +# Gradle: +.idea/**/gradle.xml +# CMake +cmake-build-debug/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### Java template +# Compiled class file +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# custom +*.iml + +**/target diff --git a/Dubbo-Demo/Service-Client/pom.xml b/Dubbo-Demo/Service-Client/pom.xml new file mode 100644 index 0000000..bac9551 --- /dev/null +++ b/Dubbo-Demo/Service-Client/pom.xml @@ -0,0 +1,14 @@ + + + + cn.mrdear.dubbo + Dubbo-Demo + 1.0.0 + + 4.0.0 + Service-Client + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Client/src/main/java/cn/mrdear/client/dto/UserDTO.java b/Dubbo-Demo/Service-Client/src/main/java/cn/mrdear/client/dto/UserDTO.java new file mode 100644 index 0000000..72dd1ce --- /dev/null +++ b/Dubbo-Demo/Service-Client/src/main/java/cn/mrdear/client/dto/UserDTO.java @@ -0,0 +1,31 @@ +package cn.mrdear.client.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户DTO,用于Service层传输 + * @author Niu Li + * @since 2017/6/12 + */ +@Data +public class UserDTO implements Serializable{ + + private static final long serialVersionUID = 4086492518942464226L; + + private Long id; + + private String username; + + private String password; + + private Integer age; + + private String nickname; + + private String mail; + + private String memo; + +} diff --git a/Dubbo-Demo/Service-Client/src/main/java/cn/mrdear/client/service/IUserService.java b/Dubbo-Demo/Service-Client/src/main/java/cn/mrdear/client/service/IUserService.java new file mode 100644 index 0000000..1edd92f --- /dev/null +++ b/Dubbo-Demo/Service-Client/src/main/java/cn/mrdear/client/service/IUserService.java @@ -0,0 +1,37 @@ +package cn.mrdear.client.service; + +import cn.mrdear.client.dto.UserDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 用户服务,一般都会在返回层再包裹一层,这里简而化之 + * @author Niu Li + * @since 2017/6/12 + */ +public interface IUserService { + + /** + * 根据id查找 + */ + UserDTO findById(Long id); + + /** + * 根据id批量查询 + */ + List queryByIds(Collection ids); + + /** + * 更新用户 + * @return 返回更新后的实体 + */ + UserDTO updateById(UserDTO userDTO); + + /** + * 根据id删除用户 + */ + Boolean deleteById(Long id); + + +} diff --git a/Dubbo-Demo/Service-Consumer/pom.xml b/Dubbo-Demo/Service-Consumer/pom.xml new file mode 100644 index 0000000..c8ba829 --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/pom.xml @@ -0,0 +1,99 @@ + + + + cn.mrdear.dubbo + Dubbo-Demo + 1.0.0 + + war + 4.0.0 + Service-Consumer + + + + + cn.mrdear.dubbo + Service-Client + 1.0.0 + + + + com.netflix.hystrix + hystrix-javanica + 1.5.12 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.8.1 + + + com.fasterxml.jackson.core + jackson-core + 2.8.6 + + + com.fasterxml.jackson.core + jackson-databind + 2.8.6 + + + + org.springframework + spring-context + 4.3.2.RELEASE + + + org.springframework + spring-webmvc + 4.3.2.RELEASE + + + + javax.servlet + jstl + 1.2 + runtime + + + org.springframework + spring-web + 4.3.2.RELEASE + + + org.springframework + spring-test + 4.3.2.RELEASE + + + + com.alibaba + dubbo + 2.5.3 + + + spring + org.springframework + + + + + com.101tec + zkclient + 0.10 + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/controller/UserController.java b/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/controller/UserController.java new file mode 100644 index 0000000..9593c2d --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/controller/UserController.java @@ -0,0 +1,27 @@ +package cn.mrdear.consumer.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import cn.mrdear.client.dto.UserDTO; +import cn.mrdear.consumer.manager.UserManager; + +import javax.annotation.Resource; + +/** + * @author Niu Li + * @since 2017/6/14 + */ +@RestController +public class UserController { + + @Resource + private UserManager userManager; + + @GetMapping("/user/{id}") + public UserDTO getUserById(@PathVariable Long id) { + UserDTO userDTO = userManager.findById(id); + return userDTO; + } +} diff --git a/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/manager/UserManager.java b/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/manager/UserManager.java new file mode 100644 index 0000000..900368e --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/manager/UserManager.java @@ -0,0 +1,17 @@ +package cn.mrdear.consumer.manager; + +import cn.mrdear.client.dto.UserDTO; + +/** + * manager + * @author Niu Li + * @since 2017/6/13 + */ + +public interface UserManager { + + UserDTO findById(Long id); + + UserDTO findByIdBack(Long id); + +} diff --git a/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/manager/impl/UserManagerImpl.java b/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/manager/impl/UserManagerImpl.java new file mode 100644 index 0000000..572c407 --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/manager/impl/UserManagerImpl.java @@ -0,0 +1,51 @@ +package cn.mrdear.consumer.manager.impl; + +import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; + +import org.springframework.stereotype.Service; + +import cn.mrdear.client.dto.UserDTO; +import cn.mrdear.client.service.IUserService; +import cn.mrdear.consumer.manager.UserManager; + +import javax.annotation.Resource; + +import java.util.Objects; + +/** + * manager调用远程RPC组装数据,此处调试只是再加一层封装 + * @author Niu Li + * @since 2017/6/13 + */ +@Service +public class UserManagerImpl implements UserManager { + + @Resource + private IUserService userService; + + @Override + @HystrixCommand(groupKey = "user", fallbackMethod = "findByIdBack") + public UserDTO findById(Long id) { + if (Objects.equals(id, 1L)) { + try { + Thread.sleep(1000000); + } catch (InterruptedException e) { + // do nothing + } + } + if (Objects.equals(id, 2L)) { + throw new RuntimeException("熔断测试"); + } + return userService.findById(id); + } + + public UserDTO findByIdBack(Long id) { + System.err.println("findByIdBack"); + UserDTO userDTO = new UserDTO(); + userDTO.setAge(1); + userDTO.setUsername("备用用户"); + return userDTO; + } + + +} diff --git a/Dubbo-Demo/Service-Consumer/src/main/resources/applicationContext.xml b/Dubbo-Demo/Service-Consumer/src/main/resources/applicationContext.xml new file mode 100644 index 0000000..4ddd015 --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/main/resources/applicationContext.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Consumer/src/main/resources/dispatcher-servlet.xml b/Dubbo-Demo/Service-Consumer/src/main/resources/dispatcher-servlet.xml new file mode 100644 index 0000000..9b9a484 --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/main/resources/dispatcher-servlet.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Consumer/src/main/webapp/WEB-INF/view/error.jsp b/Dubbo-Demo/Service-Consumer/src/main/webapp/WEB-INF/view/error.jsp new file mode 100644 index 0000000..e9ea535 --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/main/webapp/WEB-INF/view/error.jsp @@ -0,0 +1,16 @@ +<%-- + Created by IntelliJ IDEA. + User: niuli + Date: 2017/4/19 + Time: 09:45 + To change this template use File | Settings | File Templates. +--%> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Title + + +

Error 页面

+ + diff --git a/Dubbo-Demo/Service-Consumer/src/main/webapp/WEB-INF/web.xml b/Dubbo-Demo/Service-Consumer/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..f1339a6 --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,65 @@ + + + + + + webAppRootKey + web.root + + + contextConfigLocation + classpath:applicationContext.xml + + + + + + encodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + + forceEncoding + true + + + + encodingFilter + /* + + + + org.springframework.web.util.WebAppRootListener + + + org.springframework.web.context.ContextLoaderListener + + + + org.springframework.web.util.IntrospectorCleanupListener + + + + + + dispatcher + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + + classpath:dispatcher-servlet.xml + + 1 + + + dispatcher + / + + + diff --git a/Dubbo-Demo/Service-Consumer/src/main/webapp/index.jsp b/Dubbo-Demo/Service-Consumer/src/main/webapp/index.jsp new file mode 100644 index 0000000..fa47f72 --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/main/webapp/index.jsp @@ -0,0 +1,17 @@ +<%-- + Created by IntelliJ IDEA. + User: NL + Date: 2017/1/23 + Time: 9:09 + To change this template use File | Settings | File Templates. +--%> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + + + +

Hello World!

+

请访问/user/{id}测试

+ + diff --git a/Dubbo-Demo/Service-Consumer/src/test/java/cn/mrdear/test/UserManagerTest.java b/Dubbo-Demo/Service-Consumer/src/test/java/cn/mrdear/test/UserManagerTest.java new file mode 100644 index 0000000..bfe506b --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/test/java/cn/mrdear/test/UserManagerTest.java @@ -0,0 +1,31 @@ +package cn.mrdear.test; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import cn.mrdear.client.dto.UserDTO; +import cn.mrdear.consumer.manager.UserManager; + +import javax.annotation.Resource; + +/** + * @author Niu Li + * @since 2017/6/13 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:applicationContext.xml") +public class UserManagerTest { + + @Resource + private UserManager userManager; + + + @Test + public void testFindById() { + UserDTO userDTO = userManager.findById(1L); + Assert.assertNotNull(userDTO); + } +} diff --git a/Dubbo-Demo/Service-Consumer/src/test/resources/applicationContext.xml b/Dubbo-Demo/Service-Consumer/src/test/resources/applicationContext.xml new file mode 100644 index 0000000..5a693f6 --- /dev/null +++ b/Dubbo-Demo/Service-Consumer/src/test/resources/applicationContext.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/pom.xml b/Dubbo-Demo/Service-Provider/pom.xml new file mode 100644 index 0000000..97f5cb5 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/pom.xml @@ -0,0 +1,120 @@ + + + + cn.mrdear.dubbo + Dubbo-Demo + 1.0.0 + + 4.0.0 + Service-Provider + + + + + cn.mrdear.dubbo + Service-Client + 1.0.0 + + + com.alibaba + dubbo + 2.5.3 + + + org.springframework + spring + + + org.javassist + javassist + + + + + com.101tec + zkclient + 0.10 + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + com.h2database + h2 + 1.4.187 + + + org.springframework + spring-context + 4.3.2.RELEASE + + + org.springframework + spring-test + 4.3.2.RELEASE + + + + org.aspectj + aspectjweaver + 1.8.6 + + + org.aspectj + aspectjrt + 1.8.6 + + + + + cglib + cglib + 3.2.2 + + + + + org.hibernate + hibernate-core + 5.1.0.Final + + + org.hibernate + hibernate-entitymanager + 5.1.0.Final + + + + + mysql + mysql-connector-java + 5.1.34 + + + + + com.alibaba + druid + 1.0.19 + + + + + + org.springframework.data + spring-data-jpa + 1.10.4.RELEASE + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/Application.java b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/Application.java new file mode 100644 index 0000000..cbebadb --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/Application.java @@ -0,0 +1,17 @@ +package cn.mrdear.provider; + +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import java.io.IOException; + +/** + * @author Niu Li + * @since 2017/6/12 + */ +public class Application { + public static void main(String[] args) throws IOException { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); + context.start(); + System.in.read(); // 为保证服务一直开着,利用输入流的阻塞来模拟 + } +} diff --git a/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/convert/UserConvert.java b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/convert/UserConvert.java new file mode 100644 index 0000000..67ae9ca --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/convert/UserConvert.java @@ -0,0 +1,42 @@ +package cn.mrdear.provider.convert; + +import org.springframework.beans.BeanUtils; +import org.springframework.util.CollectionUtils; + +import cn.mrdear.client.dto.UserDTO; +import cn.mrdear.provider.domain.User; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Niu Li + * @since 2017/6/12 + */ +public class UserConvert { + + public static UserDTO toDTO(User user) { + UserDTO userDTO = new UserDTO(); + BeanUtils.copyProperties(user,userDTO); + return userDTO; + } + + + public static List toDTOS(List users) { + if (CollectionUtils.isEmpty(users)) { + return new ArrayList<>(1); + } + List results = new ArrayList<>(); + return users.stream().map(UserConvert::toDTO) + .collect(Collectors.toList()); + } + + + public static User toDO(UserDTO userDTO) { + User user = new User(); + BeanUtils.copyProperties(userDTO,user); + return user; + } + +} diff --git a/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/dao/UserRepository.java b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/dao/UserRepository.java new file mode 100644 index 0000000..6b068b4 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/dao/UserRepository.java @@ -0,0 +1,24 @@ +package cn.mrdear.provider.dao; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import cn.mrdear.provider.domain.User; + +import java.util.Collection; +import java.util.List; + +/** + * JPA repo层 + * @author Niu Li + * @since 2017/6/12 + */ +public interface UserRepository extends JpaRepository{ + + User findById(Long id); + + @Query("select p from User p where id in (?1)") + List queryByIds(Collection ids); + + +} diff --git a/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/domain/User.java b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/domain/User.java new file mode 100644 index 0000000..81849e5 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/domain/User.java @@ -0,0 +1,39 @@ +package cn.mrdear.provider.domain; + +import lombok.Data; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import java.io.Serializable; + +/** + * 用户实体类,对应数据库 + * @author Niu Li + * @since 2017/6/12 + */ +@Data +@Entity +@Table(name = "user") +public class User implements Serializable{ + + private static final long serialVersionUID = 1793488098966504793L; + @Id + @GeneratedValue + private Long id; + + private String username; + + private String password; + + private Integer age; + + private String nickname; + + private String mail; + + private String memo; + +} diff --git a/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/service/UserServiceImpl.java b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/service/UserServiceImpl.java new file mode 100644 index 0000000..082f809 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/java/cn/mrdear/provider/service/UserServiceImpl.java @@ -0,0 +1,51 @@ +package cn.mrdear.provider.service; + +import com.alibaba.dubbo.config.annotation.Service; + +import cn.mrdear.client.dto.UserDTO; +import cn.mrdear.client.service.IUserService; +import cn.mrdear.provider.convert.UserConvert; +import cn.mrdear.provider.dao.UserRepository; +import cn.mrdear.provider.domain.User; + +import javax.annotation.Resource; + +import java.util.Collection; +import java.util.List; + +/** + * 用户服务的具体实现,作为服务提供方提供出去 + * @author Niu Li + * @since 2017/6/12 + */ +@Service(version = "1.0.0") +public class UserServiceImpl implements IUserService { + + @Resource + private UserRepository userRepository; + + @Override + public UserDTO findById(Long id) { + User user = userRepository.findById(id); + return UserConvert.toDTO(user); + } + + @Override + public List queryByIds(Collection ids) { + List users = userRepository.queryByIds(ids); + return UserConvert.toDTOS(users); + } + + @Override + public UserDTO updateById(UserDTO userDTO) { + User user = UserConvert.toDO(userDTO); + userRepository.save(user); + return this.findById(userDTO.getId()); + } + + @Override + public Boolean deleteById(Long id) { + userRepository.delete(id); + return true; + } +} diff --git a/Dubbo-Demo/Service-Provider/src/main/resources/applicationContext.xml b/Dubbo-Demo/Service-Provider/src/main/resources/applicationContext.xml new file mode 100644 index 0000000..c811fad --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/resources/applicationContext.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.hibernate.dialect.MySQL5Dialect + + false + + false + + false + + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/src/main/resources/db.properties b/Dubbo-Demo/Service-Provider/src/main/resources/db.properties new file mode 100644 index 0000000..2228684 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/resources/db.properties @@ -0,0 +1,24 @@ +jdbc.driver=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&characterEncoding=utf8&characterSetResults\ + =utf8 +jdbc.username=root +jdbc.password=7946521 + +filters:stat + +maxActive:20 +initialSize:1 +maxWait:60000 +minIdle:10 + +timeBetweenEvictionRunsMillis:60000 +minEvictableIdleTimeMillis:300000 + +testWhileIdle:true +testOnBorrow:false +testOnReturn:false + +maxOpenPreparedStatements:20 +removeAbandoned:true +removeAbandonedTimeout:1800 +logAbandoned:true diff --git a/Dubbo-Demo/Service-Provider/src/main/resources/h2/data.sql b/Dubbo-Demo/Service-Provider/src/main/resources/h2/data.sql new file mode 100644 index 0000000..a09f7a8 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/resources/h2/data.sql @@ -0,0 +1,6 @@ +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('zhangsan', + '123456', 18, '张三', '1111@qq.com', 'hahahah'); +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('lis', +'123456', 19, '李四', '123131@qq.com', 'xixiixxi'); +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('wanger', +'123456', 29, '王二', '12131984@qq.com', 'dqdh'); \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/src/main/resources/h2/schema.sql b/Dubbo-Demo/Service-Provider/src/main/resources/h2/schema.sql new file mode 100644 index 0000000..8de82c2 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/resources/h2/schema.sql @@ -0,0 +1,10 @@ +DROP TABLE user if exist; +create table user ( + id INT(11) AUTO_INCREMENT PRIMARY KEY , + username VARCHAR(255), + password VARCHAR(255), + age INT(3), + nickname VARCHAR(255), + mail VARCHAR(255), + memo VARCHAR(255), + ); \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/src/main/resources/logback.xml b/Dubbo-Demo/Service-Provider/src/main/resources/logback.xml new file mode 100644 index 0000000..d68cd15 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + + + + %d{HH:mm:ss} [%t] %logger{5} [%line] %p - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/src/test/java/cn/mrdear/test/UserServiceTest.java b/Dubbo-Demo/Service-Provider/src/test/java/cn/mrdear/test/UserServiceTest.java new file mode 100644 index 0000000..3a50744 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/test/java/cn/mrdear/test/UserServiceTest.java @@ -0,0 +1,31 @@ +package cn.mrdear.test; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import cn.mrdear.client.dto.UserDTO; +import cn.mrdear.provider.service.UserServiceImpl; + +import javax.annotation.Resource; + +/** + * @author Niu Li + * @since 2017/6/13 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:applicationContext.xml") +public class UserServiceTest { + + @Resource + private UserServiceImpl userService; + + @Test + public void testFindById() { + UserDTO userDTO = userService.findById(1L); + Assert.assertNotNull(userDTO); + } + +} diff --git a/Dubbo-Demo/Service-Provider/src/test/resources/applicationContext.xml b/Dubbo-Demo/Service-Provider/src/test/resources/applicationContext.xml new file mode 100644 index 0000000..0192b9b --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/test/resources/applicationContext.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.hibernate.dialect.MySQL5Dialect + + false + + false + + false + + none + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/src/test/resources/db.properties b/Dubbo-Demo/Service-Provider/src/test/resources/db.properties new file mode 100644 index 0000000..2228684 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/test/resources/db.properties @@ -0,0 +1,24 @@ +jdbc.driver=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://127.0.0.1:3306/ssm?useUnicode=true&characterEncoding=utf8&characterSetResults\ + =utf8 +jdbc.username=root +jdbc.password=7946521 + +filters:stat + +maxActive:20 +initialSize:1 +maxWait:60000 +minIdle:10 + +timeBetweenEvictionRunsMillis:60000 +minEvictableIdleTimeMillis:300000 + +testWhileIdle:true +testOnBorrow:false +testOnReturn:false + +maxOpenPreparedStatements:20 +removeAbandoned:true +removeAbandonedTimeout:1800 +logAbandoned:true diff --git a/Dubbo-Demo/Service-Provider/src/test/resources/h2/data.sql b/Dubbo-Demo/Service-Provider/src/test/resources/h2/data.sql new file mode 100644 index 0000000..a09f7a8 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/test/resources/h2/data.sql @@ -0,0 +1,6 @@ +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('zhangsan', + '123456', 18, '张三', '1111@qq.com', 'hahahah'); +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('lis', +'123456', 19, '李四', '123131@qq.com', 'xixiixxi'); +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('wanger', +'123456', 29, '王二', '12131984@qq.com', 'dqdh'); \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/src/test/resources/h2/schema.sql b/Dubbo-Demo/Service-Provider/src/test/resources/h2/schema.sql new file mode 100644 index 0000000..8de82c2 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/test/resources/h2/schema.sql @@ -0,0 +1,10 @@ +DROP TABLE user if exist; +create table user ( + id INT(11) AUTO_INCREMENT PRIMARY KEY , + username VARCHAR(255), + password VARCHAR(255), + age INT(3), + nickname VARCHAR(255), + mail VARCHAR(255), + memo VARCHAR(255), + ); \ No newline at end of file diff --git a/Dubbo-Demo/Service-Provider/src/test/resources/logback.xml b/Dubbo-Demo/Service-Provider/src/test/resources/logback.xml new file mode 100644 index 0000000..d68cd15 --- /dev/null +++ b/Dubbo-Demo/Service-Provider/src/test/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + + + + %d{HH:mm:ss} [%t] %logger{5} [%line] %p - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/Dubbo-Demo/doc/readme.md b/Dubbo-Demo/doc/readme.md new file mode 100644 index 0000000..47335f0 --- /dev/null +++ b/Dubbo-Demo/doc/readme.md @@ -0,0 +1,7 @@ + +1. 启动需要先下载zk,然后启动 +2. Provider中spring配置文件host改成本机ip地址,然后启动 +3. 启动Consumer +4. 可下载Simple-monitor http://download.csdn.net/detail/liweifengwf/7864009 +5. 可下载dubbo-admin http://download.csdn.net/detail/leiyong0326/9548973 +6. dubbo的调用基本就是这样,大多数规则都可以在admin中配置也可以在spring注册服务和引用的时候配置 \ No newline at end of file diff --git a/Dubbo-Demo/pom.xml b/Dubbo-Demo/pom.xml new file mode 100644 index 0000000..bd21a12 --- /dev/null +++ b/Dubbo-Demo/pom.xml @@ -0,0 +1,79 @@ + + + 4.0.0 + + cn.mrdear.dubbo + Dubbo-Demo + pom + 1.0.0 + Dubbo-demo + + Service-Client + Service-Consumer + Service-Provider + + + + + + org.projectlombok + lombok + 1.16.14 + + + junit + junit + 4.12 + + + com.google.guava + guava + 21.0 + + + + org.slf4j + slf4j-api + 1.7.7 + + + org.slf4j + jcl-over-slf4j + 1.7.7 + + + ch.qos.logback + logback-core + 1.1.2 + + + org.logback-extensions + logback-ext-spring + 0.1.4 + + + ch.qos.logback + logback-classic + 1.1.2 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/Motan-Demo/Service-Client/pom.xml b/Motan-Demo/Service-Client/pom.xml new file mode 100644 index 0000000..8d2eade --- /dev/null +++ b/Motan-Demo/Service-Client/pom.xml @@ -0,0 +1,16 @@ + + + + Motan-Demo + cn.mrdear.motan + 1.0-SNAPSHOT + + 4.0.0 + + cn.mrdear.motan + Service-Client + + + \ No newline at end of file diff --git a/Motan-Demo/Service-Client/src/main/java/cn/mrdear/client/dto/UserDTO.java b/Motan-Demo/Service-Client/src/main/java/cn/mrdear/client/dto/UserDTO.java new file mode 100644 index 0000000..72dd1ce --- /dev/null +++ b/Motan-Demo/Service-Client/src/main/java/cn/mrdear/client/dto/UserDTO.java @@ -0,0 +1,31 @@ +package cn.mrdear.client.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 用户DTO,用于Service层传输 + * @author Niu Li + * @since 2017/6/12 + */ +@Data +public class UserDTO implements Serializable{ + + private static final long serialVersionUID = 4086492518942464226L; + + private Long id; + + private String username; + + private String password; + + private Integer age; + + private String nickname; + + private String mail; + + private String memo; + +} diff --git a/Motan-Demo/Service-Client/src/main/java/cn/mrdear/client/service/IUserService.java b/Motan-Demo/Service-Client/src/main/java/cn/mrdear/client/service/IUserService.java new file mode 100644 index 0000000..1edd92f --- /dev/null +++ b/Motan-Demo/Service-Client/src/main/java/cn/mrdear/client/service/IUserService.java @@ -0,0 +1,37 @@ +package cn.mrdear.client.service; + +import cn.mrdear.client.dto.UserDTO; + +import java.util.Collection; +import java.util.List; + +/** + * 用户服务,一般都会在返回层再包裹一层,这里简而化之 + * @author Niu Li + * @since 2017/6/12 + */ +public interface IUserService { + + /** + * 根据id查找 + */ + UserDTO findById(Long id); + + /** + * 根据id批量查询 + */ + List queryByIds(Collection ids); + + /** + * 更新用户 + * @return 返回更新后的实体 + */ + UserDTO updateById(UserDTO userDTO); + + /** + * 根据id删除用户 + */ + Boolean deleteById(Long id); + + +} diff --git a/Motan-Demo/Service-Consumer/pom.xml b/Motan-Demo/Service-Consumer/pom.xml new file mode 100644 index 0000000..31ec032 --- /dev/null +++ b/Motan-Demo/Service-Consumer/pom.xml @@ -0,0 +1,108 @@ + + + + Motan-Demo + cn.mrdear.motan + 1.0-SNAPSHOT + + 4.0.0 + + cn.mrdear.motan + Service-Consumer + + + + cn.mrdear.motan + Service-Client + 1.0-SNAPSHOT + + + + com.weibo + motan-core + RELEASE + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + com.weibo + motan-transport-netty + RELEASE + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + com.weibo + motan-registry-zookeeper + RELEASE + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + com.101tec + zkclient + + + + + com.101tec + zkclient + 0.10 + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + com.weibo + motan-springsupport + RELEASE + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + org.springframework + spring-context + 4.3.6.RELEASE + + + + \ No newline at end of file diff --git a/Motan-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/ApplicationStart.java b/Motan-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/ApplicationStart.java new file mode 100644 index 0000000..f5e634b --- /dev/null +++ b/Motan-Demo/Service-Consumer/src/main/java/cn/mrdear/consumer/ApplicationStart.java @@ -0,0 +1,21 @@ +package cn.mrdear.consumer; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import cn.mrdear.client.service.IUserService; + +/** + * @author Niu Li + * @since 2017/6/14 + */ +public class ApplicationStart { + + public static void main(String[] args) throws InterruptedException { + ApplicationContext ctx = new ClassPathXmlApplicationContext( + "classpath:applicationContext.xml"); + IUserService service = (IUserService) ctx.getBean("userService"); + System.out.println(service.findById(1L)); + } + +} diff --git a/Motan-Demo/Service-Consumer/src/main/resources/applicationContext.xml b/Motan-Demo/Service-Consumer/src/main/resources/applicationContext.xml new file mode 100644 index 0000000..28b860c --- /dev/null +++ b/Motan-Demo/Service-Consumer/src/main/resources/applicationContext.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Motan-Demo/Service-Consumer/src/main/resources/logback.xml b/Motan-Demo/Service-Consumer/src/main/resources/logback.xml new file mode 100644 index 0000000..d68cd15 --- /dev/null +++ b/Motan-Demo/Service-Consumer/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + + + + %d{HH:mm:ss} [%t] %logger{5} [%line] %p - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/Motan-Demo/Service-Provider/pom.xml b/Motan-Demo/Service-Provider/pom.xml new file mode 100644 index 0000000..d5a727e --- /dev/null +++ b/Motan-Demo/Service-Provider/pom.xml @@ -0,0 +1,151 @@ + + + + Motan-Demo + cn.mrdear.motan + 1.0-SNAPSHOT + + 4.0.0 + + cn.mrdear.motan + Service-Provider + + + + + cn.mrdear.motan + Service-Client + 1.0-SNAPSHOT + + + + com.weibo + motan-core + RELEASE + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + com.weibo + motan-transport-netty + RELEASE + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + com.weibo + motan-registry-zookeeper + RELEASE + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + com.101tec + zkclient + + + + + com.101tec + zkclient + 0.10 + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + + com.weibo + motan-springsupport + RELEASE + + + log4j + log4j + + + org.slf4j + slf4j-log4j12 + + + + + org.springframework + spring-context + 4.3.6.RELEASE + + + org.springframework.data + spring-data-jpa + 1.10.4.RELEASE + + + + org.hibernate + hibernate-core + 5.1.0.Final + + + org.hibernate + hibernate-entitymanager + 5.1.0.Final + + + + + org.aspectj + aspectjweaver + 1.8.6 + + + org.aspectj + aspectjrt + 1.8.6 + + + + + cglib + cglib + 3.2.2 + + + + com.h2database + h2 + 1.4.187 + + + + \ No newline at end of file diff --git a/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/ApplicationStart.java b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/ApplicationStart.java new file mode 100644 index 0000000..7db2920 --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/ApplicationStart.java @@ -0,0 +1,22 @@ +package cn.mrdear.provider; + +import com.weibo.api.motan.common.MotanConstants; +import com.weibo.api.motan.util.MotanSwitcherUtil; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * @author Niu Li + * @since 2017/6/14 + */ +public class ApplicationStart { + + public static void main(String[] args) throws InterruptedException { + ApplicationContext applicationContext = + new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); + MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true); + System.out.println("server start..."); + } + +} diff --git a/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/convert/UserConvert.java b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/convert/UserConvert.java new file mode 100644 index 0000000..67ae9ca --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/convert/UserConvert.java @@ -0,0 +1,42 @@ +package cn.mrdear.provider.convert; + +import org.springframework.beans.BeanUtils; +import org.springframework.util.CollectionUtils; + +import cn.mrdear.client.dto.UserDTO; +import cn.mrdear.provider.domain.User; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Niu Li + * @since 2017/6/12 + */ +public class UserConvert { + + public static UserDTO toDTO(User user) { + UserDTO userDTO = new UserDTO(); + BeanUtils.copyProperties(user,userDTO); + return userDTO; + } + + + public static List toDTOS(List users) { + if (CollectionUtils.isEmpty(users)) { + return new ArrayList<>(1); + } + List results = new ArrayList<>(); + return users.stream().map(UserConvert::toDTO) + .collect(Collectors.toList()); + } + + + public static User toDO(UserDTO userDTO) { + User user = new User(); + BeanUtils.copyProperties(userDTO,user); + return user; + } + +} diff --git a/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/dao/UserRepository.java b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/dao/UserRepository.java new file mode 100644 index 0000000..6b068b4 --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/dao/UserRepository.java @@ -0,0 +1,24 @@ +package cn.mrdear.provider.dao; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import cn.mrdear.provider.domain.User; + +import java.util.Collection; +import java.util.List; + +/** + * JPA repo层 + * @author Niu Li + * @since 2017/6/12 + */ +public interface UserRepository extends JpaRepository{ + + User findById(Long id); + + @Query("select p from User p where id in (?1)") + List queryByIds(Collection ids); + + +} diff --git a/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/domain/User.java b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/domain/User.java new file mode 100644 index 0000000..81849e5 --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/domain/User.java @@ -0,0 +1,39 @@ +package cn.mrdear.provider.domain; + +import lombok.Data; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import java.io.Serializable; + +/** + * 用户实体类,对应数据库 + * @author Niu Li + * @since 2017/6/12 + */ +@Data +@Entity +@Table(name = "user") +public class User implements Serializable{ + + private static final long serialVersionUID = 1793488098966504793L; + @Id + @GeneratedValue + private Long id; + + private String username; + + private String password; + + private Integer age; + + private String nickname; + + private String mail; + + private String memo; + +} diff --git a/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/service/UserServiceImpl.java b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/service/UserServiceImpl.java new file mode 100644 index 0000000..7ab049a --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/java/cn/mrdear/provider/service/UserServiceImpl.java @@ -0,0 +1,46 @@ +package cn.mrdear.provider.service; + +import cn.mrdear.client.dto.UserDTO; +import cn.mrdear.client.service.IUserService; +import cn.mrdear.provider.convert.UserConvert; +import cn.mrdear.provider.dao.UserRepository; +import cn.mrdear.provider.domain.User; + +import javax.annotation.Resource; + +import java.util.Collection; +import java.util.List; + +/** + * @author Niu Li + * @since 2017/6/14 + */ +public class UserServiceImpl implements IUserService{ + @Resource + private UserRepository userRepository; + + @Override + public UserDTO findById(Long id) { + User user = userRepository.findById(id); + return UserConvert.toDTO(user); + } + + @Override + public List queryByIds(Collection ids) { + List users = userRepository.queryByIds(ids); + return UserConvert.toDTOS(users); + } + + @Override + public UserDTO updateById(UserDTO userDTO) { + User user = UserConvert.toDO(userDTO); + userRepository.save(user); + return this.findById(userDTO.getId()); + } + + @Override + public Boolean deleteById(Long id) { + userRepository.delete(id); + return true; + } +} diff --git a/Motan-Demo/Service-Provider/src/main/resources/applicationContext.xml b/Motan-Demo/Service-Provider/src/main/resources/applicationContext.xml new file mode 100644 index 0000000..4b5d788 --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/resources/applicationContext.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.hibernate.dialect.MySQL5Dialect + + false + + false + + false + + none + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Motan-Demo/Service-Provider/src/main/resources/h2/data.sql b/Motan-Demo/Service-Provider/src/main/resources/h2/data.sql new file mode 100644 index 0000000..a09f7a8 --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/resources/h2/data.sql @@ -0,0 +1,6 @@ +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('zhangsan', + '123456', 18, '张三', '1111@qq.com', 'hahahah'); +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('lis', +'123456', 19, '李四', '123131@qq.com', 'xixiixxi'); +INSERT INTO user (username, password, age, nickname, mail, memo) VALUES ('wanger', +'123456', 29, '王二', '12131984@qq.com', 'dqdh'); \ No newline at end of file diff --git a/Motan-Demo/Service-Provider/src/main/resources/h2/schema.sql b/Motan-Demo/Service-Provider/src/main/resources/h2/schema.sql new file mode 100644 index 0000000..8de82c2 --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/resources/h2/schema.sql @@ -0,0 +1,10 @@ +DROP TABLE user if exist; +create table user ( + id INT(11) AUTO_INCREMENT PRIMARY KEY , + username VARCHAR(255), + password VARCHAR(255), + age INT(3), + nickname VARCHAR(255), + mail VARCHAR(255), + memo VARCHAR(255), + ); \ No newline at end of file diff --git a/Motan-Demo/Service-Provider/src/main/resources/logback.xml b/Motan-Demo/Service-Provider/src/main/resources/logback.xml new file mode 100644 index 0000000..d68cd15 --- /dev/null +++ b/Motan-Demo/Service-Provider/src/main/resources/logback.xml @@ -0,0 +1,19 @@ + + + + + + + + %d{HH:mm:ss} [%t] %logger{5} [%line] %p - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/Motan-Demo/pom.xml b/Motan-Demo/pom.xml new file mode 100644 index 0000000..eb68369 --- /dev/null +++ b/Motan-Demo/pom.xml @@ -0,0 +1,79 @@ + + + 4.0.0 + + pom + + + Service-Client + Service-Provider + Service-Consumer + + + cn.mrdear.motan + Motan-Demo + 1.0-SNAPSHOT + + + + + org.projectlombok + lombok + 1.16.14 + + + junit + junit + 4.12 + + + com.google.guava + guava + 21.0 + + + + org.slf4j + slf4j-api + 1.7.7 + + + org.slf4j + jcl-over-slf4j + 1.7.7 + + + ch.qos.logback + logback-core + 1.1.2 + + + org.logback-extensions + logback-ext-spring + 0.1.4 + + + ch.qos.logback + logback-classic + 1.1.2 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + + \ No newline at end of file diff --git a/README.MD b/README.MD index 5f8d063..5ab30da 100644 --- a/README.MD +++ b/README.MD @@ -1,3 +1,7 @@ +### 2017.9.27 +随着开发经验的增加,现在觉得这种Demo对于学习一个框架起不到太大的作用,顶多是个参考,并且由于使用经验的增加,对于之前一些错误的用法很难得到纠正,如果想要快速入门的话官方+造轮子才是最佳选择,类似豆瓣有许多开放的API,都可以用来练手,最后该项目不再更新,这点经验希望能帮助你. + + #该仓库主要记录学习javaWEB中一些Demo 1.SSM-Demo @@ -51,5 +55,21 @@ SpringDataJPA+QueryDSL使用,需要配合博客博文http://www.jianshu.com/p/e3 -------------- SpringDataRedis学习的一个Demo,内容不多,配合博文:[redis学习记录(四)-SpringDataRedis分析](http://mrdear.cn/2017/03/29/linux/redis%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95(%E5%9B%9B)-SpringDataRedis%E5%88%86%E6%9E%90/)可以很好的入手 -12.待添加 +12.Spring-Cloud-Demo +-------------- +学习Spring Cloud的一个Demo,其中对于Eureka,Ribbon,Feign等都有相应的Demo,相应博文会更新在[我的博客](mrdear.cn)上,希望对你有帮助 + +13.Dubbo-Demo +-------------- +增加Dubbo-Demo,一个基本的RPC调用Demo + +14.Motan-Demo +-------------- +增加Motan-Demo,一个基本的RPC调用Demo + +15.Spring-Security-Demo +-------------- +增加Spring Security Demo,项目中使用了JWT Token验证机制,该项目可以很好的了解整个流程的作用,需要配合我博客中Spring Security相关博文食用. + +16.待添加 -------------- diff --git a/Spring-Cloud-Demo/Service-Discovery-Eureka/pom.xml b/Spring-Cloud-Demo/Service-Discovery-Eureka/pom.xml new file mode 100644 index 0000000..9d30f7b --- /dev/null +++ b/Spring-Cloud-Demo/Service-Discovery-Eureka/pom.xml @@ -0,0 +1,28 @@ + + + + cn.mrdear.springcloud + springcloud-parent + 1.0.0 + + 4.0.0 + service-discovery-eureka + + + + org.springframework.cloud + spring-cloud-starter-eureka-server + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + \ No newline at end of file diff --git a/Spring-Cloud-Demo/Service-Discovery-Eureka/src/main/java/cn/mrdear/EurekaApplication.java b/Spring-Cloud-Demo/Service-Discovery-Eureka/src/main/java/cn/mrdear/EurekaApplication.java new file mode 100644 index 0000000..b60fdc0 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Discovery-Eureka/src/main/java/cn/mrdear/EurekaApplication.java @@ -0,0 +1,17 @@ +package cn.mrdear; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; + +/** + * @author Niu Li + * @since 2017/5/25 + */ +@EnableEurekaServer//启动服务注册中心 +@SpringBootApplication +public class EurekaApplication { + public static void main(String[] args) { + SpringApplication.run(EurekaApplication.class,args); + } +} diff --git a/Spring-Cloud-Demo/Service-Discovery-Eureka/src/main/resources/application.yml b/Spring-Cloud-Demo/Service-Discovery-Eureka/src/main/resources/application.yml new file mode 100644 index 0000000..4bb275e --- /dev/null +++ b/Spring-Cloud-Demo/Service-Discovery-Eureka/src/main/resources/application.yml @@ -0,0 +1,19 @@ + +server: + port: 8761 + +spring: + application: + name: eureka-server + +eureka: + instance: + hostname: localhost + prefer-ip-address: true + client: + register-with-eureka: false + fetch-registry: false + service-url: + defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ + + diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/pom.xml b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/pom.xml new file mode 100644 index 0000000..7a1f4b0 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/pom.xml @@ -0,0 +1,25 @@ + + + + springcloud-parent + cn.mrdear.springcloud + 1.0.0 + + 4.0.0 + + cn.mrdear.springcloud + Service-Product-Consumer-Feign-Hystrix + + + + org.springframework.cloud + spring-cloud-starter-feign + + + org.springframework.cloud + spring-cloud-starter-eureka + + + \ No newline at end of file diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/UserConsumeFeignHystrixApplication.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/UserConsumeFeignHystrixApplication.java new file mode 100644 index 0000000..e9f93d4 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/UserConsumeFeignHystrixApplication.java @@ -0,0 +1,19 @@ +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.netflix.feign.EnableFeignClients; + + +/** + * @author Niu Li + * @since 2017/6/3 + */ +@SpringBootApplication(scanBasePackages = "cn.medear.springcloud") +@EnableDiscoveryClient +@EnableFeignClients(basePackages = "cn.medear.springcloud.restclient") +public class UserConsumeFeignHystrixApplication { + + public static void main(String[] args) { + SpringApplication.run(UserConsumeFeignHystrixApplication.class, args); + } +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/controller/ConsumeUserController.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/controller/ConsumeUserController.java new file mode 100644 index 0000000..e53e366 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/controller/ConsumeUserController.java @@ -0,0 +1,41 @@ +package cn.medear.springcloud.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import cn.medear.springcloud.entity.User; +import cn.medear.springcloud.restclient.UserClient; +import lombok.extern.slf4j.Slf4j; + +/** + * 用于消费UserService的类 + * @author Niu Li + * @since 2017/6/3 + */ +@RestController +@Slf4j +public class ConsumeUserController { + + @Resource + private UserClient userClient; + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + @GetMapping("/{id}") + public String findUserById(@PathVariable Long id) { + User user = userClient.findById(id); + String valueAsString = null; + try { + valueAsString = objectMapper.writeValueAsString(user); + } catch (JsonProcessingException e) { + log.error("parse json error. {}",e); + } + return valueAsString; + } +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/entity/User.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/entity/User.java new file mode 100644 index 0000000..2dc8e22 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/entity/User.java @@ -0,0 +1,25 @@ +package cn.medear.springcloud.entity; + +import java.io.Serializable; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * @author Niu Li + * @since 2017/6/3 + */ +@Data +@NoArgsConstructor +@ToString +public class User implements Serializable{ + + private static final long serialVersionUID = -2885884654600114856L; + + private Long id; + + private String username; + + private String password; +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/restclient/UserClient.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/restclient/UserClient.java new file mode 100644 index 0000000..2d75906 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/restclient/UserClient.java @@ -0,0 +1,21 @@ +package cn.medear.springcloud.restclient; + +import org.springframework.cloud.netflix.feign.FeignClient; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import cn.medear.springcloud.entity.User; +import cn.medear.springcloud.restclient.failback.UserClientFailBack; + +/** + * @author Niu Li + * @since 2017/6/4 + */ +@FeignClient(name = "service-user-provider",fallbackFactory = UserClientFailBack.class) +public interface UserClient { + + @RequestMapping(value = "/{id}",method = RequestMethod.GET) + User findById(@PathVariable("id") Long id); + +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/restclient/failback/UserClientFailBack.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/restclient/failback/UserClientFailBack.java new file mode 100644 index 0000000..4004042 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/java/cn/medear/springcloud/restclient/failback/UserClientFailBack.java @@ -0,0 +1,40 @@ +package cn.medear.springcloud.restclient.failback; + +import org.springframework.stereotype.Component; + +import cn.medear.springcloud.entity.User; +import cn.medear.springcloud.restclient.UserClient; +import feign.hystrix.FallbackFactory; +import lombok.extern.slf4j.Slf4j; + +/** + * 用户调用断路器 + * @author Niu Li + * @since 2017/6/4 + */ +@Slf4j +@Component +public class UserClientFailBack implements FallbackFactory{ + + private static UserClient userClient = new UserClientFailBackWithInfo(); + + /** + * 错误返回内容配置 + */ + @Override + public UserClient create(Throwable throwable) { + log.error("UserClient hystrix open,error is {}",throwable.getMessage()); + return userClient; + } + + + private static class UserClientFailBackWithInfo implements UserClient{ + @Override + public User findById(Long id) { + User user = new User(); + user.setId(0L); + user.setUsername("失败用户"); + return user; + } + } +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/resources/application.yml b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/resources/application.yml new file mode 100644 index 0000000..729bcbe --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign-Hystrix/src/main/resources/application.yml @@ -0,0 +1,24 @@ +server: + port: 8086 + +spring: + application: + name: service-product-consumer-fegin-hystrix + +eureka: + client: + service-url: + default-zone: http://localhost:8761/eureka/ + instance: + prefer-ip-address: true + +#开启断路器 +feign: + hystrix: + enabled: true + +# 负载均衡配置为随机,不配置默认轮询 +service-user-provider: + ribbon: + NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule + diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign/pom.xml b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/pom.xml new file mode 100644 index 0000000..57785b7 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/pom.xml @@ -0,0 +1,30 @@ + + + + springcloud-parent + cn.mrdear.springcloud + 1.0.0 + + 4.0.0 + + cn.mrdear.springcloud + Service-Product-Consumer-Feign + + + + org.springframework.cloud + spring-cloud-starter-feign + + + io.github.openfeign + feign-httpclient + 9.5.0 + + + org.springframework.cloud + spring-cloud-starter-eureka + + + \ No newline at end of file diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/UserConsumeFeignApplication.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/UserConsumeFeignApplication.java new file mode 100644 index 0000000..7ad8139 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/UserConsumeFeignApplication.java @@ -0,0 +1,46 @@ +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.netflix.feign.EnableFeignClients; +import org.springframework.context.annotation.Bean; + + +/** + * @author Niu Li + * @since 2017/6/3 + */ +@SpringBootApplication(scanBasePackages = "cn.medear.springcloud.controller") +@EnableDiscoveryClient +@EnableFeignClients(basePackages = "cn.medear.springcloud.restclient") +public class UserConsumeFeignApplication { + + public static void main(String[] args) { + SpringApplication.run(UserConsumeFeignApplication.class, args); + } + + /** + * 自定义feign的Httpclient,其注入在HttpClientFeignLoadBalancedConfiguration中 + * @return + */ + @Bean + public HttpClient feignHttpClient() { + PoolingHttpClientConnectionManager HTTP_CLIENT_CONNECTION_MANAGER = + new PoolingHttpClientConnectionManager(RegistryBuilder.create().register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", SSLConnectionSocketFactory.getSocketFactory()).build()); + HTTP_CLIENT_CONNECTION_MANAGER.setDefaultMaxPerRoute(100); + HTTP_CLIENT_CONNECTION_MANAGER.setMaxTotal(200); + RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(60000).setConnectTimeout(60000).setSocketTimeout(60000).build(); + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setConnectionManager(HTTP_CLIENT_CONNECTION_MANAGER) + .setDefaultRequestConfig(requestConfig).build(); + return httpClient; + } +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/controller/ConsumeUserController.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/controller/ConsumeUserController.java new file mode 100644 index 0000000..e53e366 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/controller/ConsumeUserController.java @@ -0,0 +1,41 @@ +package cn.medear.springcloud.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import cn.medear.springcloud.entity.User; +import cn.medear.springcloud.restclient.UserClient; +import lombok.extern.slf4j.Slf4j; + +/** + * 用于消费UserService的类 + * @author Niu Li + * @since 2017/6/3 + */ +@RestController +@Slf4j +public class ConsumeUserController { + + @Resource + private UserClient userClient; + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + @GetMapping("/{id}") + public String findUserById(@PathVariable Long id) { + User user = userClient.findById(id); + String valueAsString = null; + try { + valueAsString = objectMapper.writeValueAsString(user); + } catch (JsonProcessingException e) { + log.error("parse json error. {}",e); + } + return valueAsString; + } +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/entity/User.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/entity/User.java new file mode 100644 index 0000000..2dc8e22 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/entity/User.java @@ -0,0 +1,25 @@ +package cn.medear.springcloud.entity; + +import java.io.Serializable; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * @author Niu Li + * @since 2017/6/3 + */ +@Data +@NoArgsConstructor +@ToString +public class User implements Serializable{ + + private static final long serialVersionUID = -2885884654600114856L; + + private Long id; + + private String username; + + private String password; +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/restclient/UserClient.java b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/restclient/UserClient.java new file mode 100644 index 0000000..28606ea --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/java/cn/medear/springcloud/restclient/UserClient.java @@ -0,0 +1,20 @@ +package cn.medear.springcloud.restclient; + +import org.springframework.cloud.netflix.feign.FeignClient; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import cn.medear.springcloud.entity.User; + +/** + * @author Niu Li + * @since 2017/6/4 + */ +@FeignClient("service-user-provider") +public interface UserClient { + + @RequestMapping(value = "/{id}",method = RequestMethod.GET) + User findById(@PathVariable("id") Long id); + +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/resources/application.yml b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/resources/application.yml new file mode 100644 index 0000000..a57867d --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Feign/src/main/resources/application.yml @@ -0,0 +1,23 @@ +server: + port: 8085 + +spring: + application: + name: service-product-consumer-fegin + +eureka: + client: + service-url: + default-zone: http://localhost:8761/eureka/ + instance: + prefer-ip-address: true + +feign: + httpclient: + enabled: true + +# 负载均衡配置为随机,不配置默认轮询 +service-user-provider: + ribbon: + NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule + diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/pom.xml b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/pom.xml new file mode 100644 index 0000000..5418098 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/pom.xml @@ -0,0 +1,22 @@ + + + + springcloud-parent + cn.mrdear.springcloud + 1.0.0 + + 4.0.0 + + cn.mrdear.springcloud + Service-Product-Consumer-Ribbon + + + + org.springframework.cloud + spring-cloud-starter-eureka + + + + \ No newline at end of file diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/UserConsumeApplication.java b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/UserConsumeApplication.java new file mode 100644 index 0000000..5366289 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/UserConsumeApplication.java @@ -0,0 +1,19 @@ +package cn.mrdear.springcloud; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @author Niu Li + * @since 2017/6/3 + */ +@SpringBootApplication +@EnableDiscoveryClient +public class UserConsumeApplication { + + public static void main(String[] args) { + SpringApplication.run(UserConsumeApplication.class,args); + } + +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/config/BeanConfig.java b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/config/BeanConfig.java new file mode 100644 index 0000000..13e312c --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/config/BeanConfig.java @@ -0,0 +1,22 @@ +package cn.mrdear.springcloud.config; + +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +/** + * @author Niu Li + * @since 2017/6/3 + */ +@Configuration +//@RibbonClient(name = "user-resporitory",configuration = MyConfig.class) +//可以指定针对某服务器采取指定的配置负载均衡算法,配置文件中配置更加方便 +public class BeanConfig { + + @Bean + @LoadBalanced //开启客户端负载均衡,自动配置类在LoadBalancerAutoConfiguration中 + public RestTemplate restTemplate(){ + return new RestTemplate(); + } +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/controller/ConsumeUserController.java b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/controller/ConsumeUserController.java new file mode 100644 index 0000000..a839637 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/java/cn/mrdear/springcloud/controller/ConsumeUserController.java @@ -0,0 +1,25 @@ +package cn.mrdear.springcloud.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; + +/** + * 用于消费UserService的类 + * @author Niu Li + * @since 2017/6/3 + */ +@RestController +public class ConsumeUserController { + + @Resource + private RestTemplate restTemplate; + + @GetMapping("/{id}") + public String findUserById(@PathVariable Long id) { + return restTemplate.getForObject("http://service-user-provider/"+id,String.class); + } +} diff --git a/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/resources/application.yml b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/resources/application.yml new file mode 100644 index 0000000..efa8d13 --- /dev/null +++ b/Spring-Cloud-Demo/Service-Product-Consumer-Ribbon/src/main/resources/application.yml @@ -0,0 +1,18 @@ +server: + port: 8082 + +spring: + application: + name: service-product-consumer-ribbon + +eureka: + client: + service-url: + default-zone: http://localhost:8761/eureka/ + instance: + prefer-ip-address: true + +# 负载均衡配置为随机,不配置默认轮询 +service-user-provider: + ribbon: + NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule diff --git a/Spring-Cloud-Demo/Service-User-Provider/pom.xml b/Spring-Cloud-Demo/Service-User-Provider/pom.xml new file mode 100644 index 0000000..e1b37bb --- /dev/null +++ b/Spring-Cloud-Demo/Service-User-Provider/pom.xml @@ -0,0 +1,47 @@ + + + + springcloud-parent + cn.mrdear.springcloud + 1.0.0 + + 4.0.0 + + cn.mrdear.springcloud + Service-User-Provider + + + + + com.h2database + h2 + runtime + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.cloud + spring-cloud-starter-eureka + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/UserApplication.java b/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/UserApplication.java new file mode 100644 index 0000000..acfdfec --- /dev/null +++ b/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/UserApplication.java @@ -0,0 +1,19 @@ +package cn.mrdear; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; + +/** + * @author Niu Li + * @since 2017/5/25 + */ +@EnableDiscoveryClient +@SpringBootApplication +public class UserApplication { + + public static void main(String[] args) { + SpringApplication.run(UserApplication.class,args); + } + +} diff --git a/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/controller/UserController.java b/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/controller/UserController.java new file mode 100644 index 0000000..4135af0 --- /dev/null +++ b/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/controller/UserController.java @@ -0,0 +1,61 @@ +package cn.mrdear.controller; + + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; +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.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +import javax.annotation.Resource; + +import cn.mrdear.entity.User; +import cn.mrdear.resporitory.UserResporitory; + +/** + * @author Niu Li + * @since 2017/5/25 + */ +@RestController +public class UserController { + + @Value("${spring.application.name}") + private String serverName; + + @Resource + private UserResporitory userResporitory; + + @Resource + private DiscoveryClient discoveryClient; + + @RequestMapping(value = "/add" ,method = RequestMethod.GET) + public User add(String username,String password) { + User user = new User(); + user.setUsername(username); + user.setPassword(password); + userResporitory.saveAndFlush(user); + return user; + } + + @GetMapping("/{id}") + public User find(@PathVariable Long id) { + return userResporitory.findOne(id); + } + + @GetMapping("/list") + public List findAll(){ + return userResporitory.findAll(); + } + + @GetMapping("/console") + public List console(){ + List instances = discoveryClient.getInstances(serverName); + return instances; + } + +} diff --git a/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/entity/User.java b/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/entity/User.java new file mode 100644 index 0000000..fb3e22c --- /dev/null +++ b/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/entity/User.java @@ -0,0 +1,32 @@ +package cn.mrdear.entity; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * @author Niu Li + * @since 2017/6/3 + */ +@Data +@NoArgsConstructor +@ToString +@Entity +public class User implements Serializable{ + + private static final long serialVersionUID = -2885884654600114856L; + + @Id + @GeneratedValue + private Long id; + + private String username; + + private String password; +} diff --git a/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/resporitory/UserResporitory.java b/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/resporitory/UserResporitory.java new file mode 100644 index 0000000..36ec6bd --- /dev/null +++ b/Spring-Cloud-Demo/Service-User-Provider/src/main/java/cn/mrdear/resporitory/UserResporitory.java @@ -0,0 +1,15 @@ +package cn.mrdear.resporitory; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import cn.mrdear.entity.User; + +/** + * @author Niu Li + * @since 2017/6/3 + */ +@Repository +public interface UserResporitory extends JpaRepository{ + +} diff --git a/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/application.yml b/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/application.yml new file mode 100644 index 0000000..dec0aa8 --- /dev/null +++ b/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/application.yml @@ -0,0 +1,20 @@ +server: + port: 8083 +spring: + application: + name: service-user-provider + jpa: + generate-ddl: false + show-sql: true + hibernate: + ddl-auto: none + datasource: + platform: h2 + schema: classpath:database/schema.sql + data: classpath:database/data.sql +eureka: + client: + service-url: + default-zone: http://localhost:8761/eureka/ + instance: + prefer-ip-address: true \ No newline at end of file diff --git a/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/database/data.sql b/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/database/data.sql new file mode 100644 index 0000000..8d203ef --- /dev/null +++ b/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/database/data.sql @@ -0,0 +1,3 @@ +INSERT INTO user(username,password) VALUES ('张三','111111'); +INSERT INTO user(username,password) VALUES ('李四','111111'); +INSERT INTO user(username,password) VALUES ('王二','111111'); \ No newline at end of file diff --git a/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/database/schema.sql b/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/database/schema.sql new file mode 100644 index 0000000..737b628 --- /dev/null +++ b/Spring-Cloud-Demo/Service-User-Provider/src/main/resources/database/schema.sql @@ -0,0 +1,6 @@ +drop table user if exists; +create table user ( + id INT(11) AUTO_INCREMENT PRIMARY KEY , + username VARCHAR(255), + password VARCHAR(255) + ); \ No newline at end of file diff --git a/Spring-Cloud-Demo/Service-User-Provider/target/classes/cn/mrdear/Application.class b/Spring-Cloud-Demo/Service-User-Provider/target/classes/cn/mrdear/Application.class new file mode 100644 index 0000000..0625b42 Binary files /dev/null and b/Spring-Cloud-Demo/Service-User-Provider/target/classes/cn/mrdear/Application.class differ diff --git a/Spring-Cloud-Demo/pom.xml b/Spring-Cloud-Demo/pom.xml new file mode 100644 index 0000000..9b0ac77 --- /dev/null +++ b/Spring-Cloud-Demo/pom.xml @@ -0,0 +1,74 @@ + + + 4.0.0 + + cn.mrdear.springcloud + springcloud-parent + pom + 1.0.0 + + + Service-Discovery-Eureka + Service-User-Provider + Service-Product-Consumer-Ribbon + Service-Product-Consumer-Feign + Service-Product-Consumer-Feign-Hystrix + + + + + org.springframework.boot + spring-boot-starter-parent + 1.5.2.RELEASE + + + + Dalston.SR1 + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.1 + + 1.8 + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-maven-plugin + + + + \ No newline at end of file diff --git a/Spring-Security-Demo/pom.xml b/Spring-Security-Demo/pom.xml new file mode 100644 index 0000000..034f981 --- /dev/null +++ b/Spring-Security-Demo/pom.xml @@ -0,0 +1,62 @@ + + + 4.0.0 + + cn.mrdear.security + Spring-Security-Demo + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 1.5.4.RELEASE + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + + io.jsonwebtoken + jjwt + 0.7.0 + + + org.projectlombok + lombok + + + org.apache.commons + commons-lang3 + 3.5 + + + com.google.guava + guava + 21.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + \ No newline at end of file diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/Application.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/Application.java new file mode 100644 index 0000000..a8425d5 --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/Application.java @@ -0,0 +1,17 @@ +package cn.mrdear.security; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Niu Li + * @since 2017/6/16 + */ +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/CommonBeanConfig.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/CommonBeanConfig.java new file mode 100644 index 0000000..bc1958e --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/CommonBeanConfig.java @@ -0,0 +1,23 @@ +package cn.mrdear.security.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import cn.mrdear.security.util.JwtTokenUtil; + +/** + * 配置一些线程安全的工具类 + * @author Niu Li + * @since 2017/6/28 + */ +@Configuration +public class CommonBeanConfig { + + /** + * 配置jwt token + */ + @Bean + public JwtTokenUtil configToken() { + return new JwtTokenUtil(); + } +} diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/CorsFilter.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/CorsFilter.java new file mode 100644 index 0000000..2babd09 --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/CorsFilter.java @@ -0,0 +1,40 @@ +package cn.mrdear.security.config; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.io.IOException; + + +public class CorsFilter implements javax.servlet.Filter { + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + System.err.println("CorsFilter"); + HttpServletResponse res = (HttpServletResponse) response; + HttpServletRequest req = (HttpServletRequest) request; + + res.setHeader("Access-Control-Allow-Origin", "*"); + res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS"); + res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Host, Referer, Connection, User-Agent, authorization, sw-useragent, sw-version"); + + // Just REPLY OK if request method is OPTIONS for CORS (pre-flight) + if (req.getMethod().equals("OPTIONS")) { + res.setStatus(HttpServletResponse.SC_OK); + return; + } + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } +} diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/SecurityConfig.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/SecurityConfig.java new file mode 100644 index 0000000..0c7f13a --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/SecurityConfig.java @@ -0,0 +1,64 @@ +package cn.mrdear.security.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.access.channel.ChannelProcessingFilter; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.context.NullSecurityContextRepository; + +import cn.mrdear.security.util.JwtTokenUtil; + +import javax.annotation.Resource; + +/** + * Spring Security配置类 + * @author Niu Li + * @since 2017/6/16 + */ +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Resource + private JwtTokenUtil jwtTokenUtil; + + /** + * 在此配置不过滤的请求 + */ + @Override + public void configure(WebSecurity web) throws Exception { + //每一个请求对应一个空的filter链,这里一般不要配置过多, + // 因为查找处是一个for循环,过多就导致每个请求都需要循环一遍直到找到 + web.ignoring().antMatchers("/","/login","/favicon.ico"); + } + + /** + * 在此配置过滤链 + */ + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + //角色定义,Spring Security会在其前面自动加上ROLE_,因此存储权限的时候也要加上ROLE_ADMIN + .antMatchers("/detail").access("hasRole('ADMIN')") + .anyRequest().permitAll().and() + //异常处理,可以再此使用entrypoint来定义错误输出 + .exceptionHandling().and() + //不需要session来控制,所以这里可以去掉 + .securityContext().securityContextRepository(new NullSecurityContextRepository()).and() + //开启匿名访问 + .anonymous().and() + //退出登录自己来控制 + .logout().disable() + //因为没用到cookies,所以关闭cookies + .csrf().disable() + //允许跨域 + .addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class) + //验证token + .addFilterBefore(new VerifyTokenFilter(jwtTokenUtil), + UsernamePasswordAuthenticationFilter.class); + } +} diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/VerifyTokenFilter.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/VerifyTokenFilter.java new file mode 100644 index 0000000..2054617 --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/config/VerifyTokenFilter.java @@ -0,0 +1,46 @@ +package cn.mrdear.security.config; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import cn.mrdear.security.util.JwtTokenUtil; +import io.jsonwebtoken.JwtException; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.Optional; + +/** + * jwt token验证类,验证成功后设置进去SecurityContext中 + * @author Niu Li + * @since 2017/6/28 + */ +@Slf4j +public class VerifyTokenFilter extends OncePerRequestFilter { + + private JwtTokenUtil jwtTokenUtil; + + public VerifyTokenFilter(JwtTokenUtil jwtTokenUtil) { + this.jwtTokenUtil = jwtTokenUtil; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + try { + Optional authentication = jwtTokenUtil.verifyToken(request); + log.debug("VerifyTokenFilter result: {}",authentication.orElse(null)); + SecurityContextHolder.getContext().setAuthentication(authentication.orElse(null)); + filterChain.doFilter(request,response); + } catch (JwtException e) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + //可以在这里指定重定向还是返回错误接口示例 + } + } +} diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/controller/LoginCntroller.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/controller/LoginCntroller.java new file mode 100644 index 0000000..488fc57 --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/controller/LoginCntroller.java @@ -0,0 +1,65 @@ +package cn.mrdear.security.controller; + +import com.google.common.collect.Lists; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import cn.mrdear.security.dto.TokenUserDTO; +import cn.mrdear.security.util.JwtTokenUtil; + +import javax.annotation.Resource; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * @author Niu Li + * @since 2017/6/19 + */ +@RestController +public class LoginCntroller { + + @Resource + private JwtTokenUtil jwtTokenUtil; + + /** + * 该链接获取token + */ + @GetMapping("/login") + public Map login(String username, String password) { + Map map = new HashMap<>(); + if (!StringUtils.equals(username, "demo") || !StringUtils.equals(password, "demo")) { + map.put("status", 4); + map.put("msg", "登录失败,用户名密码错误"); + return map; + } + TokenUserDTO userDTO = new TokenUserDTO(); + userDTO.setUsername(username); + userDTO.setRoles(Lists.newArrayList("ROLE_ADMIN")); + userDTO.setId(1L); + userDTO.setEmail("1015315668@qq.com"); + userDTO.setAvatar("ahahhahahhaha"); + map.put("status", 1); + map.put("msg", "Success"); + map.put("token", jwtTokenUtil.create(userDTO)); + return map; + } + + /** + * 该链接尝试获取登录用户,返回该认证用户的信息,请求该链接需要在header中放入x-authorization: token + */ + @GetMapping("/detail") + public TokenUserDTO userDetail() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (Objects.isNull(authentication)) { + return null; + } + return (TokenUserDTO) authentication.getDetails(); + } + +} diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/dto/TokenUserAuthentication.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/dto/TokenUserAuthentication.java new file mode 100644 index 0000000..188acfc --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/dto/TokenUserAuthentication.java @@ -0,0 +1,63 @@ +package cn.mrdear.security.dto; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import java.util.Collection; +import java.util.stream.Collectors; + +/** + * Spring Security中存放的认证用户 + * @author Niu Li + * @since 2017/6/28 + */ +public class TokenUserAuthentication implements Authentication { + + private static final long serialVersionUID = 3730332217518791533L; + + private TokenUserDTO userDTO; + + private Boolean authentication = false; + + public TokenUserAuthentication(TokenUserDTO userDTO, Boolean authentication) { + this.userDTO = userDTO; + this.authentication = authentication; + } + + @Override + public Collection getAuthorities() { + return userDTO.getRoles().stream() + .map(SimpleGrantedAuthority::new).collect(Collectors.toList()); + } + + @Override + public Object getCredentials() { + return ""; + } + + @Override + public Object getDetails() { + return userDTO; + } + + @Override + public Object getPrincipal() { + return userDTO.getUsername(); + } + + @Override + public boolean isAuthenticated() { + return authentication; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { + this.authentication = isAuthenticated; + } + + @Override + public String getName() { + return userDTO.getUsername(); + } +} diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/dto/TokenUserDTO.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/dto/TokenUserDTO.java new file mode 100644 index 0000000..a7abda4 --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/dto/TokenUserDTO.java @@ -0,0 +1,23 @@ +package cn.mrdear.security.dto; + +import lombok.Data; + +import java.util.List; + +/** + * @author Niu Li + * @since 2017/6/28 + */ +@Data +public class TokenUserDTO { + + private Long id; + + private String username; + + private String email; + + private String avatar; + + private List roles; +} diff --git a/Spring-Security-Demo/src/main/java/cn/mrdear/security/util/JwtTokenUtil.java b/Spring-Security-Demo/src/main/java/cn/mrdear/security/util/JwtTokenUtil.java new file mode 100644 index 0000000..91fcecc --- /dev/null +++ b/Spring-Security-Demo/src/main/java/cn/mrdear/security/util/JwtTokenUtil.java @@ -0,0 +1,91 @@ +package cn.mrdear.security.util; + +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; + +import cn.mrdear.security.dto.TokenUserAuthentication; +import cn.mrdear.security.dto.TokenUserDTO; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; + +import javax.servlet.http.HttpServletRequest; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +/** + * jwt token + * + * @author Niu Li + * @since 2017/6/28 + */ +public class JwtTokenUtil { + /** + * token过期时间 + */ + private static final long VALIDITY_TIME_MS = 24 * 60 * 60 * 1000; // 24 hours validity + /** + * header中标识 + */ + private static final String AUTH_HEADER_NAME = "x-authorization"; + + /** + * 签名密钥 + */ + @Value("${jwt.token.secret}") + private String secret; + + /** + * 验签 + */ + public Optional verifyToken(HttpServletRequest request) { + final String token = request.getHeader(AUTH_HEADER_NAME); + if (token != null && !token.isEmpty()){ + final TokenUserDTO user = parse(token.trim()); + if (user != null) { + return Optional.of(new TokenUserAuthentication(user, true)); + } + } + return Optional.empty(); + } + + + /** + * 从用户中创建一个jwt Token + * + * @param userDTO 用户 + * @return token + */ + public String create(TokenUserDTO userDTO) { + return Jwts.builder() + .setExpiration(new Date(System.currentTimeMillis() + VALIDITY_TIME_MS)) + .setSubject(userDTO.getUsername()) + .claim("id", userDTO.getId()) + .claim("avatar", userDTO.getAvatar()) + .claim("email", userDTO.getEmail()) + .claim("roles", userDTO.getRoles()) + .signWith(SignatureAlgorithm.HS256, secret) + .compact(); + } + + /** + * 从token中取出用户 + */ + public TokenUserDTO parse(String token) { + Claims claims = Jwts.parser() + .setSigningKey(secret) + .parseClaimsJws(token) + .getBody(); + TokenUserDTO userDTO = new TokenUserDTO(); + userDTO.setId(NumberUtils.toLong(claims.getId())); + userDTO.setAvatar(claims.get("avatar",String.class)); + userDTO.setUsername(claims.get("username",String.class)); + userDTO.setEmail(claims.get("email",String.class)); + userDTO.setRoles((List) claims.get("roles")); + return userDTO; + } + +} diff --git a/Spring-Security-Demo/src/main/resources/application.properties b/Spring-Security-Demo/src/main/resources/application.properties new file mode 100644 index 0000000..07419b0 --- /dev/null +++ b/Spring-Security-Demo/src/main/resources/application.properties @@ -0,0 +1,8 @@ +server.port=8080 + +logging.level.root=info +logging.level.org.springframework.security=debug + + +# jwt token签名密钥 +jwt.token.secret=quding2017 \ No newline at end of file