简单架构介绍:
C/S:客户端/服务端
B(Browser)/S(Server):浏览器/服务器(例:Tomcat)
Jsp文件介绍:
jsp(Java Server Pages)—java服务端页面,运行在服务器端,是一个以.jsp为后缀的文本文件
html、css—java客户端页面,运行在客户端
在jsp文件中可以出现的代码
html代码
jsp指令
page指令:
language:开发语言
contentType:服务器返回的数据类型
charset:服务器返回编码格式
pageEncoding:当前页面编码格式
java代码
常见错误码:
404:路径错误,应该检查文件所在位置及路径书写是否正确
500:代码错误
a.前端代码
<body>
<%--
<!--方式一:通过java代码获取绑定值,该方法已经过时,尽量不在jsp中加入java代码-->
<!--java代码-->
<%
String str=(String)request.getAttribute("login_error");
%>
<form action="StudentServlet?flag=login" method="post">
用户名:<input type="text" name="sname" /><br/>
密 ; 码:<input type="password" name="spwd" /><br/>
<span style="color:red">
<!--jsp表达式,该表达式意为输出该值-->
<%=str==null?"":str%>
</span>
<input type="submit" value="登录" />
</form>
--%>
<!--方式二:使用EL表达式通过绑定名获取绑定值-->
<form action="StudentServlet?flag=login" method="post">
用户名:<input type="text" name="sname" /><br/>
密 码:<input type="password" name="spwd" /><br/>
<span style="color:red">${login_error}</span>
<input type="submit" value="登录" />
</form>
</body>
注1:通常情况下一张表的所有操作都由一个Servlet完成,如何实现?可以通过在表单提交数据时附带一个参数,这个参数就是代表该表单提交的数据所要进行的操作,然后由服务端获取该参数,再通过条件语句执行对应的逻辑,所以需要对之前的doGet方法以及注册页面进行一些改动,在注册页面中也添加相应的flag值为regist,使得同一个servlet中的同一个方法可以完成对一个表的多个操作,给表单附带参数方法为Servlet?flag=?,如login.jsp页面代码中的action值所示。
注2:EL表达式(Excepression Language):表达式语言,结构是${},可用来替代jsp中的java表达式
b.StudentServlet代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//由于浏览器端设置编码集为UTF-8,而服务器端未设置编码集,所以服务器端会默认使用ISO-8859-1编码集进行解码,就会出现乱码,故需要在服务器端也设置编码集为UTF-8
request.setCharacterEncoding("UTF-8");
//先获取flag的值
String flag=request.getParameter("flag");
//获取student的操作接口对象
IStudentDAO dao=new StudentDAOImpl();
//注册
if("regist".equals(flag)){
//拿到表单发送的数据
//getParameter()方法为获取对应表单值,返回值为字符串类型
//根据表单中的参数名获取参数值,如果参数名与表单中所写表单名不一致,则服务端接受到的表单值为null
String sname=request.getParameter("sname");
String spwd=request.getParameter("spwd");
//因为拿到的为字符串类型,而student类中age为int类型,故需要类型转换
int sage=Integer.parseInt(request.getParameter("sage"));
String ssex=request.getParameter("ssex");
//将数据存入到数据库
//将数据封装为Student对象
Student stu=new Student(sname,spwd,sage,ssex);
//调用dao的保存方法,将stu对象保存到数据库
dao.saveStudent(stu);
//注册成功以后重新访问login.jsp文件
//通过重定向方法,使得注册成功后服务器能够返回登录页面
response.sendRedirect("login.jsp");
}
//登录
if("login".equals(flag)){
String sname=request.getParameter("sname");
String spwd=request.getParameter("spwd");
Student stu=dao.findStudentBySnameAndSpwd(sname, spwd);
if(stu==null){
//查无此人,则进行提示并返回登录页面
//设值绑定,将某绑定值绑定至request并给其一个绑定名,则重定向文件可通过该绑定名获取该绑定值
//第一个参数为绑定名,第二个参数为绑定值
request.setAttribute("login_error","查无此人");
//请求转发
request.getRequestDispatcher("login.jsp").forward(request, response);
}else{
//显示
}
}
}
注:重定向为一次请求一次响应一次请求一次响应,在用户登录失败时应该再次返回登录页面并进行提示,所以应该在servlet方判断后向login发送登录失败信息,如何发送信息?可以通过request.setAttribute(arg0,arg0)方法,第一个参数绑定名与第二个参数绑定值来传送信息至jsp端,但是由于重定向时第二次请求时第一次绑定的数据会被清空,所以就回导致并未将提示信息发送至jsp端,如何解决?不使用重定向,而使用请求转发request.getRequestDispatcher().forward(request,response)方法,第一个方法为获取请求,参数为所要请求的页面,第二个方法为转发,转发方法有两个参数,第一个为请求,第二个为响应,如果查无此人,则进行提示并返回登录页面
代码实现效果:
c.Student
Student类中增加一个带sid的构造方法
d.IStudentDAO代码
public interface IStudentDAO {
public void saveStudent(Student stu);
//通过用户名及密码只能查到一个学生对象,所以用户名不允许重复,但在本例中不进行实现
public Student findStudentBySnameAndSpwd(String sname,String spwd);
}
e.StudentImpl新增代码
public Student findStudentBySnameAndSpwd(String sname, String spwd) {
Student stu=null;
try{
conn=DBUtil.getConnection();
ps=conn.prepareStatement("SELECT sid,sname,spwd,sage,ssex FROM student WHERE sname=? AND spwd=?");
ps.setString(1,sname);
ps.setString(2,spwd);
rs=ps.executeQuery();
if(rs.next()){
stu=new Student(rs.getInt("sid"),sname,spwd,rs.getInt("sage"),rs.getString("ssex"));
}
}catch(Exception e){
e.printStackTrace();
}finally{
DBUtil.closeConnection(rs, ps, conn);
}
return stu;
}