flask 检测post是否为空_使用Flask搭建一个校园论坛-4

4738cd92011f4956654fda2ac0615e52.png

在上一节中完成了注册功能的前期准备工作,在这一节内容中将完成用户注册、登录功能。

1.知识预览

在本届中将学习到以下内容的知识

  1. 如何使用wtform来渲染表单
  2. 如果使用flask-mail来发送邮件

2.用户注册

在前端中form表单是用的比较多的东西,我们可以使用wtforms这个框架,直接通过后端代码来渲染前端表单。新建bbs/forms.py文件,嵌入以下代码

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, SelectField, BooleanField, TextAreaField, FileField, Label, HiddenField, PasswordFieldclass BaseUserForm(FlaskForm):user_name = StringField(u'用户名',validators=[DataRequired(message='用户名不能为空'),Length(min=1, max=16, message='用户名长度限定在1-16位之间'),Regexp('^[a-zA-Z0-9_]*$',message='用户名只能包含数字、字母以及下划线.')],render_kw={'placeholder': '请输入用户名长度1-16之间'})nickname = StringField(u'昵称',validators=[DataRequired(message='昵称不能为空'),Length(min=1, max=20, message='昵称长度限定在1-20位之间')],render_kw={'placeholder': '请输入昵称长度1-20之间'})user_email = StringField(u'注册邮箱',render_kw={'placeholder': '请输入注册邮箱', 'type': 'email'})submit = SubmitField(u'注册', render_kw={'class': 'btn btn-success btn-xs'})

在上面的代码中,首先导入相关的库,然后新建了一个BaseUserForm的类,因为用户的信息在很多表单中使用到了,因此可以将共同的属性剥离出来,然后在不同的场合继承该基类,并且可以根据不同的场合在子类中定制我们的表单属性,这样就可以降低代码的冗余量。如果在每个需要使用到用户信息的表单代码中写入同样的内容,那么久显得代码很臃肿了。

BaseUserForm类中使用到了wtforms中的一些属性,比如StringField就相当于是我们前端的input标签,SubmitField就相当于是<input type="submit">,具体可以去看wtforms的官方文档。

继续在上面的文件中嵌入如下代码,新建注册表单类

class RegisterForm(FlaskForm):user_name = StringField(u'用户名',validators=[DataRequired(message='用户名不能为空'),Length(min=1, max=16, message='用户名长度限定在1-16位之间'),Regexp('^[a-zA-Z0-9_]*$',message='用户名只能包含数字、字母以及下划线.')],render_kw={'placeholder': '请输入用户名长度1-16之间'})nickname = StringField(u'昵称',validators=[DataRequired(message='昵称不能为空'),Length(min=1, max=20, message='昵称长度限定在1-16位之间')],render_kw={'placeholder': '请输入昵称长度1-20之间'})user_email = StringField(u'注册邮箱',validators=[DataRequired(message='注册邮箱不能为空'),Length(min=4, message='注册邮箱长度必须大于4')],render_kw={'placeholder': '请输入注册邮箱', 'type': 'email'})password = StringField(u'密码',validators=[DataRequired(message='用户密码不能为空'),Length(min=8, max=40, message='用户密码长度限定在8-40位之间'),EqualTo('confirm_pwd', message='两次密码不一致')],render_kw={'placeholder': '请输入密码', 'type': 'password'})confirm_pwd = StringField(u'确认密码',validators=[DataRequired(message='用户密码不能为空'),Length(min=8, max=40, message='用户密码长度限定在8-40位之间')],render_kw={'placeholder': '输入确认密码', 'type': 'password'})colleges = SelectField(u'学院', choices=[(1, '计算机')])submit = SubmitField(u'注册', render_kw={'class': 'source-button btn btn-primary btn-xs mt-2'})def __init__(self, *args, **kwargs):super(RegisterForm, self).__init__(*args, **kwargs)cols = College.query.all()self.colleges.choices = [(col.id, col.name) for col in cols]def validate_user_name(self, filed):if User.query.filter_by(username=filed.data).first():raise ValidationError('用户名已被注册.')def validate_user_email(self, filed):if User.query.filter_by(email=filed.data.lower()).first():raise ValidationError('邮箱已被注册.')def validate_nickname(self, filed):if User.query.filter_by(nickname=filed.data).first():raise ValidationError('昵称已被注册')

