Java实现邮件发送报错无效的协议为null

用java实现邮件发送时运行代码报错提示 无效的协议为 null
报错信息如下
javax.mail.NoSuchProviderException:Invalid protocol:null

出错处源代码

Transport transport = session.getTransport();

ctrl+鼠标左键进入源码查看,源码为:

/**
 * Get a Transport object that implements this user's desired 
 * Transport protcol. The <code>mail.transport.protocol</code> property 
 * specifies the desired protocol. If an appropriate Transport 
 * object cannot be obtained, MessagingException is thrown.
 *
 * @return 		a Transport object 
 * @exception	NoSuchProviderException If the provider is not found.
 */
public Transport getTransport() throws NoSuchProviderException {
    return getTransport(getProperty("mail.transport.protocol"));
}

发现,源码是从Properties中取了mail.transport.protocol的值
再进入getProperty的源码查看,源码如下

/**
 * Returns the value of the specified property. Returns null
 * if this property does not exist.
 *
 * @return		String that is the property value
 */
public String getProperty(String name) { 
return props.getProperty(name); 
}

再进入props.getProperty的源码查看,源码如下

/**
 * Searches for the property with the specified key in this property list.
 * If the key is not found in this property list, the default property list,
 * and its defaults, recursively, are then checked. The method returns
 * {@code null} if the property is not found.
 *
 * @param   key   the property key.
 * @return  the value in this property list with the specified key value.
 * @see     #setProperty
 * @see     #defaults
 */
public String getProperty(String key) {
    Object oval = super.get(key);
    String sval = (oval instanceof String) ? (String)oval : null;
    return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
}

发现其实就是相当于一个键值对,在通过key的值去取出value的值,也就是通过mail.transport.protocol取出对应的值

这里通过调试发现
在这里插入图片描述
发现我们所需要的value值对应的keymail.transport,所以底层源码找不到对应的value值,这里把它改过来
更改前代码:

Properties properties = new Properties();
properties.setProperty("mail.host", host);
properties.setProperty("mail.transport", "smtp"); // 更改处
properties.setProperty("mail.smtp.auth", "true");

更改后代码:

Properties properties = new Properties();
properties.setProperty("mail.host", host);
properties.setProperty("mail.transport.protocol", "smtp"); // 更改处
properties.setProperty("mail.smtp.auth", "true");

之后成功解决问题
在这里插入图片描述

关于这个问题博主在查阅他人的博客时,注意到这样一个解决方案:
将代码:

Transport transport = session.getTransport();

改为:

Transport transport = session.getTransport("smtp");

博主这里也查看了源码,源码如下:

/**
 * Get a Transport object that implements the specified protocol.
 * If an appropriate Transport object cannot be obtained, null is
 * returned.
 *
 * @return 		a Transport object 
 * @exception	NoSuchProviderException If provider for the given
 *			protocol is not found.
 */
public Transport getTransport(String protocol) throws NoSuchProviderException {
	return getTransport(new URLName(protocol, null, -1, null, null, null));
}

其中getTransport源码为:

/**
 * Get a Transport object for the given URLName. If the requested 
 * Transport object cannot be obtained, NoSuchProviderException is thrown.
 *
 * The "scheme" part of the URL string (Refer RFC 1738) is used 
 * to locate the Transport protocol. <p>
 *
 * @param	url	URLName that represents the desired Transport
 * @return		a closed Transport object
 * @see		javax.mail.URLName
 * @exception	NoSuchProviderException If a provider for the given
 *			URLName is not found.
 */
public Transport getTransport(URLName url) throws NoSuchProviderException {
	String protocol = url.getProtocol();
	Provider p = getProvider(protocol);
	return getTransport(p, url);
}

关于这个方法,博主对此的理解是相当于重新创建了一个属性,那么我们之前事先设置好的属性就等于白设置了,所以博主最后没有使用这个方法,如果大家是跟我一样事先设置好Properties的属性的话,博主个人还是建议使用上面的方法,这里就看大家各自的代码是如何编写实现的了

有理解不到位或是不足之处欢迎在评论区指出讨论

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当出现"无效的目标行版: 17"的误时,这通常表示您的Java运行时环境不支持使用Java 17编译的类文件。根据引用中的误信息,您的项目中的某个类(/UserServiceApplication)已经被使用了一个更高版本(61.0)的Java运行时编译。而您当前使用的Java运行时环境只能识别最高版本为52.0的类文件。 要解决这个问题,您可以尝试以下步骤: 1. 确保您的Java运行时环境已经升级到Java 17或更高版本。您可以通过在命令行中运行"java -version"来检查当前的Java版本。 2. 如果您已经安装了Java 17或更高版本,但仍然收到此误消息,请检查您的项目配置和IDE设置。根据引用,您可以尝试通过修改项目的构建选项来指定目标字节码版本。确保将目标字节码版本设置为您当前使用的Java运行时环境所支持的版本(例如52.0)。 3. 如果您使用的是Maven或Gradle进行构建,您还可以在项目的构建配置文件(pom.xml或build.gradle)中设置Java编译器的版本。确保将编译器设置为与您当前使用的Java运行时环境兼容的版本。 请根据您的具体情况选择适合的解决方案,并确保您的Java运行时环境与项目的目标字节码版本兼容,以解决"无效的目标行版: 17"的误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Tomcat启动springboot项目war包报:启动子级时出的问题](https://download.csdn.net/download/weixin_38545117/12898521)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【springboot启动报java: 误: 无效的源行版:17](https://blog.csdn.net/Father_Of_Soft/article/details/132275867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值