【微服务】Staffjoy 项目源码分析(九)—— Web 模块()

一. 架构设计

在这里插入图片描述
今天试一试竖版构图,从右到左嗷。
右侧是页面的构造类,每个类对应一个具体类的构造方法,Page 则为一个标准类模板
PageFactory 中存储了诸多类的调用方法,调用后反应对应数据对象
其余差不多,具体看下面的分析

二. 代码解析

具体页面类构造方法展示一个,其余大同小异

    @Builder(builderMethodName = "childBuilder")
    public ActivatePage(String title,
                        String description,
                        String templateName,
                        String cssId,
                        String version,
                        String errorMessage,
                        String email,
                        String name,
                        String phonenumber,
                        String token) {
        super(title, description, templateName, cssId, version);
        this.errorMessage = errorMessage;
        this.email = email;
        this.name = name;
        this.phonenumber = phonenumber;
        this.token = token;
    }

上面为 ActivatePage 类的构造方法
传入 title 等诸多参数后,封装到对象内。
另,本类继承了 Page 类为父类
super 方法构造 Page 类参数对象。

接着讲解 PageFactory 这个配置生成类对象
举一个生成标准类 Page 的方法和一个生成具体类的方法

    public Page buildCareersPage() {
        return Page.builder()
                .title("Staffjoy Careers")
                .description("If you’re looking to improve the way small businesses schedule their hourly workers, you are invited to apply to join our team in San Francisco.")
                .templateName("careers")
                .cssId("careers")
                .version(StaffjoyProps.getDeployEnv())
                .build();
    }

上面是生成招聘页面的代码,
就是返回一个类的对象,构造完成后返回。

    public LoginPage buildLoginPage() {
        return LoginPage.childBuilder()
                .title("Staffjoy Log in")
                .description("Log in to Staffjoy to start scheduling your workers. All you’ll need is your email and password.")
                .templateName("login")
                .cssId("login")
                .version(StaffjoyProps.getDeployEnv())
                .build();
    }

然后是 LoginPage 生成
类似,但是调用的是 LoginPage 页中配置且定义别名为 childBuilder 的子类构造方法

其余大同小异,不再分析

然后到 HelperService 类代码
从此类开始就调用了其他模块的 client
此处调用 accountClient 和 mailClient

首先在 trackEventAsync 中异步的调用了 accountClient 用于给 Intercom 记录日志
代码如下

    @Async(AppConfig.ASYNC_EXECUTOR_NAME)
    public void trackEventAsync(String userId, String event) {
        TrackEventRequest trackEventRequest = TrackEventRequest.builder()
                .userId(userId).event(event).build();
        BaseResponse baseResponse = null;
        try {
            baseResponse = accountClient.trackEvent(trackEventRequest);
        } catch (Exception ex) {
            String errMsg = "fail to trackEvent through accountClient";
            logException(logger, ex, errMsg);
        }
        if (!baseResponse.isSuccess()) {
            logError(logger, baseResponse.getMessage());
        }
    }

在 syncUserAsync 中也是如此,代码较简单,直接调用方法,不展示

接着是调用 mailClient 的方法

    @Async(AppConfig.ASYNC_EXECUTOR_NAME)
    public void sendEmailAsync(AccountDto a, CompanyDto c) {
        EmailRequest emailRequest = EmailRequest.builder()
                .to("sales@staffjoy.xyz")
                .name("")
                .subject(String.format("%s from %s just joined Staffjoy", a.getName(), c.getName()))
                .htmlBody(String.format("Name: %s<br>Phone: %s<br>Email: %s<br>Company: %s<br>App: https://app.staffjoy.com/#/companies/%s/employees/",
                        a.getName(),
                        a.getPhoneNumber(),
                        a.getEmail(),
                        c.getName(),
                        c.getId()))
                .build();

        BaseResponse baseResponse = null;
        try {
            baseResponse = mailClient.send(emailRequest);
        } catch (Exception ex) {
            String errMsg = "Unable to send email";
            logException(logger, ex, errMsg);
        }
        if (!baseResponse.isSuccess()) {
            logError(logger, baseResponse.getMessage());
        }
    }

