真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

[Springcloud一步步實現(xiàn)廣告系統(tǒng)]6.Service實現(xiàn)&Zuul配置&Test

DAO層設計實現(xiàn)

這里我們使用Spring DATA JPA來實現(xiàn)數(shù)據(jù)庫操作,當然大家也可以使用Mybatis,都是一樣的,我們依然以用戶表操作為例:

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:國際域名空間、虛擬主機、營銷軟件、網(wǎng)站建設、新干網(wǎng)站維護、網(wǎng)站推廣。

/**
 * AdUserRepository for 用戶數(shù)據(jù)庫操作接口
 * 繼承自JpaRepository,第一個參數(shù)AdUser代表當前要操作的實體類的class定義,第二個參數(shù)Long表示該類的主鍵類型
 *
 * @author Isaac.Zhang
 */

public interface AdUserRepository extends JpaRepository { 
    /**
     * 根據(jù)用戶名稱獲取用戶
     *
     * @param username 名稱
     * @return 用戶對象
     */
    AdUser findByUserName(String username);

    List findAllByUserName(String userName);
}
  • JPARepository 的默認實現(xiàn)方法,如果我們只是繼承了JpaRepository而沒有實現(xiàn)具體的操作方法,我們也是可以通過使用它的默認方法來做CRUD操作的,如下:

    [Spring cloud 一步步實現(xiàn)廣告系統(tǒng)] 6. Service實現(xiàn)&Zuul配置&Test

功能Service實現(xiàn)

創(chuàng)建service package,依然以用戶操作為例,創(chuàng)建com.sxzhongf.ad.service.IUserServicecom.sxzhongf.ad.service.impl.UserServiceImpl,UserServiceImpl實現(xiàn)了IUserService

  1. 創(chuàng)建 IUserService 接口
/**
 * IUserService for 用戶service
 *
 * @author Isaac.Zhang | 若初
 */
public interface IUserService {
    /**
     * 創(chuàng)建用戶接口
     *
     * @param userRequestVO {@link UserRequestVO}
     * @return {@link UserResponseVO}
     * @throws AdException 錯誤
     */
    UserResponseVO createUser(UserRequestVO userRequestVO) throws AdException;

    List findAllByUserName(String userName);
}
  1. 使用IUserService接口
/**
 * UserServiceImpl for 用戶service
 *
 * @author Isaac.Zhang | 若初
 */
@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    private final AdUserRepository userRepository;

    @Autowired
    public UserServiceImpl(AdUserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * 創(chuàng)建用戶
     *
     * @param userRequestVO {@link UserRequestVO}
     * @return result {@link UserResponseVO}
     */
    @Override
    @Transactional
    public UserResponseVO createUser(UserRequestVO userRequestVO) throws AdException {
        if (!userRequestVO.validate()) {
            log.error("Request params error: {}", userRequestVO);
            throw new AdException(Constants.ErrorMessage.REQUEST_PARAM_ERROR);
        }
        //查重
        AdUser existUser = userRepository.findByUserName(userRequestVO.getUserName());
        if (existUser != null) {
            log.error("{} user is not exist.", userRequestVO.getUserName());
            throw new AdException(Constants.ErrorMessage.USER_EXIST);
        }
        AdUser user = userRepository.save(new AdUser(userRequestVO.getUserName(), CommonUtils.md5(userRequestVO.getUserName())));
        log.info("current user is : {}", user);
        return new UserResponseVO(user.getUserId(), user.getUserName(), user.getToken(),
                user.getCreateTime(), user.getUpdateTime());
    }

    @Override
    public List findAllByUserName(String userName) {
        return userRepository.findAllByUserName(userName);
    }
}
  1. 創(chuàng)建數(shù)據(jù)傳輸對象(dto/vo)

    其實好多人在這里都會特別郁悶,搞不清楚這些命名有什么區(qū)別,個人建議是大家不用糾結,dto(data transfer object),就是表示我們在各個層傳遞的對象,vo在展示層操作的對象。但是這個只是個命名,它的本質就是一個object, 你傳遞到DAO層可以嗎?當然可以,你傳單獨字段都是可以的。所以,沒必要過分糾結這種信息,咬文嚼字有時候反而會適得其反。

