一.开启nacos 和redis
1.查看nacos和redis是否启动
docker ps
2.查看是否安装nacos和redis
docker ps -a
3.启动nacos和redis
docker start nacos
docker start redis-6379
docker ps
二.使用SpringSession共享例子
这里的两个例子在我的一个博客有创建过程,我就不再创建了。
对两个共享做出一点修改
1.对springsessiondemo做修改
2.1.1.添加实体类 Score
java
package com.jr.entry;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
@Component
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Score {
private String name;
private Double score;
}
2.1.2添加实体类 UserDto
java
package com.jr.entry;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Component
@Data
public class UserDto {
private String id;
private String name;
private String password;
private List<Score> scoreList;
}
2.1 3.添加接口 IUserService
java
package com.jr.service;
import com.jr.entry.UserDto;
public interface IUserService {
public UserDto info();
}
4.添加接口实现类 UserServiceImpl
java
package com.jr.service.impl;
import com.jr.entry.UserDto;
import com.jr.service.IUserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements IUserService {
@Override
public UserDto info() {
return new UserDto();
}
}
5添加 UserController 类
java
package com.jr.controller;
import com.jr.entry.UserDto;
import com.jr.service.IUserService;
import com.jr.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
@GetMapping
public Result info(){
UserDto userDto=userService.info();
return Result.ok().put("data",userDto);
}
}
6.添加枚举 ResultCode(为了更规范化)
java
package com.jr.util;
public enum ResultCode {
SUCCESS(0, "请求成功"),
ERROR(1, "请求失败"),
;
private int code;
private String message;
ResultCode(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
7.添加工具类 Result (为了更规范化)
java
package com.jr.util;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class Result {
private Integer code;
private String message;
private Map<String, Object> map = new HashMap<>();
private Result() {
}
public static Result ok() {
Result r = new Result();
r.setCode(ResultCode.SUCCESS.getCode());
r.setMessage(ResultCode.SUCCESS.getMessage());
return r;
}
public static Result error() {
Result r = new Result();
r.setCode(ResultCode.ERROR.getCode());
r.setMessage(ResultCode.ERROR.getMessage());
return r;
}
public Result put(String key, Object value) {
map.put(key, value);
return this;
}
public Object get(String key) {
return map.get(key);
}
}
8.修改application.properties文件中,项目注册名字:
spring.application.name=openfeignDemo1
java
spring.application.name=openfeignDemo1
2.对sessiondemo1做改动
1.添加实体类 Score
java
package com.jr.entry;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
@Component
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Score {
private String name;
private Double score;
}
2.2.添加实体类 UserDto
java
package com.jr.entry;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Component
@Data
public class UserDto {
private String id;
private String name;
private String password;
private List<Score> scoreList;
}
3.添加接口 IScoreService
java
package com.jr.service;
import com.jr.entry.Score;
import java.util.List;
public interface IScoreService {
public List<Score> info();
}
4.添加接口实现类 ScoreServiceImpl
java
package com.jr.service.impl;
import com.jr.entry.Score;
import com.jr.service.IScoreService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ScoreServiceImpl implements IScoreService {
@Override
public List<Score> info() {
List<Score> result = new ArrayList<>();
for (int i=0;i<3;i++){
Score score=new Score();
score.setName("name"+i);
score.setScore(Math.random()*10);
result.add(score);
}
return result;
}
}
5.添加 ScoreController类
java
@RestController
@RequestMapping("/score")
public class ScoreController {
@Autowired
private IScoreService scoreService;
@GetMapping("/info")
public Result info(){
List<Score> list=scoreService.info();
return Result.ok().put("list",list);
}
}
6.添加枚举 ResultCode
java
package com.jr.util;
public enum ResultCode {
SUCCESS(0, "请求成功"),
ERROR(1, "请求失败"),
;
private int code;
private String message;
ResultCode(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
7.添加工具类 Result
java
package com.jr.util;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class Result {
private Integer code;
private String message;
private Map<String, Object> map = new HashMap<>();
private Result() {
}
public static Result ok() {
Result r = new Result();
r.setCode(ResultCode.SUCCESS.getCode());
r.setMessage(ResultCode.SUCCESS.getMessage());
return r;
}
public static Result error() {
Result r = new Result();
r.setCode(ResultCode.ERROR.getCode());
r.setMessage(ResultCode.ERROR.getMessage());
return r;
}
public Result put(String key, Object value) {
map.put(key, value);
return this;
}
public Object get(String key) {
return map.get(key);
}
}
8.8.修改application.properties文件中,项目注册名字:
spring.application.name=openfeignDemo2
java
spring.application.name=openfeignDemo2
三.启动两个项目(同时)
如果遇到socket closed问题,可能是哪个项目端口冲突了,改了就行
1.第一个项目
2.第二个项目
nacos网站里
四.实现http请求管理
我们想要在第一个项目里面查询用户信息的同时也能访问第二个项目的成绩集合。
1.两个项目都向pom.xml添加依赖
XML
<!-- feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.2.在 "用户项目" 里(第一个项目),添加一个接口
定义了Feign接口,接口中的方法和对应服务端Controller方法一样,两点不同
RequestMapping注解的值要求全路径,包括controller上和方法上的注解地址拼接到一起
添加FeignClient注解,参数是服务端微服务的名称
java
package com.jr.feign;
import com.jr.util.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
@Component
@FeignClient("openfeignDemo2")
public interface ScoreFeign {
@GetMapping("/score/info")
public Result info();
}
3.改动UserServiceImpl实现类
java
package com.jr.service.impl;
import com.jr.entry.Score;
import com.jr.entry.UserDto;
import com.jr.feign.ScoreFeign;
import com.jr.service.IUserService;
import com.jr.util.Result;
import com.jr.util.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private ScoreFeign scoreFeign;
@Override
public UserDto info() {
UserDto userDto=new UserDto();
userDto.setId("10");
userDto.setName("奥特曼");
userDto.setPassword("123456");
Result result=scoreFeign.info();
if(result.getCode() == ResultCode.SUCCESS.getCode()){
userDto.setScoreList((List<Score>) result.get("list"));
}
return userDto;
}
}
4.4.启动类添加注解 @EnableFeignClients
java
package com.jr;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
@SpringBootApplication
@EnableRedisHttpSession
@EnableFeignClients //开始OPenFeign
public class SpringBootMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class,args);
}
}
5.启动两个项目 (同时)
第一个项目:
第二个项目:
四.添加请求头
1.改第一个项目的控制层UserController
2.修改第二个项目控制器方法,添加了请求头的获得
3.启动项目,使用postman进行测试
1234356是我自己设置的,可以自己设置(但是不能是汉字,可以是大小写字母和数字)
第一个项目的控制台(这里两个是因为我点了两次,实际只有一个)
第二个项目的控制台(这里两个是因为我点了两次,实际只有一个)
4.创建拦截器
第一个项目的header为123456,但是第二个项目的后台为null。
4.4.1在第一个项目创建拦截器类
java
package com.jr.interceptor;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Configuration
public class RequestHeaderInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return;
}
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String test = request.getHeader("test");
template.header("test", test);
}
}
4.4.2然后重新启动两个项目,用postman工具测试
没有什么要改的postman,直接send,主要是看控制台。
第一个项目的结果,没啥变化
第二个项目的结果,发生了变化。header不是null,而是123456。
五.参数传递
1.第一个项目下的对应的IUserService
接口,添加两个方法
java
UserDto add(UserDto user);
UserDto id(String id);
2.在第一个项目下的UserController里添加如下代码
java
@GetMapping("/{id}")
public Result id(@PathVariable String id) { //url传值
UserDto userDto = userService.id(id);
return Result.ok().put("data", userDto);
}
@PostMapping("/add")
public Result add(@RequestBody UserDto user) { //对象传值
UserDto userDto = userService.add(user);
return Result.ok().put("data", userDto);
}
3. feign接口, 在第一个项目下的ScoreFeign接口里,添加如下代码
java
@GetMapping("/score/{id}")
Result id(@PathVariable String id);
@PostMapping("/score/add")
Result add(@RequestBody UserDto user);
4.第一个项目对应的接口实现类,重写两个方法
java
@Override
public UserDto add(UserDto user) {
UserDto userDto=new UserDto();
Result result=scoreFeign.add(user);
if(result.getCode() == ResultCode.SUCCESS.getCode()){
UserDto resultUser= JSON.parseObject(JSON.toJSONString(result.get("data")),UserDto.class);
System.out.println(resultUser);
BeanUtils.copyProperties(resultUser,userDto);
}
return userDto;
}
@Override
public UserDto id(String id) {
UserDto userDto=new UserDto();
Result result=scoreFeign.id(id);
if(result.getCode() == ResultCode.SUCCESS.getCode()){
userDto.setId((String)result.get("id"));
}
return userDto;
}
5.为第二个项目的下的UserController里,添加如下代码
java
@GetMapping("/{id}")
public Result id(@PathVariable String id) {
return Result.ok().put("id", id);
}
@PostMapping("/add")
public Result add(@RequestBody UserDto user) {
return Result.ok().put("data", user);
}
6.启动测试,用postman工具进行测试
5.6.1先用get方法来url传值
5.6.2在用post方法传对象
下面结果是我网卡了,没出来第二张图是对的。
六.我的项目结构
1.第一个项目
2.第二个项目
七.注意
本博客中的四和五大点,中
第一个项目的业务类中的
都和第一个项目,第二个项目的对应