需求如图:

根据上述分析图,在对应的层添加方法
修改MemberDAO接口,声明queryMemberByUsernameAndPassword()方法
//提供一个通过用户名和密码返回对应的Member的方法
public Member queryMemberByUsernameAndPassword(String username,String password);
修改MemberDAOImpl实现类,实现queryMemberByUsernameAndPassword()方法
/**
* 通过用户名和密码返回对应的Member对象
*
* @param username 用户名
* @param password 密码
* @return 返回值为对应的Member对象,如果不存在则返回null
*/
@Override
public Member queryMemberByUsernameAndPassword(String username, String password) {
String sql = "SELECT * FROM `member` WHERE `username`=? AND `password`=MD5(?);";
return querySingle(sql, Member.class, username, password);
}
在utils包中的MemberDAOImplTest类中增加测试方法
@Test
public void queryMemberByUsernameAndPassword() {
Member member = memberDAO.queryMemberByUsernameAndPassword
("king", "king");
System.out.println("member=" + member);
}
代码测试通过
修改MemberService接口,声明login方法
//登录用户
//相比于直接传递用户名和密码,传递一个Member对象拓展性会比较好一些
public Member login(Member member);
修改MemberServiceImpl接口实现类,实现login方法
/**
* 根据登录传入的member信息,返回对应的在数据库中的member对象
*
* @param member
* @return 返回的是数据库中的member对象,若不存在则返回null
*/
@Override
public Member login(Member member) {
return memberDAO.queryMemberByUsernameAndPassword
(member.getUsername(), member.getPassword());
}
在utils包中的MemberServiceImplTest类中增加测试方法
@Test
public void login() {
Member member = memberService.login
(new Member(null, "admin", "admin", null));
System.out.println("member=" + member);
}
代码测试通过
配置loginServlet
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.li.furns.web.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
创建LoginServlet
package com.li.furns.web;
import com.li.furns.entity.Member;
import com.li.furns.service.MemberService;
import com.li.furns.service.impl.MemberServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
private MemberService memberService = new MemberServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收用户名和密码
//如果前端输入的是null,后台接收的数据为空串""
String username = request.getParameter("username");
String password = request.getParameter("password");
//构建一个member对象
Member member = new Member(null, username, password, null);
//2.调用MemberServiceImpl的login方法
if (memberService.login(member) == null) {//数据库中没有该用户,返回登录页面
//注意路径
request.getRequestDispatcher("/views/member/login.html")
.forward(request, response);
} else {
//否则,跳转到登录成功页面
request.getRequestDispatcher("/views/member/login_ok.html")
.forward(request, response);
}
}
}
在5.2分析图的基础上修改如下两处:
修改LoginServlet,将错误提示和用户名放入request域中
package com.li.furns.web;
import com.li.furns.entity.Member;
import com.li.furns.service.MemberService;
import com.li.furns.service.impl.MemberServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
private MemberService memberService = new MemberServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收用户名和密码
//如果前端输入的是null,后台接收的数据为空串""
String username = request.getParameter("username");
String password = request.getParameter("password");
//构建一个member对象
Member member = new Member(null, username, password, null);
//2.调用MemberServiceImpl的login方法
if (memberService.login(member) == null) {//数据库中没有该用户,返回登录页面
//登录失败,将错误信息和登录会员名放入request域中
request.setAttribute("errInfo", "登录失败,用户名或者密码错误");
request.setAttribute("username", username);
//注意路径
request.getRequestDispatcher("/views/member/login.jsp")
.forward(request, response);
} else {
//否则,跳转到登录成功页面
request.getRequestDispatcher("/views/member/login_ok.html")
.forward(request, response);
}
}
}
将login.html改为login.jsp(文件右键Refactor-->Rename,在弹窗中点击Do Refactor,会把其他文件引用login.html的信息自动改为login.jsp)
部分代码,详细代码请看 https://github.com/liyuelian/furniture_mall.git
<div class="login-register-form">
<%--提示错误信息--%>
<span class="errorMsg"
style="float: right; font-weight: bold; font-size: 20pt; margin-left: 10px;">
${requestScope.errInfo}
</span>
<form action="loginServlet" method="post">
<input type="text" name="username" placeholder="Username" value="${requestScope.username}"/>
<input type="password" name="password" placeholder="Password"/>
<div class="button-box">
<div class="login-toggle-btn">
<input type="checkbox"/>
<a class="flote-none" href="javascript:void(0)">Remember me</a>
<a href="#">Forgot Password?</a>
</div>
<button type="submit"><span>Login</span></button>
</div>
</form>
前端页面两个表单login和register的action都提交到MemberServlet中
修改login.jsp,分别在login和register表单中添加hidden,两个表单都提交到MemberServlet处理
在web.xml中配置MemberServlet
<servlet>
<servlet-name>MemberServlet</servlet-name>
<servlet-class>com.li.furns.web.MemberServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MemberServlet</servlet-name>
<url-pattern>/memberServlet</url-pattern>
</servlet-mapping>
实现MemberServlet
package com.li.furns.web;
import com.li.furns.entity.Member;
import com.li.furns.service.MemberService;
import com.li.furns.service.impl.MemberServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class MemberServlet extends HttpServlet {
private MemberService memberService = new MemberServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取提交表单的hidden元素值,判断进行login还是register业务
String action = request.getParameter("action");
if ("login".equals(action)) {
//进入登录业务
login(request, response);
} else if ("register".equals(action)) {
//进入注册业务
register(request, response);
}
}
public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收用户名和密码
//如果前端输入的是null,后台接收的数据为空串""
String username = request.getParameter("username");
String password = request.getParameter("password");
//构建一个member对象
Member member = new Member(null, username, password, null);
//2.调用MemberServiceImpl的login方法
if (memberService.login(member) == null) {//数据库中没有该用户,返回登录页面
//登录失败,将错误信息和登录会员名放入request域中
request.setAttribute("errInfo", "登录失败,用户名或者密码错误");
request.setAttribute("username", username);
//注意路径
request.getRequestDispatcher("/views/member/login.jsp")
.forward(request, response);
} else {
//否则,跳转到登录成功页面
request.getRequestDispatcher("/views/member/login_ok.html")
.forward(request, response);
}
}
public void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收用户注册信息--参数名要以前端页面的变量名为准
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
//如果返回false,说明该用户信息可以注册
if (!memberService.isExistsUsername(username)) {
//构建一个member对象
Member member = new Member(null, username, password, email);
if (memberService.registerMember(member)) {
//如果注册成功,请求转发到register_ok.html
request.getRequestDispatcher("/views/member/register_ok.html")
.forward(request, response);
} else {
//注册失败,请求转发到register_fail.html
request.getRequestDispatcher("/views/member/register_fail.html")
.forward(request, response);
}
} else {//否则不能进行注册
//请求转发到login.html
//后面可以加入提示信息
request.getRequestDispatcher("/views/member/login.jsp")
.forward(request, response);
}
}
}
虽然方案一也可以实现业务需求,但是随着业务的增加,if-else语句也会随之增多,代码可读性变差,因此这里使用第二种方案实现,思想如下:
每一个业务Servlet类中都会有doPost和doGet方法,现在创建一个BasicServlet抽象类,其他的业务Servlet类都继承BasicServlet抽象类。
将业务类中的doPost和doGet方法抽象到BasicServlet中,当http请求到业务类时,因为业务类中没有重写doPost和doGet,就会到父类BasicServlet中找并调用。
同时在父类BasicServlet的doPost()方法中使用动态绑定,通过反射去获取到子类中的某个业务方法,然后调用。
修改MemberServlet,将doPost方法抽象到父类BasicServlet中:
package com.li.furns.web;
import com.li.furns.entity.Member;
import com.li.furns.service.MemberService;
import com.li.furns.service.impl.MemberServiceImpl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
/**
* 该Servlet处理和Member相关的请求
*
* @author 李
* @version 1.0
*/
public class MemberServlet extends BasicServlet {
private MemberService memberService = new MemberServiceImpl();
/**
* 处理会员登录业务
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接收用户名和密码
//如果前端输入的是null,后台接收的数据为空串""
String username = request.getParameter("username");
String password = request.getParameter("password");
//构建一个member对象
Member member = new Member(null, username, password, null);
//2.调用MemberServiceImpl的login方法
if (memberService.login(member) == null) {//数据库中没有该用户,返回登录页面
//登录失败,将错误信息和登录会员名放入request域中
request.setAttribute("errInfo", "登录失败,用户名或者密码错误");
request.setAttribute("username", username);
//注意路径
request.getRequestDispatcher("/views/member/login.jsp")
.forward(request, response);
} else {
//否则,跳转到登录成功页面
request.getRequestDispatcher("/views/member/login_ok.html")
.forward(request, response);
}
}
/**
* 处理会员注册业务
*
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收用户注册信息--参数名要以前端页面的变量名为准
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
//如果返回false,说明该用户信息可以注册
if (!memberService.isExistsUsername(username)) {
//构建一个member对象
Member member = new Member(null, username, password, email);
if (memberService.registerMember(member)) {
//如果注册成功,请求转发到register_ok.html
request.getRequestDispatcher("/views/member/register_ok.html")
.forward(request, response);
} else {
//注册失败,请求转发到register_fail.html
request.getRequestDispatcher("/views/member/register_fail.html")
.forward(request, response);
}
} else {//否则不能进行注册
//请求转发到login.html
//后面可以加入提示信息
request.getRequestDispatcher("/views/member/login.jsp")
.forward(request, response);
}
}
}
创建BasicServlet,在该抽象类中使用使用模板模式+反射+动态绑定
package com.li.furns.web;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* 业务servlet的共同父类
* BasicServlet 是供子类去继承的,不需要在web.xml中配置
* 使用模板模式+反射+动态绑定===>简化了多个if-else的语句
*
* @author 李
* @version 1.0
*/
public abstract class BasicServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取提交表单的隐藏域元素的值
//如果我们使用模板模式+反射+动态绑定,要满足action的值要和方法名一致
String action = req.getParameter("action");
//使用反射,获取到当前对象的方法
//1.this就是请求的业务Servlet,即运行类型
//2.declaredMethod 方法对象就是当前请求的业务servlet对应的action名称的方法
try {
/**
* public Method getDeclaredMethod(){}
* 该方法返回一个Method对象,它反射此Class对象所表示的类或接口的指定已声明方法。
* 参数:此方法接受两个参数:
* -方法名称,这是要获取的方法。
* -参数类型 这是指定的方法的参数类型的数组。
* 返回值:此方法以 Method 对象的形式返回此类的指定方法。
*/
Method declaredMethod =
this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
//使用方法对象进行反射调用
//public Object invoke(Object obj, Object... args){}
declaredMethod.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
之后再去开发业务类,只需要继承BasicServlet即可,推荐使用方案二
注册业务:

登录业务:

我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析: 在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1: print(k)k=k/2A.1000 B.10C.11D.9解析: 按照题意每次循环K/2,直到K值小于等
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定