2018年4月9日 星期一

Sprig Cloud(五):Feign




簡介


快速入門


restTemplate.getForObject("http://flim-user/"+id,User.class);

Map map = new HashMap();map.put("name","張三");map.put("username","account1");map.put("age",20);this.restTemplate.getForObject(" http://localhost:8010/search?name=name&username=username&age=age",User[].class,map);

服務消費者整合 Feign


org.springframework.cloudspring-cloud-starter-feign1.4.4.RELEASE

@FeignClient(name = "film-user") // 服務提供者名稱public interface UserFeignClient @GetMapping("/id") UserEntity findById(@PathVariable("id") int id);


  • 由於使用 Eureka,film-user 會被解析成 Eureka Server 中註冊的微服務,若不想使用 Eureka,可以使用 service.ribbon.listOfServers 屬性配置服務列表




  • 還可使用 url 屬性指定請求 URL



@FeignClient(name = "film-user",url = "http://localhost:8080")

@Autowiredprivate UserFeignClient userFeignClient;@GetMapping("/user/id")public UserEntity findById(@PathVariable int id) return userFeignClient.findById(id);

自定義 Feign 配置


@Configurationpublic class FeignConfiguration //使用Feign自帶的註解 @Bean public Contract feignContract() return new feign.Contract.Default(); 

@FeignClient(name = "film-user",configuration = FeignConfiguration.class)public interface UserFeignClient //使用Feign自帶的註解@RequestLine @RequestLine("GET /id") UserEntity findById(@PathVariable("id") int id);

手動建立 Feign


修改服務提供者


org.springframework.bootspring-boot-starter-security

@[email protected]@EnableGlobalMethodSecurity(prePostEnabled = true)public class SecurityConfig extends WebSecurityConfigurerAdapter @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception auth.inMemoryAuthentication() .withUser("user").password("password1").roles("USER") .and() .withUser("admin").password("password2").roles("ADMIN") .and() .passwordEncoder(this.passwordEncoder()); @Override protected void configure(HttpSecurity http) throws Exception //所有請求都要經過httpBasic認證 http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); @Bean public PasswordEncoder passwordEncoder() //返回一個明文密碼器,Spring 提供給我們做明文測試的 return NoOpPasswordEncoder.getInstance(); 

@RestControllerpublic class UserController @Autowired private UserRepository userRepository; private final Logger log = LoggerFactory.getLogger(UserController.class); @GetMapping("/id") public User findById(@PathVariable int id) Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); org.springframework.security.core.userdetails.User principal = (org.springframework.security.core.userdetails.User) authentication.getPrincipal(); Collection extends GrantedAuthority> authorities = authentication.getAuthorities(); log.info("當前的使用者是,角色是",principal.getUsername(),authorities.stream() .map((GrantedAuthority e) -> e.getAuthority()).collect(Collectors.joining(","))); User user = userRepository.findOne(id); return user; 

 com.linyuan.controller.UserController : 當前的使用者是user,角色是ROLE_USER com.linyuan.controller.UserController : 當前的使用者是admin,角色是ROLE_ADMIN

修改服務消費者



  • 去掉介面 UserFeignClient 上的 @FeignClient 註解,去掉啟動類上的 @EnableFeignClients 註解




  • 修改 Controller,通過 @Import 導 FeignClientsConfiguration,FeignClientsConfiguration 是 Spring Cloud 為 Feign 提供的預設配置,這裏 userFeignClient 登入賬號是 user,adminFeignClient 登入賬號是 admin,它們使用的是同一個介面