因为学院的选项有许多,我们可以在类的构造函数中通过数据库去获取数据库中已经存在的学院,然后将其设置到colleges类属性的choices值上,这样当我们打开页面渲染表单时,数据就会自动渲染到select标签option上去了,如下图

f7750aa7ba56f32cdb45f5860a45a7e7.png

然后还新建了三个函数validate_user_namevalidate_user_email以及validate_nickname,这三个函数主要是用来判断email、username、nickname三个字段的唯一性,因为在数据库建表的时候将这三个字段设置为unique=True,因此在这里需要做一个唯一性的判断。

使用wtforms时,我们可以通过validate_加上你需要校验的属性字段名称来检验前端用户输入的数据是否符合标准。

表单类的编写已经完成,接下来就是整个注册逻辑的实现了。新建bbs/templates/frontend/register.html文件,嵌入以下代码

{% extends "frontend/base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block title %}用户注册
{% endblock %}
{% block content %}<body><main><div class="container"><div class="jumbotron pt-5 pb-1 mt-2"><div class="row"><div class="col-md-8"><h3 class="text-muted"><b>欢迎注册加入狗子学院~</b></h3><hr class="bg-primary"><p><b>在这里你可以:</b></p><ul><li>浏览当下校园的一些趣事、杂谈以及谁和谁的八卦</li><li>发布一些咸鱼交易、寻物启事等等</li><li>发现臭味相投的朋友、开拓自己的圈子</li></ul><img src="{{ url_for('static', filename='img/index.jpg') }}" class="rounded img-fluid"></div><div class="col-md-4"><div class="card mb-3 w-100 bg-light"><div class="card-header"><h4 class="text-muted"><strong>用户注册</strong></h4></div><div class="card-body">{% include "_flash.html" %}<form class="bs-component" action="/auth/register/" method="post">{{ form.csrf_token }}{{ wtf.form_field(form.user_name) }}{{ wtf.form_field(form.nickname) }}{{ wtf.form_field(form.user_email) }}{{ wtf.form_field(form.password) }}{{ wtf.form_field(form.confirm_pwd) }}{{ wtf.form_field(form.colleges) }}<label for="captcha">验证码</label><div class="input-group"><input type="text" class="form-control" name="captcha" id="captcha" placeholder="请输入验证码" aria-required="true" aria-describedby="captcha" required><div class="input-group-append"><button class="btn btn-success" onclick="sendCapt()" id="sendCaptcha">发送</button></div></div><p class="p-hint">验证码发送成功,10分钟内有效!</p>{{ form.submit }}<hr><small>已有账号? <a style="text-decoration: none;" href="{{ url_for('.login') }}">登录.</a></small></form></div></div></div></div></div></div></main>

然后打开bbs/blueprint/frontend/auth.py文件,接着在上一节下面嵌入如下代码

@auth_bp.route('/register/', methods=['GET', 'POST'])
def register():colleges = College.query.all()form = RegisterForm()return render_template('frontend/register.html', colleges=colleges, form=form)

在后端代码中我们通过render_template函数返回了前端注册页面,并且携带注册表单的实例参数。在前端html文件中,我们可以通过form.参数名的方式来进行表单渲染。同时还在前端文件中导入了bootstrap/wtf.html,这样就可以将表单的样式渲染成bootstrap的样式,当然也可以不是bootstrap/wtf.html来渲染,在后端表单类中可以通过render_kw参数来指定我们表单的一些特定参数。

在前端页面中我们还手动加入了一行验证码输入框,点击发送按钮就可以将验证码发送到用户填写的邮箱当中去了。为什么不将此输入框写到后端表单中去?因为那样不好处理前端样式了。

访问http://127.0.0.1/auth/register/ 将会看到如下页面:

9dcc597975ab0489f47b9e0ca07e2a58.png

在注册页面中是需要用户填写邮箱收到的验证码,因此我们需要在后端代码中实现发送邮件的功能。发送邮件的功能是通过flask-email来实现的,打开bbs/extensions.py文件,加入下面的代码,然后在__init__.py文件中进行注册。

from flask_mail import Mail
mail = Mail()

在使用发送邮件功能之前,首先我们需要到qq邮箱或者网易邮箱或者其他可以使用的邮箱申请SMTP服务,具体流程可以某度某歌搜索一下,这里就不再累述。将申请到的私密信填入到.env文件中

MAIL_SERVER='smtp.qq.com'
MAIL_USERNAME='你的qq邮箱名'
MAIL_PASSWORD='qq邮箱秘钥不是登录密码是申请SMTP那串无规则秘钥'

然后在bbs/setting.py文件中加入下面的代码

class BaseConfig(object):    # 省略之前代码BBS_MAIL_SUBJECT_PRE = '[狗子学院]'MAIL_SERVER = os.getenv('MAIL_SERVER')MAIL_PORT = 465MAIL_USE_SSL = TrueMAIL_USERNAME = os.getenv('MAIL_USERNAME')MAIL_PASSWORD = os.getenv('MAIL_PASSWORD')MAIL_DEFAULT_SENDER = ('BBS Admin', MAIL_USERNAME)

新建bbs/email.py文件,并将下面代码写入其中。

from threading import Threadfrom bbs.extensions import mail
from flask_mail import Message
from flask import current_app, render_templatedef async_send_mail(app, msg):with app.app_context():mail.send(msg)def send_email(to_mail, subject, template, **kwargs):message = Message(current_app.config['BBS_MAIL_SUBJECT_PRE'] + subject,recipients=[to_mail],sender=current_app.config['MAIL_USERNAME'])message.body = render_template(template + '.txt', **kwargs)message.html = render_template(template + '.html', **kwargs)th = Thread(target=async_send_mail, args=(current_app._get_current_object(), message))th.start()return th

在send_email函数中,使用了render_template()来渲染了邮件消息body以及html参数,因此需要先将这两个模板准备好。新建bbs/templates/email/verifyCode.htmlbbs/templates/email/verifyCode.txt 文件,将下面的代码写到文件中去

verifyCode.html

<h3 style="font-weight: bold;font-size: 18px">Hello {{ username }},</h3>
<p>Welcome to join the <a href="http://bbs.2dogz.cn">狗子学院</a>!This is your register captcha below here.</p>
<h1><strong>{{ ver_code }}</strong></h1>
<h5><b><i>The captcha will expire after 10 minutes.</i></b></h5>
<p style="color: red; font-style: italic"> If this operate is not by yourself, please change your password right now!Maybe your account was cracked.</p>
<small>(Please do not reply to this notification, this inbox is not monitored.)</small>

verifyCode.txt

Hello {{ username }}
Welcome to Blogin!
Welcome to join the 狗子学院!This is your register captcha below here.
{{ ver_code }}
The captcha will expire after 10 minutes.
If this operate is not by yourself, please change your password right now!Maybe your account was cracked.</p>(Please do not reply to this notification, this inbox is not monitored.)

然后开始编写发送邮件的后端逻辑代码,新建bbs/blueprint/frontend/normal.py 文件,因为发送邮件属于通用行为,因此将其放入normal.py模块中,将以下代码嵌入其中

from flask import Blueprint, send_from_directory, request, jsonify
from bbs.extensions import db
from bbs.email import send_email
from bbs.models import VerifyCode, Gender, Role, College@normal_bp.route('/send-email/', methods=['POST'])
def send():to_email = request.form.get('user_email')username = request.form.get('user_name')ver_code = generate_ver_code()send_email(to_mail=to_email, subject='Captcha', template='email/verifyCode', username=username,ver_code=ver_code)# 判断是否已经存在一个最新的可用的验证码,以确保生效的验证码是用户收到最新邮件中的验证码exist_code = VerifyCode.query.filter(VerifyCode.who == to_email, VerifyCode.is_work == 1).order_by(VerifyCode.timestamps.desc()).first()if exist_code:exist_code.is_work = Falsent = datetime.datetime.now()et = nt + datetime.timedelta(minutes=10)verify_code = VerifyCode(val=ver_code, who=to_email, expire_time=et)db.session.add(verify_code)db.session.commit()return jsonify({'tag': 1, 'info': '邮件发送成功!'})

我们根据请求中的keyword来获取前端发送过来的请求参数,然后调用send_email()函数进行发送邮件,同时将生成的随机验证码放入到邮件消息体中去。

然后判断数据库中是否已经存在了属于该注册用户的验证码,如果有则将它设置为过期的,然后将新的验证码存入到数据库中,并设置过期时间为10分钟。这里是通过MySQL来保存的验证码信息,也有其他方法来保存验证码信息,比如使用redis来保存,redis可以设置字段过期时间,如果达到了这个时间,再去取这个字段的值就会为None。

接着我们来处理前端发送邮件的代码,打开bbs/templates/frontend/register.html文件,加入下面的代码

<main>
...
</main>
<script>let time = 60;let reg = /^w+((-w+)|(.w+))*@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$/;function sendCapt(){let $sendBtn = $("#sendCaptcha");let $email = $("#user_email");let $username = $("#user_name");if ($username.val() === '' || $email.val() === '' || !reg.test($email.val())){return false;}$sendBtn.attr('disabled', true);getRandomCode($sendBtn);$.ajax({url: '/normal/send-email/',type: 'post',data: {'user_name': $username.val(), 'user_email': $email.val()},success: function (res){if (res.tag){$(".p-hint").slideDown(500).delay(3000).hide(500);}}})}//倒计时function getRandomCode(obj) {if (time === 0) {time = 60;obj.text('发送');obj.attr('disabled', false);return;} else {time--;obj.text(time+'(秒)');}setTimeout(function() {getRandomCode(obj);},1000);}</script>

通过ajax向后端/normal/send-email/发送请求,同时将emailusername传递到后端,同时将发送验证码按钮置为不可点击状态,间隔60s才能发送一次,并在前端页面给用户一个提示信息。这样发送验证码邮件的整个流程就完成了,接下里要处理用户点击注册按钮之后的逻辑。

我们使用的是wtfforms来渲染的后端表单,并且在某些表单字段中加入了一些限制信息。在后端代码中,我们可以通过wtfforms的示例来验证我们的表单,打开bbs/blueprint/frontend/auth.py 加入下面的代码

@auth_bp.route('/register/', methods=['GET', 'POST'])
def register():    ...if form.validate_on_submit():username = form.user_name.datanickname = form.nickname.datapassword = form.confirm_pwd.dataemail = form.user_email.datacollege = form.colleges.datacaptcha = request.form.get('captcha')code = VerifyCode.query.filter(VerifyCode.who == email, VerifyCode.is_work == 1).order_by(VerifyCode.timestamps.desc()).first()if code:if code.val != int(captcha):flash('验证码错误!', 'danger')return redirect(request.referrer)elif code.expire_time < datetime.datetime.now():flash('验证码已过期!', 'danger')return redirect(request.referrer)else:flash('请先发送验证码到邮箱!', 'info')return redirect(request.referrer)user = User(username=username,college_id=college,nickname=nickname,email=email,password=password,status_id=1)user.generate_avatar()user.set_password(password)code.is_work = Falsedb.session.add(user)db.session.commit()flash('注册成功,欢迎加入二狗学院!', 'success')return redirect(url_for('.login'))

通过form.validate_on_submit()来判断提交的表单是否通过了验证,通过验证之后通过form.字段名.data来获取对应表单字段的值,然后根据邮箱来查找上一步数据库保存的验证码,如果不存在验证码,则提示用户发送验证码到邮箱,因为存在着一种可能用户乱填一个验证码,而不发送验证码到邮箱。然后判断验证码是否正确或者过期,如果未通过,则发送对应的提示消息提示用户,如果通过,则将用户信息保存到数据库中,然后重定向到登录页面。至此,用户注册的功能就已经完成了。

用户登录

相比注册功能,用户登录就比较简单了。新建bbs/templates/frontend/login.html文件,该文件为用户登录的前端页面模板文件,同样的我们使用wtfforms来渲染表单,在文件中嵌入下面的代码

{% extends "frontend/base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block title %}用户登录
{% endblock %}
{% block content %}<body><main><div class="container">{% include "_flash.html" %}<div class="jumbotron pt-5 pb-3 mt-5"><div class="row"><div class="col-md-8"><img src="{{ url_for('static', filename='img/index.jpg') }}" class="rounded img-fluid"></div><div class="col-md-4"><div class="card mb-3 w-100 bg-light align-self-center"><div class="card-header"><h4 class="text-muted"><strong>用户登录</strong></h4></div><div class="card-body "><form class="bs-component" action="/auth/login/" method="post">{{ form.csrf_token }}{{ wtf.form_field(form.usr_email) }}{{ wtf.form_field(form.password) }}{{ wtf.form_field(form.remember_me) }}{{ form.submit }}<hr><small>没有账号? <a style="text-decoration: none;" href="{{ url_for('.register') }}">注册.</a></small></form></div></div></div></div></div></div></main></body>
{% endblock %}

代码中的form.csrf_token 是一种防止csrf攻击的手段,关于csrf攻击具体可以百度,之后的代码就跟注册模板一样,通过wtfforms进行表单渲染,因此我们需要新建一个渲染登录表单的类,打开bbs/forms.py模块,加入新建登录表单的代码,如下所示

class LoginForm(FlaskForm):usr_email = StringField(u'邮箱/用户名', validators=[DataRequired(message='用户名或邮箱不能为空')],render_kw={'placeholder': '请输入邮箱或用户名'})password = StringField(u'登录密码',validators=[DataRequired(message='登录密码不能为空'),Length(min=8, max=40, message='登录密码必须在8-40位之间')],render_kw={'type': 'password', 'placeholder': '请输入用户密码'})remember_me = BooleanField(u'记住我')submit = SubmitField(u'登录', render_kw={'class': 'source-button btn btn-primary btn-xs'})

接着需要处理后端的登录视图函数,打开bbs/blueprint/frontend/auth.py模块,新建一个视图函数,代码如下所示

from flask_login import current_user, login_user, logout_user
@auth_bp.route('/login/', methods=['GET', 'POST'])
def login():if current_user.is_authenticated:return redirect(url_for('index_bp.index'))form = LoginForm()if form.validate_on_submit():usr = form.usr_email.datapwd = form.password.datauser = User.query.filter(or_(User.username == usr, User.email == usr.lower())).first()if user is not None and user.status.name == '禁用':flash('您的账号处于封禁状态,禁止登陆!联系管理员解除封禁!', 'danger')return redirect(url_for('.login'))if user is not None and user.check_password(pwd):if login_user(user, form.remember_me.data):flash('登录成功!', 'success')return redirect(url_for('index_bp.index'))elif user is None:flash('无效的邮箱或用户名.', 'danger')else:flash('无效的密码', 'danger')return render_template('frontend/login.html', form=form)

关于登录逻辑处理,flask有一个十分流行好用的第三方库flask-login,使用该第三库我们可以很方便的处理登录、退出权限控制等操作。

首先通过current_user来判断用户是否已经登录了,如果登录则返回主页面。接着通过LoginForm示例来获取前端登录页面传递过来的值,从数据库获取用户的相关信息,首先判断账号是否被禁用了,如果被禁用则弹出提示信息,并返回给前端页面。接着判断用户密码是否匹配,如果不匹配则返回登录页面,并提示用户密码不匹配,反之则重定向到主页。

这里的登录成功重定向其实可以做的更加人性化,当用户进入到需要登录才能操作的页面时候,这时候会自动跳转到登录页面。如果用户登录成功,应该是返回前一个页面而不是固定返回主页。flask_login的login_required装饰器重定向到登录页面的时候会带一个next参数,因此我们可以通过此参数来让用户登录成功之后重定向到上一页,具体实现很简单,就请读者自主开发吧!

这时候我们打开登录页面,可以看到如下页面

9023412adfa6e8bb87ebd5b8f4513a52.png

到此,用户登录注册功能就已经全部实现了,下一节将开始讲述论坛主页的实现。

教程中的资源文件可以进入我的github仓库下载源代码使用

仓库连接​github.com

论坛已经基本完成了,我已经部署到我的个人服务器上去了

主页 -二狗学院​bbs.2dogz.cn

感兴趣的同学可以关注我的博客网站哦,会不定期更新一些程序员相关的博客哦!

Home - Blogin​2dogz.cn
073ab62bb93cd2f86ac5e5f5b998dec7.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368480.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL Table 自动生成Net底层-生成数据操作Repository

生成接口类 public static string DataTableToBaseIService(string tableName, string nameSpace, string className){var table SqlTableHelper.GetSQLTableInfo(tableName);StringBuilder reval new StringBuilder();reval.AppendFormat(" using System; using…

CSS3扁平化Loading动画特效

效果预览&#xff1a;http://hovertree.com/texiao/css3/42/ 代码如下&#xff1a; <!doctype html><html><head><meta charset"utf-8"><title>css3旋转加载效果_何问起</title><style>body {background: #263238;backgro…

自定义Spring命名空间使JAXB更容易

首先&#xff0c;让我大声说出来&#xff1a; Spring不再是XML繁重的了 。 事实上&#xff0c;如今&#xff0c;您可以使用大量注释&#xff0c; Java配置和Spring Boot来编写几乎没有XML或根本没有XML的Spring应用程序。 认真地停止谈论Spring和XML&#xff0c;这已经成为过去…

sublime text3运行python不显示内容_sublime text 运行python无法出结果

一、python和sublime text 已经安装完毕。二、用sublime text运行python程序得时候出现三、配置Python环境1、打开Tools > Build System > New Build System..2、点击New Build System后&#xff0c;会生成一个空配置文件&#xff0c;在这个配置文件内覆盖配置信息&#…

利用锚点再点事吧丨

上图 接着HTML代码&#xff1a; <div id"color"> <div id"red">红</div> <div id"yellow">黄</div> <div id"black">黑</div> <div id"green">绿</div> </div>…

JavaScript变量声明与提升

一直以来对变量提升都是比较模糊的&#xff0c;今天特地看了一下这个知识点&#xff0c;总结一下。 1、举个最简单的例子来说一下什么是变量提升吧。  function foo(){console.log(x); // undefinedvar x 12;console.log(x) // 12 } foo(); 由于变量声明提升&#xff0c;其…

javaweb笔记1

转载于:https://www.cnblogs.com/webdev8888/p/9164291.html

重复运行JUnit测试而没有循环

最近&#xff0c;我遇到了一个问题&#xff0c;我不得不编写一种方法的测试&#xff0c;该方法需要计算在一定可能性范围内的随机分布值1 。 更准确地说&#xff0c;如果您假设签名看起来像 interface RandomRangeValueCalculator {long calculateRangeValue( long center, lo…

以太网数据帧的报尾封装字段是什么_16、90秒快速“读懂”数据包的封装、解封装...

数据转发过程概述数据包在相同网段内或不同网段之间转发所依据的原理基本一致。一、数据帧封装TCP封装(四层)当主机建立了到达目的地的TCP连接后&#xff0c;便开始对应用层数据进行封装。主机A会对待发送的应用数据首先执行加密和压缩等相关操作&#xff0c;之后进行传输层封装…

MVP模式在Android实际项目中的应用和优化

注&#xff1a;本文阅读需要对MVP模式有基本了解。 MVP模式已经出现有很长一段时间了&#xff0c;但是火起来是这两年的事情。 关于MVP的概览&#xff0c;介绍&#xff0c;乃至于教程&#xff0c;Demo&#xff0c;实例&#xff0c;网上都有很多&#xff0c;我也有一篇文章专门收…

将训练集构建成ImageNet模型

以下程序实现将训练集构建为ImageNet模型&#xff0c;训练集图片为56个民族 import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter;public class createTxt {public static void createClassInd(){//56个…

CSS基本知识(慕课网)

1、注释 注解&#xff1a;CSS中注释/*这里是注释的文字*/ HTML中注释<!--这里是注释的文字--> 2、外部式css样式&#xff0c;写在单独的一个文件中 注解&#xff1a; 外部式css样式(也可称为外联式)就是把css代码写一个单独的外部文件中&#xff0c;这个css样式文件以“…

JMS和Spring:有时很重要的小事情

JmsTemplate和DefaultMessageListenerContainer是用于访问JMS兼容MOM的Spring帮助器。 他们的主要目标是在JMS API之上形成一层&#xff0c;并处理诸如事务管理/消息确认之类的基础结构&#xff0c;并隐藏JMS API的某些重复和笨拙的部分&#xff08;保留在那里&#xff1a; JMS…

python 音速_webpack多页应用架构系列(十一):预打包Dll,实现webpack音速编译

前言上文说到我们利用webpack来打包一个可配置的bootstrap&#xff0c;但文末留下一个问题&#xff1a;由于bootstrap十分庞大&#xff0c;因此每次编译都要耗费大部分的时间在打包bootstrap这一块&#xff0c;而换来的仅仅是配置的便利&#xff0c;十分不划算。我也并非是故意…

whereis 命令

可以用来查看命令的路径&#xff0c;安装在哪里 whereis命令是定位可执行文件、源代码文件、帮助文件在文件系统中的位置 [rootsalt-server-192 a]# whereis mysql mysql: /usr/bin/mysql /usr/lib64/mysql /usr/share/mysql /usr/share/man/man1/mysql.1.gz 转载于:https://ww…

css实现3D立方体旋转特效

先来看运行后出来的效果 它是在不停运行的一个立方体 先来看html部分的代码 <div class"rect-wrap"> <!--舞台元素&#xff0c;设置perspective&#xff0c;让其子元素获得透视效果。--><div class"container"> <!-- 容器&#…

Eclipse中的Tomcat:6个流行的“如何”问题

学习新技术总是一个艰难的过程。 当您尝试学习将要相互交互的两种技术时&#xff0c;此过程将变得更加困难。 Tomcat和Eclipse是Java EE开发中最流行的先决条件。 因此&#xff0c;要成为一名专业的开发人员&#xff0c;您需要知道如何使用此对执行最需要的操作以及如何进行一些…

adc分辨率和精度的区别_科普 | 传感器的灵敏度、分辨率和精度三者之间有何区别?...

传感器作为一种检测装置&#xff0c;具有微型化、数字化、智能化、多功能化、系统化、网络化的特点。在现代工业生产尤其是自动化生产过程中&#xff0c;需要各种传感器来监视和控制生产过程中的各个参数&#xff0c;使设备工作在正常状态或最佳状态&#xff0c;并使产品达到最…

Node08 - 配置模板引擎 -(route)

1、配置模板引擎 &#xff08;01&#xff09;、输出什么东西        //view engine&#xff1a;视图模板引擎(以何种方式呈现给用户) > 指定输出html           server.set(view engine, html); &#xff08;02&#xff09;、模板文件放在哪 //views: 指定好…

for循环与foreach的区别

for循环与foreach的区别 foreach 依赖 IEnumerable. 第一次 var a in GetList() 时 调用 GetEnumerator 返回第一个对象 并 赋给a, 以后每次再执行 var a in GetList() 的时候 调用 MoveNext.直到循环结束. 期间GetList()方法只执行一次. 1 2 3 4 5 6 7 8 9 10 11 12 13 fo…