千家信息网

Service如何实现&Zuul配置&Test

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,Service如何实现&Zuul配置&Test,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。DAO层设计实现这里我们使用Spring D
千家信息网最后更新 2026年11月03日Service如何实现&Zuul配置&Test

Service如何实现&Zuul配置&Test,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

DAO层设计实现

这里我们使用Spring DATA JPA来实现数据库操作,当然大家也可以使用Mybatis,都是一样的,我们依然以用户表操作为例:

/** * AdUserRepository for 用户数据库操作接口 * 继承自JpaRepository,第一个参数AdUser代表当前要操作的实体类的class定义,第二个参数Long表示该类的主键类型 * * @author Isaac.Zhang */public interface AdUserRepository extends JpaRepository {     /**     * 根据用户名称获取用户     *     * @param username 名称     * @return 用户对象     */    AdUser findByUserName(String username);    List findAllByUserName(String userName);}
  • JPARepository 的默认实现方法,如果我们只是继承了JpaRepository而没有实现具体的操作方法,我们也是可以通过使用它的默认方法来做CRUD操作的,如下:

功能Service实现

创建service package,依然以用户操作为例,创建com.sxzhongf.ad.service.IUserService和com.sxzhongf.ad.service.impl.UserServiceImpl,UserServiceImpl实现了IUserService。

  1. 创建 IUserService 接口

/** * IUserService for 用户service * * @author Isaac.Zhang | 若初 */public interface IUserService {    /**     * 创建用户接口     *     * @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@Servicepublic 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 findAllByUserName(String userName) {        return userRepository.findAllByUserName(userName);    }}
  1. 创建数据传输对象(dto/vo)

    其实好多人在这里都会特别郁闷,搞不清楚这些命名有什么区别,个人建议是大家不用纠结,dto(data transfer object),就是表示我们在各个层传递的对象,vo在展示层操作的对象。但是这个只是个命名,它的本质就是一个object, 你传递到DAO层可以吗?当然可以,你传单独字段都是可以的。所以,没必要过分纠结这种信息,咬文嚼字有时候反而会适得其反。

/** * UserRequestVO for 创建用户请求对象VO * * @author Isaac.Zhang | 若初 */@Data@AllArgsConstructor@NoArgsConstructorpublic class UserRequestVO {    private String userName;    public boolean validate() {        return !StringUtils.isEmpty(userName);    }}---  /** * UserResponseVO for 用户响应VO * * @author Isaac.Zhang | 若初 */@Data@AllArgsConstructor@NoArgsConstructorpublic 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 = "请求参数异常";        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 Isaac.Zhang | 若初 */@Slf4jpublic class CommonUtils {    /**     * md5 加密     */    public static String md5(String value) {        return DigestUtils.md5Hex(value).toUpperCase();    }}

参考创建用户的实现,依次实现其他表操作。

Controller实现

依然以用户功能实现为例:

/** * 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));    }}

在网关中配置广告投放系统

我们在投放系统的配置中,配置了server.servlet.context-path:/ad-sponsor这么一个路径,意味着所有请求当前系统的路径都需要带有ad-sponsor, 例如:http://xxx/ad-sponsor/user/get?username=yyy,这是网关请求所必需的。根据上述,我们在网关服务中配置我们当前的投放系统:

spring:  application:    name: ad-gateway-zuulserver:  port: 1111eureka:  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/get2019-07-27 20:44:19.093  WARN 4766 --- [nio-1111-exec-4] c.s.a.g.filter.ValidateTokenFilter       : access token is empty2019-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 Isaac.Zhang */@Slf4j@Componentpublic 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}]}


至此,我们的广告投放系统简单功能已经全部实现完毕,并且可以通过网关进行转发。

看完上述内容,你们掌握Service如何实现&Zuul配置&Test的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

用户 配置 网关 信息 服务 对象 系统 参数 方法 路由 名称 接口 内容 前缀 功能 数据 结果 路径 错误 只是 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海睿民互联网科技有限公司 中国互联网科技工作委员会毛军 互联网的科技创新 华宇互联网科技 凡科互联网科技 九亚互联网科技 华中科技大学互联网 奇士达互联网科技 壕鑫互联网络科技 济南华为互联网科技产业总部基地 武汉健翔互联网络科技有限公司 昭通互联网科技选哪家 智腾互联网科技有限公司 宁波跨境商互联网科技有限公司 科技互联网行业投资研究 保山互联网科技靠谱吗 求路客互联网科技电话 广东猫王互联网科技有限公司电话 互联网企业和网络科技有限公司 现代科技的标志之一的互联网 中国 科技 互联网 互联网金融和金融科技 太原新华互联网科技学校怎么样 富国互联网科技创新基金 北京华百购互联网科技有限公司 互联网校园科技培训 注册互联网科技公司经营范围大全 互联网数据科技专业 高科技互联网套路 深圳互联网科技的发展
0