@Import(FeignClientsConfiguration.class)@RestControllerpublic class MovieController private UserFeignClient adminFeignClient; private UserFeignClient userFeignClient; @Autowired public MovieController(Decoder decoder, Encoder encoder, Client client, Contract contract) this.userFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract) .requestInterceptor(new BasicAuthRequestInterceptor("user","password1")) .target(UserFeignClient.class,"http://film-user/"); this.adminFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract) .requestInterceptor(new BasicAuthRequestInterceptor("admin","password2")) .target(UserFeignClient.class,"http://film-user/"); @GetMapping("/user/id") public UserEntity findByIdUser(@PathVariable int id) return userFeignClient.findById(id); @GetMapping("/admin/id") public UserEntity findByIdAdmin(@PathVariable int id) return adminFeignClient.findById(id); 


  • 測試:


    com.linyuan.controller.UserController : 當前的使用者是user,角色是ROLE_USERcom.linyuan.controller.UserController : 當前的使用者是admin,角色是ROLE_ADMIN



    • 啟動 Eureka Server、film-user、film-consumer





    • 訪問 http://localhost:8010/user/1 與 http://localhost:8010/admin/1 可看到控制檯輸出不同結果



Feign 對壓縮的支援


feign.compression.request.enabled = truefeign.compression.response.enabled = true

feign.compression.request.enabled = truefeign.compression.request.mine-types = text/xml,application/xml,application/json #預設配置feign.compression.request.min-request-size = 2048 #預設配置

Feign 日誌



  • Feign 對日誌的處理非常靈活,可為每個 Feign 客戶端指定日誌策略,每個 Feign 客戶端都會建立一個 Logger,預設名稱為 Feign 介面的完整類名,但 Feign 日誌列印只會對 DEBUG 級別做出響應




  • 我們可為每個 Feign 客戶端配置各自的 Logger.level 物件,告訴 Feign 記錄哪些日誌,Logger.Level 的值有以下選擇:




    • NONE:不記錄任何日誌(預設)




    • BASIC:僅記錄請求方法、URL、響應狀態碼以及執行時間




    • HEADERS:記錄 BASIC 級別的基礎上,記錄請求和響應的 header




    • FULL:記錄請求響應的 header、body 和後設資料




  • 編寫 Feign 配置類



@Configurationpublic class FeignConfiguration @Bean public Logger.Level feignLoggerLevel() return Logger.Level.BASIC; 

@FeignClient(name = "film-user",configuration = FeignConfiguration.class)public interface UserFeignClient @RequestMapping(value = "/id", method = RequestMethod.GET) UserEntity findById(@PathVariable("id") int id);

logging: level: com.linyuan.request.UserFeignClient: DEBUG #Feign的Logger.Level只對DEBUG作出響應/

2017-12-22 11:41:34.387 DEBUG 7405 --- [nio-8010-exec-3] com.linyuan.request.UserFeignClient : [UserFeignClient#findById] ---> GET http://flim-user/1 HTTP/1.12017-12-22 11:41:34.395 DEBUG 7405 --- [nio-8010-exec-3] com.linyuan.request.UserFeignClient : [UserFeignClient#findById] GET http://flim-user/1 HTTP/1.12017-12-22 11:41:35.012 DEBUG 7405 --- [nio-8010-exec-5] com.linyuan.request.UserFeignClient : [UserFeignClient#findById] GET http://flim-user/1 HTTP/1.12017-12-22 11:41:35.602 DEBUG 7405 --- [nio-8010-exec-4] com.linyuan.request.UserFeignClient : [UserFeignClient#findById] 

Feign 構造多引數請求


GET 請求多引數



  • 假設請求 URL 包含多個引數,如:http://flim-user/get?id=1&username=張三,因為 Feign 支援 SpringMVC 註解,則寫法可以為:



    @FeignClient(name = "film-user")public interface UserFeignClient @RequestMapping(value = "/get", method = RequestMethod.GET) UserEntity get1(@RequestParam("id") int id,@RequestParam("username")String username);

    @RequestMapping(value = "/get", method = RequestMethod.GET)User get2(@RequestParam Map map);

    public User get(String username,String password) HashMap map = Maps.newHashMap(); map.put("id",1); map.put("username","張三"); return this.userUserFeignClient.get2(map);


POST 請求多引數


@RestControllerpublic class UserController @PostMapping("/post") public User post (@RequestBody User user) ... 

@FeignClient(name = "flim-user")public interface UserFeignClient @RequestMapping(value = "/post", method = RequestMethod.POST) UserEntity post(@RequestBody User user);




http://www.kubonews.com/2018040912618.html

生活苦悶?快上酷播亮新聞:http://www.kubonews.com

沒有留言:

張貼留言