Java tutorial
package com.zanshang.controllers.web; import com.qiniu.util.StringUtils; import com.zanshang.captcha.CaptchaException; import com.zanshang.captcha.PhoneCaptchaService; import com.zanshang.config.spring.CacheConfig; import com.zanshang.constants.BusinessType; import com.zanshang.constants.Connect; import com.zanshang.constants.EmailConstants; import com.zanshang.framework.SavedRequestAwareRegisterSuccessHandler; import com.zanshang.framework.Ticket; import com.zanshang.framework.spring.MongodbUserDetailsManager; import com.zanshang.framework.wechat.WechatOAuth2AuthenticationFilter; import com.zanshang.framework.weibo.WeiboOAuth2AuthenticationFilter; import com.zanshang.models.*; import com.zanshang.models.audit.AuditCompany; import com.zanshang.services.*; import com.zanshang.services.company.CompanyTrapdoorImpl; import com.zanshang.services.mailbox.EmailCodeTrapdoorImpl; import com.zanshang.services.oauth.OAuthUrlProcessService; import com.zanshang.services.person.PersonTrapdoorImpl; import com.zanshang.services.phone.PhoneCaptchaTrapdoorImpl; import com.zanshang.services.setting.SettingTrapdoorImpl; import com.zanshang.services.wechat.WechatAuthorizationTrapdoorImpl; import com.zanshang.services.weibo.WeiboAuthorizationTrapdoorImpl; import com.zanshang.utils.AkkaTrapdoor; import com.zanshang.utils.Json; import com.zanshang.utils.PhoneValidator; import org.apache.commons.validator.routines.EmailValidator; import org.bson.types.ObjectId; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.context.MessageSource; import org.springframework.dao.DuplicateKeyException; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.mobile.device.Device; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.security.web.savedrequest.RequestCache; import org.springframework.stereotype.Controller; import org.springframework.util.Assert; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import javax.annotation.PostConstruct; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.Size; import java.io.IOException; import java.util.HashMap; import java.util.Locale; import java.util.Map; /** * Created by Lookis on 6/26/15. */ @Controller @RequestMapping(RegisterController.REGISTER_PATH) public class RegisterController { public static final String CONNECT_PATH = "/connect"; public static final String REGISTER_PATH = "/register"; Logger logger = LoggerFactory.getLogger(getClass()); @Autowired SavedRequestAwareRegisterSuccessHandler handler; @Autowired OAuthUrlProcessService oAuthUrlProcessService; @Autowired PhoneCaptchaService captchaService; @Autowired CacheManager cacheManager; @Autowired PasswordEncoder encoder; @Autowired MongodbUserDetailsManager userDetailsManager; @Autowired MessageSource messageSource; @Autowired MongoTemplate mongoTemplate; @Autowired AkkaTrapdoor akkaTrapdoor; @Autowired AuthenticationManager authenticationManager; @Autowired RequestCache requestCache; PhoneCaptchaTrapdoor phoneService; CompanyTrapdoor companyService; SettingTrapdoor settingService; EmailCodeTrapdoor emailService; PersonTrapdoor personService; WechatAuthorizationTrapdoor wechatService; WeiboAuthorizationTrapdoor weiboService; @PostConstruct public void initActor() { companyService = akkaTrapdoor.createTrapdoor(CompanyTrapdoor.class, CompanyTrapdoorImpl.class); settingService = akkaTrapdoor.createTrapdoor(SettingTrapdoor.class, SettingTrapdoorImpl.class); personService = akkaTrapdoor.createTrapdoor(PersonTrapdoor.class, PersonTrapdoorImpl.class); emailService = akkaTrapdoor.createTrapdoor(EmailCodeTrapdoor.class, EmailCodeTrapdoorImpl.class); wechatService = akkaTrapdoor.createTrapdoor(WechatAuthorizationTrapdoor.class, WechatAuthorizationTrapdoorImpl.class); weiboService = akkaTrapdoor.createTrapdoor(WeiboAuthorizationTrapdoor.class, WeiboAuthorizationTrapdoorImpl.class); phoneService = akkaTrapdoor.createTrapdoor(PhoneCaptchaTrapdoor.class, PhoneCaptchaTrapdoorImpl.class); handler.setTargetUrlParameter("return"); handler.setRequestCache(requestCache); } //? @RequestMapping(method = RequestMethod.GET) public String showRegister(Map<String, Object> model) { model.put("personalForm", new PersonalForm()); model.put("companyForm", new CompanyForm()); return "2_1_2_2"; } @RequestMapping(value = "/company", method = RequestMethod.POST) public Object companyRegister(@Valid CompanyForm companyForm, BindingResult result, Map<String, Object> model, Locale locale) { if (result.hasErrors()) { model.put("personalForm", new PersonalForm()); return "2_1_2_2"; } else { EmailAccount account = new EmailAccount(companyForm.getEmail(), encoder.encode(companyForm.getPassword())); account.setEnabled(false);//???? account.setNonLocked(false);//?????? try { userDetailsManager.createUser(account); } catch (DuplicateKeyException e) { model.put("personalForm", new PersonalForm()); result.rejectValue("email", "register.email.duplicate"); return "2_1_2_2"; } Map<String, String> mailModel = new HashMap<>(); mailModel.put("email", companyForm.getEmail()); emailService.create(companyForm.getEmail(), EmailConstants.EMAIL_ACTIVE_TEMPLATENAME, messageSource.getMessage("email.title.activation", null, locale), mailModel); Setting setting = new Setting(account.getUid(), companyForm.getContact(), companyForm.getEmail()); Company company = new Company(account.getUid(), companyForm.getCompanyName(), companyForm.getCompanyCode(), companyForm.getContact(), companyForm.getContactPhone(), companyForm.getLicense()); companyService.save(company); AuditCompany auditCompany = new AuditCompany(companyForm.getEmail()); mongoTemplate.save(auditCompany); settingService.save(setting); ModelAndView mav = new ModelAndView("return"); mav.addObject("title", messageSource.getMessage("register.email.verification.title", null, locale)); mav.addObject("content", messageSource.getMessage("register.email.verification.content", null, locale)); return mav; } } @RequestMapping(value = "/personal/email", method = RequestMethod.POST) public Object emailRegister(@Valid PersonalForm personalForm, BindingResult result, Map<String, Object> model, Locale locale, HttpServletRequest request, HttpServletResponse response, @Ticket String ticket) { if (result.hasErrors()) { model.put("companyForm", new CompanyForm()); return "2_1_2_2"; } else { EmailAccount account = new EmailAccount(personalForm.getEmail(), encoder.encode(personalForm.getPassword())); account.setEnabled(false);//???? try { userDetailsManager.createUser(account); } catch (DuplicateKeyException e) { model.put("companyForm", new CompanyForm()); result.rejectValue("email", "register.email.duplicate"); return "2_1_2_2"; } Map<String, String> mailModel = new HashMap<>(); mailModel.put("email", personalForm.getEmail()); emailService.create(personalForm.getEmail(), EmailConstants.EMAIL_ACTIVE_TEMPLATENAME, messageSource.getMessage("email.title.activation", null, locale), mailModel); Person person = new Person(account.getUid(), null); Setting setting = new Setting(account.getUid(), personalForm.getName(), personalForm.getEmail()); personService.save(person); settingService.save(setting); ModelAndView mav = new ModelAndView("return"); mav.addObject("title", messageSource.getMessage("register.email.verification.title", null, locale)); mav.addObject("content", messageSource.getMessage("register.email.verification.content", null, locale)); //register String returnUrl = oAuthUrlProcessService.getParamByKey(BusinessType.LOGIN, ticket, "return"); if (returnUrl != null && !returnUrl.isEmpty()) { handler.setDefaultTargetUrl(returnUrl); } returnUrl = handler.onRegisterSuccess(request, response); mav.addObject("goto", returnUrl); return mav; } } @RequestMapping(value = "/personal/phone", method = RequestMethod.POST) public Object phoneRegister(@Valid PersonalForm personalForm, BindingResult result, Map<String, Object> model, Locale locale, HttpServletRequest request, HttpServletResponse response, @Ticket String ticket) { if (result.hasErrors()) { model.put("companyForm", new CompanyForm()); return "2_1_2_2"; } else { if (!PhoneValidator.isValid(personalForm.getPhone())) { model.put("companyForm", new CompanyForm()); result.rejectValue("phone", "register.personal.phone.format_error"); return "2_1_2_2"; } //verify code try { if (captchaService.verify(personalForm.getPhone(), personalForm.getCode())) { phoneService.delete(personalForm.getPhone()); } else { model.put("companyForm", new CompanyForm()); result.rejectValue("code", "register.connect.phone.error_expire"); return "2_1_2_2"; } } catch (CaptchaException e) { logger.error("Phone Verification Code Not exist." + personalForm.getPhone()); model.put("companyForm", new CompanyForm()); result.rejectValue("code", "register.connect.phone.error_expire"); return "2_1_2_2"; } PhoneAccount account = new PhoneAccount(personalForm.getPhone(), encoder.encode(personalForm.getPassword())); try { userDetailsManager.createUser(account); } catch (DuplicateKeyException e) { model.put("companyForm", new CompanyForm()); result.rejectValue("phone", "register.phone.duplicate"); return "2_1_2_2"; } Setting setting = new Setting(account.getUid(), personalForm.getName(), null); settingService.save(setting); Person person = new Person(account.getUid(), personalForm.getPhone()); personService.save(person); ModelAndView mav = new ModelAndView("registersuccess"); // mav.addObject("title", messageSource.getMessage("register.phone.verification.title", null, locale)); // mav.addObject("content", messageSource.getMessage("register.phone.verification.content", null, locale)); //register String returnUrl = oAuthUrlProcessService.getParamByKey(BusinessType.LOGIN, ticket, "return"); if (returnUrl != null && !returnUrl.isEmpty()) { handler.setDefaultTargetUrl(returnUrl); } returnUrl = handler.onRegisterSuccess(request, response); mav.addObject("return", returnUrl); return mav; } } //?? //controller? //no cache! post? @RequestMapping(value = CONNECT_PATH + "/{platform}", method = RequestMethod.GET) public Object connectRegister(@PathVariable("platform") String platform, HttpServletRequest request, @Ticket String ticket) { ModelAndView mav = new ModelAndView("2_1_2_1_1"); mav.addObject("platform", platform); return mav; } @RequestMapping(value = CONNECT_PATH + "/{platform}", method = RequestMethod.POST) public Object checkRegister(@RequestParam("username") String username, @PathVariable("platform") String platform, HttpServletRequest request, @Ticket String ticket, Locale locale) { ModelAndView mav = new ModelAndView(); mav.addObject("platform", platform); try { ZSAccount userDetails = (ZSAccount) userDetailsManager.loadUserByUsername(username); Person person = personService.get(userDetails.getUid()); if (person == null) { //?connectcompany? mav.setViewName("2_1_2_1_1"); mav.addObject("message", messageSource.getMessage("connect.company", null, locale)); return mav; } mav.setViewName("2_1_2_1_2"); mav.addObject("username", username); return mav; } catch (UsernameNotFoundException e) { boolean isEmail = EmailValidator.getInstance().isValid(username); boolean isPhone = PhoneValidator.isValid(username); if (isEmail) { // PersonalForm personalForm = new PersonalForm(); personalForm.setEmail(username); mav.addObject("personalForm", personalForm); mav.setViewName("2_1_2_1_3"); return mav; } else if (isPhone) { // mav.setViewName("2_1_2_1_4"); PersonalPhoneForm form = new PersonalPhoneForm(); form.setPhone(username); mav.addObject("personalPhoneForm", form); mav.addObject("phone", username); return mav; } else { mav.setViewName("2_1_2_1_1"); mav.addObject("message", messageSource.getMessage("connect.username.format_error", null, locale)); return mav; } } } //?connect @RequestMapping(value = CONNECT_PATH + "/{platform}/account", method = RequestMethod.POST) public Object accountExist(@PathVariable("platform") String platform, @RequestParam("username") String username, @RequestParam("password") String rawPassword, @Ticket String ticket, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { UserDetails userDetails = userDetailsManager.loadUserByUsername(username); String encPassword = userDetails.getPassword(); boolean matches = encoder.matches(rawPassword, encPassword); if (matches) { Person person = personService.get(new ObjectId(userDetails.getUsername())); //company??connect Assert.notNull(person); connectAccount(platform, ticket, person); authenticateUser(username, rawPassword, request); //register String returnUrl = oAuthUrlProcessService.getParamByKey(BusinessType.LOGIN, ticket, "return"); if (returnUrl != null && !returnUrl.isEmpty()) { return "redirect:" + returnUrl; } handler.setDefaultTargetUrl("redirect:/"); return handler.onRegisterSuccess(request, response); } else { ModelAndView mav = new ModelAndView("2_1_2_1_2"); mav.addObject("username", username); mav.addObject("platform", platform); mav.addObject("bad_credentials", true); return mav; } } //Email @RequestMapping(value = CONNECT_PATH + "/{platform}/email", method = RequestMethod.POST) public Object createConnectEmailAccount(@PathVariable("platform") String platform, @Valid PersonalForm personalForm, BindingResult result, Map<String, Object> model, HttpServletRequest request, HttpServletResponse response, @Ticket String ticket, Locale locale, Device device) { model.put("platform", platform); if (result.hasErrors()) { return "2_1_2_1_3"; } else { EmailAccount account = new EmailAccount(personalForm.getEmail(), encoder.encode(personalForm.getPassword())); account.setEnabled(true);//???? try { userDetailsManager.createUser(account); } catch (DuplicateKeyException e) { result.rejectValue("email", "register.email.duplicate"); return "2_1_2_1_1"; } Map<String, String> mailModel = new HashMap<>(); mailModel.put("email", personalForm.getEmail()); emailService.create(personalForm.getEmail(), EmailConstants.EMAIL_ACTIVE_TEMPLATENAME, messageSource.getMessage("email.title.activation", null, locale), mailModel); Setting setting = new Setting(account.getUid(), personalForm.getName(), personalForm.getEmail()); settingService.save(setting); Person person = new Person(account.getUid(), null); personService.save(person); connectAccount(platform, ticket, person); authenticateUser(personalForm.getEmail(), personalForm.getPassword(), request); String targetUrl; if (device.isMobile()) { targetUrl = "redirect:/projects"; } else { targetUrl = "redirect:/"; } //register String returnUrl = oAuthUrlProcessService.getParamByKey(BusinessType.LOGIN, ticket, "return"); if (returnUrl != null && !returnUrl.isEmpty()) { return "redirect:" + returnUrl; } handler.setDefaultTargetUrl(targetUrl); return handler.onRegisterSuccess(request, response); } } //Phone @RequestMapping(value = CONNECT_PATH + "/{platform}/phone", method = RequestMethod.POST) public Object createConnectPhoneAccount(@PathVariable("platform") String platform, @Valid PersonalPhoneForm personalPhoneForm, BindingResult result, Map<String, Object> model, HttpServletRequest request, HttpServletResponse response, @Ticket String ticket) { model.put("platform", platform); model.put("phone", personalPhoneForm.getPhone()); if (result.hasErrors()) { return "2_1_2_1_4"; } else { if (!PhoneValidator.isValid(personalPhoneForm.getPhone())) { result.rejectValue("phone", "register.personal.phone.format_error"); return "2_1_2_1_4"; } //verify code try { if (captchaService.verify(personalPhoneForm.getPhone(), personalPhoneForm.getCode())) { //pass } else { result.rejectValue("code", "register.connect.phone.error_expire"); return "2_1_2_1_4"; } } catch (CaptchaException e) { logger.error("Phone Verification Code Not exist." + personalPhoneForm.getPhone()); result.rejectValue("code", "register.connect.phone.error_expire"); return "2_1_2_1_4"; } //create phone account PhoneAccount account = new PhoneAccount(personalPhoneForm.getPhone(), encoder.encode(personalPhoneForm.getPassword())); try { userDetailsManager.createUser(account); } catch (DuplicateKeyException e) { logger.error("Register with same phone number which already exist in system." + personalPhoneForm.getPhone()); result.rejectValue("phone", "register.phone.duplicate"); return "2_1_2_1_4"; } Setting setting = new Setting(account.getUid(), personalPhoneForm.getName(), null); settingService.save(setting); Person person = new Person(account.getUid(), personalPhoneForm.getPhone()); personService.save(person); authenticateUser(personalPhoneForm.getPhone(), personalPhoneForm.getPassword(), request); connectAccount(platform, ticket, person); //register String returnUrl = oAuthUrlProcessService.getParamByKey(BusinessType.LOGIN, ticket, "return"); if (returnUrl != null && !returnUrl.isEmpty()) { return "redirect:" + returnUrl; } handler.setDefaultTargetUrl("redirect:/"); return handler.onRegisterSuccess(request, response); } } private void authenticateUser(String username, String password, HttpServletRequest request) { UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password); token.setDetails(new WebAuthenticationDetails(request)); Authentication authenticatedUser = authenticationManager.authenticate(token); token.setDetails(new WebAuthenticationDetails(request)); SecurityContextHolder.getContext().setAuthentication(authenticatedUser); } private void connectAccount(String platform, String ticket, Person person) { Cache cache = cacheManager.getCache(CacheConfig.CACHE_NAME_PRE_REGISTER_ACCESSTOKEN); String jsonMap = cache.get(ticket, String.class); Map<String, String> foreignUser = Json.fromJson(jsonMap, Map.class); if (foreignUser != null) { switch (platform) { case WechatOAuth2AuthenticationFilter.PLATFORM: wechatService.save(foreignUser); person.setWechatId((String) foreignUser.get(Connect.WECHAT_ID_IN_ACCESSTOKEN)); break; case WeiboOAuth2AuthenticationFilter.PLATFORM: weiboService.save(foreignUser); person.setWeiboId(foreignUser.get(Connect.WEIBO_ID_IN_ACCESSTOKEN)); default: logger.error("Connect with platform not supported! " + platform); } } personService.save(person); } static class CompanyForm { @NotEmpty(message = "{register.company.companyName.notempty}") private String companyName; @NotEmpty(message = "{register.company.companyCode.notempty}") private String companyCode; @NotEmpty(message = "{register.company.contact.notempty}") private String contact; @NotEmpty(message = "{register.company.contactPhone.notempty}") private String contactPhone; @NotEmpty(message = "{register.company.email.notempty}") @Email(message = "{register.company.email.format_error}") private String email; @NotEmpty(message = "{register.company.password.notempty}") @Size(min = 6, message = "{register.company.password.minlength}") private String password; @NotEmpty(message = "{register.company.license.notempty}") private String license; public String getCompanyName() { return companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } public String getCompanyCode() { return companyCode; } public void setCompanyCode(String companyCode) { this.companyCode = companyCode; } public String getContact() { return contact; } public void setContact(String contact) { this.contact = contact; } public String getContactPhone() { return contactPhone; } public void setContactPhone(String contactPhone) { this.contactPhone = contactPhone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getLicense() { return license; } public void setLicense(String license) { this.license = license; } } static class PersonalPhoneForm { @NotEmpty(message = "{register.personal.phone.notempty}") private String phone; @NotEmpty(message = "{register.personal.password.notempty}") @Size(min = 6, message = "{register.personal.password.minlength}") private String password; @NotEmpty(message = "{register.personal.name.notempty}") private String name; @NotEmpty(message = "{register.personal.phonecode.notempty}") private String code; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } } static class PersonalForm { @Email(message = "{register.personal.email.format_error}") private String email; @Size(min = 8, message = "{register.personal.phone.format_error}") private String phone; private String code; @NotEmpty(message = "{register.personal.password.notempty}") @Size(min = 6, message = "{register.personal.password.minlength}") private String password; @NotEmpty(message = "{register.personal.name.notempty}") private String name; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } @Override public String toString() { return "PersonalForm{" + "email='" + email + '\'' + ", password='" + password + '\'' + '}'; } } }