/**
 * UserRequestVO for 創(chuàng)建用戶請求對象VO
 *
 * @author Isaac.Zhang | 若初
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRequestVO {
    private String userName;
    public boolean validate() {
        return !StringUtils.isEmpty(userName);
    }
}

---

/**
 * UserResponseVO for 用戶響應VO
 *
 * @author Isaac.Zhang | 若初
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserResponseVO {
    private Long userId;
    private String userName;
    private String token;
    private Date createTime;
    private Date updateTime;
}
  1. 因為報錯信息有可能是相同的,那我們抽取一個常量類來封裝。
/**
 * Constants for TODO
 *
 * @author Isaac.Zhang | 若初
 */
public class Constants {
    /**
     * 通用錯誤信息異常類
     */
    public static class ErrorMessage {
        public static final String REQUEST_PARAM_ERROR = "請求參數(shù)異常";
        public static final String USER_EXIST = "用戶已存在";
        public static final String USER_NOT_EXIST = "用戶不存在";
    }
}
  1. 在Common Project 下面創(chuàng)建一個工具類com.sxzhongf.ad.common.utils.CommonUtils,用來對用戶username進行md5加密來獲取token信息。
/**
 * CommonUtils for 工具類
 *
 * @author Isaac.Zhang | 若初
 */
@Slf4j
public class CommonUtils {
    /**
     * md5 加密
     */
    public static String md5(String value) {
        return DigestUtils.md5Hex(value).toUpperCase();
    }
}

參考創(chuàng)建用戶的實現(xiàn),依次實現(xiàn)其他表操作。

Controller實現(xiàn)

依然以用戶功能實現(xiàn)為例:

/**
 * UserController for 用戶controller
 *
 * @author Isaac.Zhang | 若初
 */
@RestController
@Slf4j
@RequestMapping("/user")
public class UserController {
    @Autowired
    private IUserService userService;

    @PostMapping(path = "/create")
    public UserResponseVO createUser(@RequestBody UserRequestVO requestVO) throws AdException {
        log.info("ad-sponsor: createUser -> {}", JSON.toJSONString(requestVO));
        return userService.createUser(requestVO);
    }

    @GetMapping(path = "/get")
    public CommonResponse getUserList(@Param(value = "username") String username) throws AdException {
        log.info("ad-sponsor: getUserList -> {}", JSON.toJSONString(username));
        return new CommonResponse(userService.findAllByUserName(username));
    }
}
在網(wǎng)關中配置廣告投放系統(tǒng)

我們在投放系統(tǒng)的配置中,配置了server.servlet.context-path:/ad-sponsor這么一個路徑,意味著所有請求當前系統(tǒng)的路徑都需要帶有ad-sponsor, 例如:http://xxx/ad-sponsor/user/get?username=yyy,這是網(wǎng)關請求所必需的。根據(jù)上述,我們在網(wǎng)關服務中配置我們當前的投放系統(tǒng):

spring:
  application:
    name: ad-gateway-zuul
server:
  port: 1111
eureka:
  client:
    service-url:
      defaultZone: http://server1:7777/eureka/,http://server2:8888/eureka/,http://server3:9999/eureka/
  instance:
    hostname: ad-gateway-zuul
