一、报错内容
logdate: 2023-03-14 16:50:00.782
loglevel: ERROR
logmessage: sendMailByIoIntegral error:{}
microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. The request failed. The remote server returned an error: (401)Unauthorized
at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:74)
at microsoft.exchange.webservices.data.core.request.MultiResponseServiceRequest.execute(MultiResponseServiceRequest.java:158)
at microsoft.exchange.webservices.data.core.ExchangeService.internalCreateItems(ExchangeService.java:598)
at microsoft.exchange.webservices.data.core.ExchangeService.createItem(ExchangeService.java:657)
at microsoft.exchange.webservices.data.core.service.item.Item.internalCreate(Item.java:245)
at microsoft.exchange.webservices.data.core.service.item.EmailMessage.internalSend(EmailMessage.java:147)
at microsoft.exchange.webservices.data.core.service.item.EmailMessage.send(EmailMessage.java:258)
at com.project.cloud.common.email.util.DesvMailUtil.sendEmail(DesvMailUtil.java:68)
at com.project.cloud.thirdparty.api.service.compment.MailSendService.sendMailByIoIntegral(MailSendService.java:87)
at com.project.cloud.thirdparty.api.job.IssueIoIntegralJobHandler.notifyUser(IssueIoIntegralJobHandler.java:148)
at com.project.cloud.thirdparty.api.job.IssueIoIntegralJobHandler.dealTask(IssueIoIntegralJobHandler.java:116)
at com.project.cloud.thirdparty.api.job.IssueIoIntegralJobHandler.lambda$issueIoIntegralJob$0(IssueIoIntegralJobHandler.java:70)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647)
at com.project.cloud.thirdparty.api.job.IssueIoIntegralJobHandler.issueIoIntegralJob(IssueIoIntegralJobHandler.java:69)
at com.project.cloud.thirdparty.api.job.IssueIoIntegralJobHandler$$FastClassBySpringCGLIB$$db1fcb63.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.project.cloud.thirdparty.api.job.IssueIoIntegralJobHandler$$EnhancerBySpringCGLIB$$8a1ea2c9.issueIoIntegralJob(<generated>)
at sun.reflect.GeneratedMethodAccessor446.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.xxl.job.core.handler.impl.MethodJobHandler.execute(MethodJobHandler.java:29)
at com.xxl.job.core.thread.JobThread.run(JobThread.java:152)
Caused by: microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. The remote server returned an error: (401)Unauthorized
at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.validateAndEmitRequest(ServiceRequestBase.java:644)
at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:62)
... 23 common frames omitted
Caused by: microsoft.exchange.webservices.data.core.exception.http.HttpErrorException: The remote server returned an error: (401)Unauthorized
at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.getEwsHttpWebResponse(ServiceRequestBase.java:723)
at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.validateAndEmitRequest(ServiceRequestBase.java:639)
... 24 common frames omitted
二、报错说明
从报错中,定位错误代码
com.project.cloud.thirdparty.api.job.IssueIoIntegralJobHandler.issueIoIntegralJob(IssueIoIntegralJobHandler.java:69)
2.1 定位对应的Service实现类
@Slf4j
@Service
@AllArgsConstructor
public class MailSendService {
private final MailConfigProperties mailConfigProperties;
public void notifyUser(String phone, String email, IoIntegralTask task) {
String receiver = task.getReceiver();
String recognizer = task.getRecognizer();
String medal = MedalLevelEnum.getTxt(task.getMedalLevel());
BigDecimal integral = task.getIntegral();
String signName = smsTemplateProperties.getSignName4();
String templateCode = smsTemplateProperties.getTemplateCode4();
JSONObject smsTemplateParamJson = new JSONObject();
smsTemplateParamJson.put("name", receiver);
smsTemplateParamJson.put("name1", recognizer);
smsTemplateParamJson.put("medal", medal);
smsTemplateParamJson.put("num", ObjectUtil.isNotNull(integral) ? StrUtil.toString(integral) : "0");
try {
smsUtils.sendSms(signName, phone, templateCode, smsTemplateParamJson.toString());
} catch (ClientException e) {
log.error("短信发送失败: e:{}", e);
}
if (StrUtil.isBlank(email)) {
return;
}
mailSendService.sendMailByIoIntegral(receiver, recognizer, medal, integral, email);
}
}
2.2 定位到发邮件的组件
发现账号密码是通过使用配置文件去拿的
public void sendMailByIoIntegral(String receiver, String recognizer, String medal, BigDecimal integral, String email) {
MailUtil mailUtil = new MailUtil(mailConfigProperties.getUsername(), mailConfigProperties.getPassword(), mailConfigProperties.getDomain(), mailConfigProperties.getUri());
HashMap<String, Object> param = new HashMap<String, Object>();
param.put("to", email);
param.put("username", "邮件用户略");
param.put("title", "邮件标题略");
String msgBody="邮件正文略";
msgBody = StrUtil.format(msgBody, receiver, recognizer, medal, integral);
param.put("item", msgBody);
// 发送邮件
try {
mailUtil.sendEmail(param);
} catch (Exception e) {
log.error("sendMailByIoIntegral error:{}", e);
}
}
2.3 定位到发邮件的工具类
@Slf4j
@Data
public class MailUtil {
private String username;
private String password;
private String domain;
private String uri;
public MailUtil(String username, String password, String domain, String uri) {
this.username = username;
this.password = password;
this.domain = domain;
this.uri = uri;
}
public void sendEmail(Map<String, Object> params) throws Exception {
// 新建server版本
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
// 用户名,密码,域名
ExchangeCredentials credentials = new WebCredentials(username, password, domain);
service.setCredentials(credentials);
service.setUrl(new URI(uri));
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
EmailMessage msg = new EmailMessage(service);
msg.setSubject(MapUtil.getStr(params, "title"));
log.info("email params={}", params);
// 正文
msg.setBody(MessageBody.getMessageBodyFromText(MapUtil.getStr(params, "item")));
// 收件人
msg.getToRecipients().add(MapUtil.getStr(params, "to"));
msg.send(); // 发送
}
}
检查Nacos中的邮箱的账号信息
emailinfo:
username: xxxxx
password: xxxxx
domain: xxxxx
uri: xxxxx
拿这个username+password进远程工具去尝试范围。
我得到了如下提示。
三、报错解决
不用修改代码,直接将账号密码变成长久有效即可。