本方法是为了发送加入成功的邮件的方法,
故调用 mailClient 发送邮件

接着开始分析 Controller 层代码
本模块中,主要逻辑代码是写在 Controller 层上的
基本一个类对应一个页面写一个调用方法

下面进行具体分析

首先是 ActivateController 类
本类负责激活操作,调用 accountClient 和 companyClient

    @RequestMapping(value = "/activate/{token}")
    public String activate(@PathVariable String token,
                           @RequestParam(value="password", required = false) String password,
                           @RequestParam(value="name", required = false) String name,
                           @RequestParam(value="tos", required = false) String tos,
                           @RequestParam(value="phonenumber", required = false) String phonenumber,
                           Model model,
                           HttpServletRequest request,
                           HttpServletResponse response) {

        ActivatePage page = pageFactory.buildActivatePage();
        page.setToken(token);

        String email = null;
        String userId = null;
        try {
            DecodedJWT jwt = Sign.verifyEmailConfirmationToken(token, appProps.getSigningSecret());
            email = jwt.getClaim(Sign.CLAIM_EMAIL).asString();
            userId = jwt.getClaim(Sign.CLAIM_USER_ID).asString();
        } catch (Exception ex) {
            String errMsg = "Failed to verify email confirmation token";
            helperService.logException(logger, ex, errMsg);
            return "redirect:" + ResetController.PASSWORD_RESET_PATH;
        }

        GenericAccountResponse genericAccountResponse1 = null;
        try {
            genericAccountResponse1 = accountClient.getAccount(AuthConstant.AUTHORIZATION_WWW_SERVICE, userId);
        } catch (Exception ex) {
            String errMsg = "fail to get user account";
            helperService.logException(logger, ex, errMsg);
            throw new ServiceException(errMsg, ex);
        }
        if (!genericAccountResponse1.isSuccess()) {
            helperService.logError(logger, genericAccountResponse1.getMessage());
            throw new ServiceException(genericAccountResponse1.getMessage());
        }
        AccountDto account = genericAccountResponse1.getAccount();

        page.setEmail(email);
        page.setName(account.getName());
        page.setPhonenumber(account.getPhoneNumber());

        if (!HelperService.isPost(request)) {
            model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, page);
            return Constant.VIEW_ACTIVATE;
        }

        // POST
        // update form in case we fail
        page.setName(name);
        page.setPhonenumber(phonenumber);

        if (password.length() < 6) {
            page.setErrorMessage("Your password must be at least 6 characters long");
        }

        if (StringUtils.isEmpty(tos)) {
            page.setErrorMessage("You must agree to the terms and conditions by selecting the checkbox.");
        }

        if (page.getErrorMessage() != null) {
            model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, page);
            return Constant.VIEW_ACTIVATE;
        }

        account.setEmail(email);
        account.setConfirmedAndActive(true);
        account.setName(name);
        account.setPhoneNumber(phonenumber);

        GenericAccountResponse genericAccountResponse2 = null;
        try {
            genericAccountResponse2 = accountClient.updateAccount(AuthConstant.AUTHORIZATION_WWW_SERVICE, account);
        } catch (Exception ex) {
            String errMsg = "fail to update user account";
            helperService.logException(logger, ex, errMsg);
            page.setErrorMessage(errMsg);
            model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, page);
            return Constant.VIEW_ACTIVATE;
        }
        if (!genericAccountResponse2.isSuccess()) {
            helperService.logError(logger, genericAccountResponse2.getMessage());
            page.setErrorMessage(genericAccountResponse2.getMessage());
            model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, page);
            return Constant.VIEW_ACTIVATE;
        }

        // Update password
        BaseResponse baseResponse = null;
        try {
            UpdatePasswordRequest updatePasswordRequest = UpdatePasswordRequest.builder()
                    .userId(userId)
                    .password(password)
                    .build();
            baseResponse = accountClient.updatePassword(AuthConstant.AUTHORIZATION_WWW_SERVICE, updatePasswordRequest);
        } catch (Exception ex) {
            String errMsg = "fail to update password";
            helperService.logException(logger, ex, errMsg);
            page.setErrorMessage(errMsg);
            model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, page);
            return Constant.VIEW_ACTIVATE;
        }
        if (!baseResponse.isSuccess()) {
            helperService.logError(logger, baseResponse.getMessage());
            page.setErrorMessage(baseResponse.getMessage());
            model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, page);
            return Constant.VIEW_ACTIVATE;
        }

        // login user
        Sessions.loginUser(account.getId(),
                account.isSupport(),
                false,
                appProps.getSigningSecret(),
                envConfig.getExternalApex(),
                response);
        logger.info("user activated account and logged in", "user_id", account.getId());


        // Smart redirection - for onboarding purposes
        GetWorkerOfResponse workerOfResponse = null;
        try {
            workerOfResponse = companyClient.getWorkerOf(AuthConstant.AUTHORIZATION_WWW_SERVICE, account.getId());
        } catch (Exception ex) {
            String errMsg = "fail to get worker of list";
            helperService.logException(logger, ex, errMsg);
            throw new ServiceException(errMsg, ex);
        }
        if (!workerOfResponse.isSuccess()) {
            helperService.logError(logger, workerOfResponse.getMessage());
            throw new ServiceException(workerOfResponse.getMessage());
        }
        WorkerOfList workerOfList = workerOfResponse.getWorkerOfList();

        GetAdminOfResponse getAdminOfResponse = null;
        try {
            getAdminOfResponse = companyClient.getAdminOf(AuthConstant.AUTHORIZATION_WWW_SERVICE, account.getId());
        } catch (Exception ex) {
            String errMsg = "fail to get admin of list";
            helperService.logException(logger, ex, errMsg);
            throw new ServiceException(errMsg, ex);
        }
        if (!getAdminOfResponse.isSuccess()) {
            helperService.logError(logger, getAdminOfResponse.getMessage());
            throw new ServiceException(getAdminOfResponse.getMessage());
        }
        AdminOfList adminOfList = getAdminOfResponse.getAdminOfList();

        String destination = null;
        if (adminOfList.getCompanies().size() != 0 || account.isSupport()) {
            destination = helperService.buildUrl("http", "app." + envConfig.getExternalApex());
        } else if (workerOfList.getTeams().size() != 0) {
            destination = helperService.buildUrl("http", "myaccount." + envConfig.getExternalApex());
        } else {
            // onboard
            destination = helperService.buildUrl("http", "www." + envConfig.getExternalApex(), "/new_company/");
        }

        return "redirect:" + destination;
    }