##############################################
# 以下為重要信息
zuul:
  ignored-services: '*' # 過濾所有請求,除了下面routes中聲明過的服務
  # 配置網(wǎng)關路由規(guī)則
  routes:
    sponsor: #在路由中自定義服務路由名稱
      path: /ad-sponsor/**
      serviceId: mscx-ad-sponsor #微服務name
      strip-prefix: false
    search: #在路由中自定義服務路由名稱
      path: /ad-search/**
      serviceId: mscx-ad-search #微服務name
      strip-prefix: false
  prefix: /gateway/api
  strip-prefix: false #不對 prefix: /gateway/api 設置的路徑進行截取,默認轉發(fā)會截取掉配置的前綴
Test
  • 直接訪問投放系統(tǒng)

    調用curl -G http://localhost:7000/ad-sponsor/user/get?username=Isaac%20Zhang,返回結果:

{
  code: 0,  // 統(tǒng)一成功標示
  message: "success", // 統(tǒng)一處理結果message
  data: [  // 具體的對象信息
    {
      userId: 10,
      userName: "Isaac Zhang",
      token: "2D3ABB6F2434109A105170FB21D00453",
      userStatus: 1,
      createTime: 1561118873000,
      updateTime: 1561118873000
    }
  ]
}
  • 通過網(wǎng)關調用

    因為我在網(wǎng)關配置中加了前綴prefix: /gateway/api,因此,我們訪問的時候需要添加上這個前綴信息,否則會報404錯誤。

    curl -G http://localhost:1111/gateway/api/ad-sponsor/user/get?username=Isaac%20Zhang,我們發(fā)現(xiàn)結果并沒有按照我們想象的展示出來。

    bogon:~ zhangpan$ http://localhost:1111/gateway/api/ad-sponsor/user/get?username=Isaac%20Zhang
    -bash: http://localhost:1111/gateway/api/ad-sponsor/user/get?username=Isaac%20Zhang: No such file or directory

    為什么呢?我們來查看一下日志:

    2019-07-27 20:44:19.093  INFO 4766 --- [nio-1111-exec-4] c.s.a.g.filter.ValidateTokenFilter       : GET request to http://localhost:1111/gateway/api/ad-sponsor/user/get
    2019-07-27 20:44:19.093  WARN 4766 --- [nio-1111-exec-4] c.s.a.g.filter.ValidateTokenFilter       : access token is empty
    2019-07-27 20:44:19.098  INFO 4766 --- [nio-1111-exec-4] c.s.ad.gateway.filter.AccessLogFilter    : Request "/gateway/api/ad-sponsor/user/get" spent : 0 seconds.
    2019-07-27 20:48:37.801  INFO 4766 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver      : Resolving eureka endpoints via configuration

    我們可以清晰的看到,ValidateTokenFilter : access token is empty,為什么會有這么一個報錯呢?那是因為我在配置網(wǎng)關的時候,添加了一次攔截:

    /**
    * ValidateTokenFilter for 服務token校驗
    *
    * @author Isaac.Zhang
    */
    @Slf4j
    @Component
    public class ValidateTokenFilter extends ZuulFilter {
    ...
      @Override
      public Object run() throws ZuulException {
          RequestContext ctx = RequestContext.getCurrentContext();
          HttpServletRequest request = ctx.getRequest();
          log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
    
          Object accessToken = request.getHeader("accessToken"); //.getParameter("accessToken");
          if (accessToken == null) {
              log.warn("access token is empty");
              ctx.setSendZuulResponse(false);
              ctx.setResponseStatusCode(401);
    //            ctx.setResponseBody(body)對返回body內容進行編輯
              return null;
          }
          log.info("access token ok");
          return null;
      }
    }

    觀察代碼我們發(fā)現(xiàn),會從RequestHeader中獲取accessToken參數(shù),我們沒有提供,當然就會報錯了呀。接下來,我們提供上該參數(shù)再試:

    bogon:~ zhangpan$ curl -H "accessToken:true" http://localhost:1111/gateway/api/ad-sponsor/user/get?username=Isaac%20Zhang
    ---返回
    {"code":0,"message":"success","data":[{"userId":10,"userName":"Isaac Zhang","token":"2D3ABB6F2434109A105170FB21D00453","userStatus":1,"createTime":1561118873000,"updateTime":1561118873000}]}

    至此,我們的廣告投放系統(tǒng)簡單功能已經全部實現(xiàn)完畢,并且可以通過網(wǎng)關進行轉發(fā)。


本文標題:[Springcloud一步步實現(xiàn)廣告系統(tǒng)]6.Service實現(xiàn)&Zuul配置&Test
分享網(wǎng)址:http://weahome.cn/article/ihdghc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部