91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

[Spring cloud 一步步實現廣告系統] 6. Service實現&Zuul配置&Test

發布時間:2020-07-28 23:24:02 來源:網絡 閱讀:299 作者:zhangpan0614 欄目:編程語言
DAO層設計實現

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

/**
 * AdUserRepository for 用戶數據庫操作接口
 * 繼承自JpaRepository<AdUser, Long>,第一個參數AdUser代表當前要操作的實體類的class定義,第二個參數Long表示該類的主鍵類型
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang</a>
 */

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

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

    [Spring cloud 一步步實現廣告系統] 6. Service實現&Zuul配置&Test

功能Service實現

創建service package,依然以用戶操作為例,創建com.sxzhongf.ad.service.IUserServicecom.sxzhongf.ad.service.impl.UserServiceImpl,UserServiceImpl實現了IUserService

  1. 創建 IUserService 接口
/**
 * IUserService for 用戶service
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 */
public interface IUserService {
    /**
     * 創建用戶接口
     *
     * @param userRequestVO {@link UserRequestVO}
     * @return {@link UserResponseVO}
     * @throws AdException 錯誤
     */
    UserResponseVO createUser(UserRequestVO userRequestVO) throws AdException;

    List<AdUser> findAllByUserName(String userName);
}
  1. 使用IUserService接口
/**
 * UserServiceImpl for 用戶service
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 */
@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    private final AdUserRepository userRepository;

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

    /**
     * 創建用戶
     *
     * @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<AdUser> findAllByUserName(String userName) {
        return userRepository.findAllByUserName(userName);
    }
}
  1. 創建數據傳輸對象(dto/vo)

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

/**
 * UserRequestVO for 創建用戶請求對象VO
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserRequestVO {
    private String userName;
    public boolean validate() {
        return !StringUtils.isEmpty(userName);
    }
}

---

/**
 * UserResponseVO for 用戶響應VO
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 */
@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 <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 */
public class Constants {
    /**
     * 通用錯誤信息異常類
     */
    public static class ErrorMessage {
        public static final String REQUEST_PARAM_ERROR = "請求參數異常";
        public static final String USER_EXIST = "用戶已存在";
        public static final String USER_NOT_EXIST = "用戶不存在";
    }
}
  1. 在Common Project 下面創建一個工具類com.sxzhongf.ad.common.utils.CommonUtils,用來對用戶username進行md5加密來獲取token信息。
/**
 * CommonUtils for 工具類
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 */
@Slf4j
public class CommonUtils {
    /**
     * md5 加密
     */
    public static String md5(String value) {
        return DigestUtils.md5Hex(value).toUpperCase();
    }
}

參考創建用戶的實現,依次實現其他表操作。

Controller實現

依然以用戶功能實現為例:

/**
 * UserController for 用戶controller
 *
 * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang | 若初</a>
 */
@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));
    }
}
在網關中配置廣告投放系統

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

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中聲明過的服務
  # 配置網關路由規則
  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 設置的路徑進行截取,默認轉發會截取掉配置的前綴
Test
  • 直接訪問投放系統

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

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

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

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

    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,為什么會有這么一個報錯呢?那是因為我在配置網關的時候,添加了一次攔截:

    /**
    * ValidateTokenFilter for 服務token校驗
    *
    * @author <a href="mailto:magicianisaac@gmail.com">Isaac.Zhang</a>
    */
    @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;
      }
    }

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

    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}]}

    至此,我們的廣告投放系統簡單功能已經全部實現完畢,并且可以通過網關進行轉發。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

怀来县| 中山市| 兴国县| 河曲县| 淳安县| 卢湾区| 肃宁县| 贵港市| 营口市| 临洮县| 莱州市| 新密市| 镇安县| 大余县| 镇赉县| 留坝县| 崇仁县| 中江县| 五台县| 监利县| 仙居县| 新宾| 襄樊市| 陕西省| 磐安县| 水富县| 无极县| 汝阳县| 金山区| 江油市| 资溪县| 博爱县| 阜阳市| 浦东新区| 陆丰市| 德州市| 磴口县| 新源县| 江门市| 肇源县| 波密县|