代码较复杂,慢慢分析

首先,通过传入的被绑定好的 token等参数填充 ActivatePage 对象
通过 token 和 appProps 中被定义的 signingSecret 密码生成 JWT 令牌
再通过 JWT.getClaim 方法得到对应的 email 和 userId
通过 userId 调用 accountClient 获得 account 对象
将 email 及 account 对象数据存储 ActivatePage 对象中
也通过之前得到的 email 和传入的 name 参数配置 account 对象
然后通过 accountClient 更新对象
再通过 common-lib 模块中定义的 sessions 对象的生成获得登录用户对象保持
通过 服务名 和 userId 调用 companyClient 找到 workerList 对象与 adminList 对象
根据两个对象是否存在生成不同的跳转路径
完成跳转

然后到了 ConfirmResetController 类

    @Autowired
    private AccountClient accountClient;

    @Autowired
    private CompanyClient companyClient;

    @RequestMapping(value = "/reset/{token}")
    public String reset(@PathVariable String token,
                        @RequestParam(value="password", required = false) String password,
                        Model model,
                        HttpServletRequest request,
                        HttpServletResponse response) {

        ConfirmResetPage page = pageFactory.buildConfirmResetPage();
        page.setToken(token);


        String email = null;
        String userId = null;
        try {
            DecodedJWT jwt = Sign.verifyEmailConfirmationToken(token, appProps.getSigningSecret());
            email = jwt.getClaim(Sign.CLAIM_EMAIL).asString();
            userId = jwt.getClaim(Sign.CLAIM_USER_ID).asString();
        } catch (Exception ex) {
            String errMsg = "Failed to verify email confirmation token";
            helperService.logException(logger, ex, errMsg);
            return "redirect:" + ResetController.PASSWORD_RESET_PATH;
        }

        if (!HelperService.isPost(request)) {
            model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, page);
            return Constant.VIEW_CONFIRM_RESET;
        }

        // isPost

        if (password.length() < 6) {
            page.setErrorMessage("Your password must be at least 6 characters long");
            model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, page);
            return Constant.VIEW_CONFIRM_RESET;
        }

        GenericAccountResponse genericAccountResponse1 = null;
        try {
            genericAccountResponse1 = accountClient.getAccount(AuthConstant.AUTHORIZATION_WWW_SERVICE, userId);
        } catch (Exception ex) {
            String errMsg = "fail to get user account";
            helperService.logException(logger, ex, errMsg);
            throw new ServiceException(errMsg, ex);
        }
        if (!genericAccountResponse1.isSuccess()) {
            helperService.logError(logger, genericAccountResponse1.getMessage());
            throw new ServiceException(genericAccountResponse1.getMessage());
        }

        AccountDto account = genericAccountResponse1.getAccount();

        account.setEmail(email);
        account.setConfirmedAndActive(true);

        GenericAccountResponse genericAccountResponse2 = null;
        try {
            genericAccountResponse2 = accountClient.updateAccount(AuthConstant.AUTHORIZATION_WWW_SERVICE, account);
        } catch (Exception ex) {
            String errMsg = "fail to update user account";
            helperService.logException(logger, ex, errMsg);
            throw new ServiceException(errMsg, ex);
        }
        if (!genericAccountResponse2.isSuccess()) {
            helperService.logError(logger, genericAccountResponse2.getMessage());
            throw new ServiceException(genericAccountResponse2.getMessage());
        }

        // Update password
        BaseResponse baseResponse = null;
        try {
            UpdatePasswordRequest updatePasswordRequest = UpdatePasswordRequest.builder()
                    .userId(userId)
                    .password(password)
                    .build();
            baseResponse = accountClient.updatePassword(AuthConstant.AUTHORIZATION_WWW_SERVICE, updatePasswordRequest);
        } catch (Exception ex) {
            String errMsg = "fail to update password";
            helperService.logException(logger, ex, errMsg);
            throw new ServiceException(errMsg, ex);
        }
        if (!baseResponse.isSuccess()) {
            helperService.logError(logger, baseResponse.getMessage());
            throw new ServiceException(baseResponse.getMessage());
        }

        // login user
        Sessions.loginUser(account.getId(),
                account.isSupport(),
                false,
                appProps.getSigningSecret(),
                envConfig.getExternalApex(),
                response);
        logger.info("user activated account and logged in", "user_id", account.getId());

        // Smart redirection - for onboarding purposes
        GetWorkerOfResponse workerOfResponse = null;
        try {
            workerOfResponse = companyClient.getWorkerOf(AuthConstant.AUTHORIZATION_WWW_SERVICE, account.getId());
        } catch (Exception ex) {
            String errMsg = "fail to get worker of list";
            helperService.logException(logger, ex, errMsg);
            throw new ServiceException(errMsg, ex);
        }
        if (!workerOfResponse.isSuccess()) {
            helperService.logError(logger, workerOfResponse.getMessage());
            throw new ServiceException(workerOfResponse.getMessage());
        }
        WorkerOfList workerOfList = workerOfResponse.getWorkerOfList();

        GetAdminOfResponse getAdminOfResponse = null;
        try {
            getAdminOfResponse = companyClient.getAdminOf(AuthConstant.AUTHORIZATION_WWW_SERVICE, account.getId());
        } catch (Exception ex) {
            String errMsg = "fail to get admin of list";
            helperService.logException(logger, ex, errMsg);
            throw new ServiceException(errMsg, ex);
        }
        if (!getAdminOfResponse.isSuccess()) {
            helperService.logError(logger, getAdminOfResponse.getMessage());
            throw new ServiceException(getAdminOfResponse.getMessage());
        }
        AdminOfList adminOfList = getAdminOfResponse.getAdminOfList();

        String destination = null;
        if (adminOfList.getCompanies().size() != 0 || account.isSupport()) {
            destination = HelperService.buildUrl("http", "app." + envConfig.getExternalApex());
        } else if (workerOfList.getTeams().size() != 0) {
            destination = HelperService.buildUrl("http", "myaccount." + envConfig.getExternalApex());
        } else {
            // onboard
            destination = HelperService.buildUrl("http", "www." + envConfig.getExternalApex(), "/new_company/");
        }

        return "redirect:" + destination;


    }

老规矩,先生成数据对象 ConfirmResetPage
然后通过 token 和 设定好的 signingSecret 得到 JWT
在得到 account 对象
根据 account 对象得到 workerList 和 adminList
根据俩 list 存在与否进行跳转

其实和上个方法差不多。

接着是 LoginController

    @RequestMapping(value = "/login")
    public String login(@RequestParam(value="return_to", required = false) String returnTo, // POST and GET are in the same handler - reset
                        @RequestParam(value="email", required = false) String email,
                        @RequestParam(value="password", required = false) String password,
                        // rememberMe=True means that the session is set for a month instead of a day
                        @RequestParam(value="remember-me", required = false) String rememberMe,
                        Model model,
                        HttpServletRequest request,
                        HttpServletResponse response) {

        LoginPage loginPage = pageFactory.buildLoginPage();
        loginPage.setReturnTo(returnTo); // for GET

        // if logged in - go away
        if (!StringUtils.isEmpty(AuthContext.getAuthz()) && !AuthConstant.AUTHORIZATION_ANONYMOUS_WEB.equals(AuthContext.getAuthz())) {
            String url = HelperService.buildUrl("http", "myaccount." + envConfig.getExternalApex());
            return "redirect:" + url;
        }

        if (HelperService.isPost(request)) {

            AccountDto account = null;
            GenericAccountResponse genericAccountResponse = null;
            try {
                VerifyPasswordRequest verifyPasswordRequest = VerifyPasswordRequest.builder()
                        .email(email)
                        .password(password)
                        .build();
                genericAccountResponse = accountClient.verifyPassword(AuthConstant.AUTHORIZATION_WWW_SERVICE, verifyPasswordRequest);
            } catch (Exception ex) {
                helperService.logException(logger, ex, "fail to verify user password");
            }
            if (genericAccountResponse != null) {
                if (!genericAccountResponse.isSuccess()) {
                    helperService.logError(logger, genericAccountResponse.getMessage());
                } else {
                    account = genericAccountResponse.getAccount();
                }
            }

            if (account != null) { // login success
                // set cookie
                Sessions.loginUser(account.getId(),
                        account.isSupport(),
                        !StringUtils.isEmpty(rememberMe),
                        appProps.getSigningSecret(),
                        envConfig.getExternalApex(),
                        response);
                helperService.trackEventAsync(account.getId(), "login");
                helperService.syncUserAsync(account.getId());

                String scheme  = "https";
                if (envConfig.isDebug()) {
                    scheme = "http";
                }

                if (StringUtils.isEmpty(returnTo)) {
                    returnTo = HelperService.buildUrl(scheme, "app." + envConfig.getExternalApex());
                } else {
                    if (!returnTo.startsWith("http")) {
                        returnTo = "http://" + returnTo;
                    }
                    // sanitize
                    if (!isValidSub(returnTo)) {
                        returnTo = HelperService.buildUrl(scheme, "myaccount." + envConfig.getExternalApex());
                    }
                }

                return "redirect:" + returnTo;

            } else {
                logger.info("Login attempt denied", "email", email);
                loginPage.setDenied(true);
                loginPage.setPreviousEmail(email);
            }

        }

        model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, loginPage);
        return Constant.VIEW_LOGIN;
    }

同样的,先生成 LoginPage 对象,开始填参数
确认请求是 ppost 后,开始求 account 对象
先确认 email , password 什么的正确,然后求的 account 对象
再生成 sessions 对象,通过 helperService 调用方法记录日志和通知 Intercom
最后根据传入的 returnTo 参数进行判断跳转到哪里
生成路由,将 loginpage 存到 model 中执行跳转

    @RequestMapping(value = "/new_company")
    public String newCompany(@RequestParam(value="name", required = false) String name,
                             @RequestParam(value="timezone", required = false) String timezone,
                             @RequestParam(value="team", required = false) String teamName,
                             Model model) {
        if (StringUtils.isEmpty(AuthContext.getAuthz()) || AuthConstant.AUTHORIZATION_ANONYMOUS_WEB.equals(AuthContext.getAuthz())) {
            return "redirect:/login";
        }

        if(StringUtils.hasText(name)) {
            if (!StringUtils.hasText(timezone)) {
                timezone = DEFAULT_TIMEZONE;
            }
            if (!StringUtils.hasText(teamName)) {
                teamName = DEFAULT_TEAM_NAME;
            }

            // fetch current userId
            String currentUserId = AuthContext.getUserId();
            if (currentUserId == null) {
                throw new ServiceException("current userId not found in auth context");
            }

            AccountDto currentUser = null;
            GenericAccountResponse genericAccountResponse = null;
            try {
                genericAccountResponse = accountClient.getAccount(AuthConstant.AUTHORIZATION_WWW_SERVICE, currentUserId);
            } catch(Exception ex) {
                String errMsg = "fail to get user account";
                helperService.logException(logger, ex, errMsg);
                throw new ServiceException(errMsg, ex);
            }
            if (!genericAccountResponse.isSuccess()) {
                helperService.logError(logger, genericAccountResponse.getMessage());
                throw new ServiceException(genericAccountResponse.getMessage());
            } else {
                currentUser = genericAccountResponse.getAccount();
            }

            // Make the company
            GenericCompanyResponse genericCompanyResponse = null;
            try {
                CompanyDto companyDtoToCreate = CompanyDto.builder()
                        .name(name)
                        .defaultTimezone(timezone)
                        .defaultDayWeekStarts(DEFAULT_DAYWEEK_STARTS)
                        .build();
                genericCompanyResponse = companyClient.createCompany(AuthConstant.AUTHORIZATION_WWW_SERVICE, companyDtoToCreate);
            } catch(Exception ex) {
                String errMsg = "fail to create company";
                helperService.logException(logger, ex, errMsg);
                throw new ServiceException(errMsg, ex);
            }
            if (!genericCompanyResponse.isSuccess()) {
                helperService.logError(logger, genericCompanyResponse.getMessage());
                throw new ServiceException(genericCompanyResponse.getMessage());
            }

            CompanyDto companyDto = genericCompanyResponse.getCompany();

            // register current user in directory
            GenericDirectoryResponse genericDirectoryResponse1 = null;
            try {
                NewDirectoryEntry newDirectoryEntry = NewDirectoryEntry.builder()
                        .companyId(companyDto.getId())
                        .email(currentUser.getEmail())
                        .build();
                genericDirectoryResponse1 = companyClient.createDirectory(AuthConstant.AUTHORIZATION_WWW_SERVICE, newDirectoryEntry);
            } catch(Exception ex) {
                String errMsg = "fail to create directory";
                helperService.logException(logger, ex, errMsg);
                throw new ServiceException(errMsg, ex);
            }
            if (!genericDirectoryResponse1.isSuccess()) {
                helperService.logError(logger, genericDirectoryResponse1.getMessage());
                throw new ServiceException(genericDirectoryResponse1.getMessage());
            }

            // create admin
            GenericDirectoryResponse genericDirectoryResponse2 = null;
            try {
                DirectoryEntryRequest directoryEntryRequest = DirectoryEntryRequest.builder()
                        .companyId(companyDto.getId())
                        .userId(currentUserId)
                        .build();
                genericDirectoryResponse2 = companyClient.createAdmin(AuthConstant.AUTHORIZATION_WWW_SERVICE, directoryEntryRequest);
            } catch(Exception ex) {
                String errMsg = "fail to create admin";
                helperService.logException(logger, ex, errMsg);
                throw new ServiceException(errMsg, ex);
            }
            if (!genericDirectoryResponse2.isSuccess()) {
                helperService.logError(logger, genericDirectoryResponse2.getMessage());
                throw new ServiceException(genericDirectoryResponse2.getMessage());
            }

            // create team
            GenericTeamResponse teamResponse = null;
            try {
                CreateTeamRequest createTeamRequest = CreateTeamRequest.builder()
                        .companyId(companyDto.getId())
                        .name(teamName)
                        .color(DEFAULT_TEAM_COLOR)
                        .build();
                teamResponse = companyClient.createTeam(AuthConstant.AUTHORIZATION_WWW_SERVICE, createTeamRequest);
            } catch(Exception ex) {
                String errMsg = "fail to create team";
                helperService.logException(logger, ex, errMsg);
                throw new ServiceException(errMsg, ex);
            }
            if (!teamResponse.isSuccess()) {
                helperService.logError(logger, teamResponse.getMessage());
                throw new ServiceException(teamResponse.getMessage());
            }
            TeamDto teamDto = teamResponse.getTeam();

            // register as worker
            GenericDirectoryResponse directoryResponse = null;
            try {
                WorkerDto workerDto = WorkerDto.builder()
                        .companyId(companyDto.getId())
                        .teamId(teamDto.getId())
                        .userId(currentUserId)
                        .build();
                directoryResponse = companyClient.createWorker(AuthConstant.AUTHORIZATION_WWW_SERVICE, workerDto);
            } catch(Exception ex) {
                String errMsg = "fail to create worker";
                helperService.logException(logger, ex, errMsg);
                throw new ServiceException(errMsg, ex);
            }

            if (!directoryResponse.isSuccess()) {
                helperService.logError(logger, directoryResponse.getMessage());
                throw new ServiceException(directoryResponse.getMessage());
            }

            // redirect
            logger.info(String.format("new company signup - %s", companyDto));
            String url = HelperService.buildUrl("http", "app." + envConfig.getExternalApex());

            helperService.syncUserAsync(currentUserId);
            helperService.trackEventAsync(currentUserId, "freetrial_created");

            if (EnvConstant.ENV_PROD.equals(envConfig.getName()) && !currentUser.isSupport()) {
                // Alert sales of a new account signup
                helperService.sendEmailAsync(currentUser, companyDto);
            }

            return "redirect:" + url;
        }

        model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, pageFactory.buildNewCompanyPage());
        return Constant.VIEW_NEW_COMPANY;
    }

接着是创建新 company 的方法
逻辑如下
先判断应用上下文 AuthContext 中是否存在 Authz
不存在则跳转到登录页面
根据 AuthContext 找到 userId
从而找到 account 对象
再根据传入参数和查找到的对象建立 company 对象
将对象通过 companyClient 传过去在数据库存储
生成 Directory 员工目录 对象 也存到 companyClient 去
admin,team,worker 对象 同上
然后生成指定 url 开始重定向
将 page 传入 model
完成跳转。

最后展示生成模板 page 页面对象的 StaticPageController 类的一个方法

    @RequestMapping(value="/careers")
    public String getCareers(Model model) {
        model.addAttribute(Constant.ATTRIBUTE_NAME_PAGE, pageFactory.buildCareersPage());
        return Constant.VIEW_CAREERS;
    }

简单来说就是调用 PageFactory 中的方法构建对象,添加到 model 中,返回

三. 小关键点

这次是点 ps

上面分析省略了一些非关键类
有的方法大同小异,不值得分析
比如 signupController

有的不是关键点
比如 AssetLoader 类,用于配置图像生成
又比如 ViewConfig 类,用于 Thymeleaf 模板引擎配置

请自行分析。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值