最近在csdn上看到不少有关javaweb开发的概念陈述,有些使用的专业术语简直让我一个菜鸟大学生望而却步,实在没有往下读完的欲望。今天突发奇想,说说我自己对javaweb开发的基础见解。
我必须得假设偶然看到这篇文章的读者们都是对javaweb开发有简单了解的,所以使用其他语言的童鞋们可能不太懂我接下来要说的东西。
Servlet
我们都知道,Servlet是用于做后端服务的,它本质上是一个页面,只是它写的都是java代码。最常见的手法是通过前端页面中的form表单来向后台Servlet页面发送参数,Servlet就负责处理这些数据,更多的是会通过这些参数来获取或是设置数据库中的数据,然后再通过response对象回写到浏览器中。不过,当我们学习了ajax之后,便不再使用这样的形式了,而且我认为使用ajax是最好的方式,因为它灵活可控,而且不会强制跳转页面,更容易做提交反馈了。
我们来看一个负责控制登录的LoginServlet案例,这个代码是我手写的,大佬勿喷。
@WebServlet(name = "LoginServlet", value = "/LoginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 先设置响应的字符集是utf-8
response.setContentType("text/html;charset=UTF-8");
String username="'"+request.getParameter("username")+"'";
String password="'"+request.getParameter("password")+"'";
String login_sql= SqlStrCreater.two_parm_selectsql("user",
"=","用户名",username,"and",
"=","密码",password);
ArrayList<Map<String,Object>> user_list= (ArrayList) SqlTableUtils.getTableRecordList(login_sql);
// System.out.println(user_list);
if(user_list!=null){
User user=new User(username,password, (String) user_list.get(0).get("权限等级"));
request.getSession().setAttribute("user",user);
response.getWriter().write("<script>" +"window.location.href='oa_index.jsp'"+
"</script>");
}else {
// 登录信息有误,请重新输入
response.getWriter().write("<script>" +"alert('用户名或密码错误');window.location.href='index.jsp'"+
"</script>");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
HttpServlet通过request对象下的getParameter方法来通过键获取值,实际上是通过input的name值来获取value,当然你也可以用getParameterMap方法来获取所有的键值对,然后再挨个处理,获取完数据后,通过写好的sql工具来判断用户输入的用户名和密码是否正确,若正确,将用户对象存入Session(这个对象待会再说)中并跳转界面。若不正确,通过js的alert函数提醒用户它输入错误并返回到登录界面重新输入,当然,这是一般提交方式,如果你使用ajax,那就不用跳转回来了,反正它也不跳转到Servlet页面下,仅仅提交请求。必须要说明的是,Servlet可以回写html代码,但是它很不方便,就像上边这个实例一样,它通过response对象获取一个写出流Writer,然后通过write或者print方法回写html代码,这意味着你不能大量地在Servlet中编写html,即使你很能肝,代码的可读性是硬伤。
JSP
就像我刚才说的,在Servlet中能够编写html代码,但它很复杂,也很难看。所以,jsp就诞生了,jsp本质上也是一个Servlet,不过呢,Servlet是在java代码中混入html,而jsp是在html中混入java代码。我们在jsp编码过程中,可以使用html的一切语法,还可以通过<%>java代码<%>这样的形式来写入java代码,这样,我们就可以在jsp中直接获得后台的数据并且渲染到页面上了。不得不说的是,jsp还内置了一些对象,我们可以直接调用,有out、response、request、session、jspcontext、pagecontext和application。
我们先来看以下这部分jsp代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String UserName=request.getParameter("UserName");
%>
<html>
<head>
<title>
用户界面
</title>
</head>
<body>
<h1>
欢迎您:<%=UserName>
</h1>
</body>
这个页面通过java来获取它接收到的参数,并且直接把内容渲染到了h1标签中,在<%=>中直接填入变量名就可以实现这一点。不过要注意的是,页面依然是从上至下加载的,我的习惯是将数据的获取写在页面的顶部,这样会优先加载,后来我要考虑的就只是数据的渲染位置和样式了。
<thead>
<tr>
<th>序号</th>
<%
if (TableColNames!=null){
for (int i=0;i<TableColNames.size();i++){
%>
<th>
<%=TableColNames.get(i)%>
</th>
<%
}
}else {
response.getWriter().write("<script>alert('查询出现异常,该表可能不存在');</script><div style='color:red;'>表头异常!</div>");
}
%>
</tr>
</thead>
这是一个table表格的表头,从第二个th开始是它的表头属性,如果获取到的属性集合是空的话,就提示用户异常,如果有的话,就写一个循环渲染它们。
最后要说的是,jsp实际上在编译时,会被编译成一个Servlet,这个问题,大家在看class字节码文件时应该就能看明白,实际上它是用了out写出流回写html语句的,这就证明了jsp本质上就是一个servlet。
在javaweb项目中,我们应该尽量使用jsp页面来替代所有的html页面。
Request
Request对象是Servlet的内置对象,它代表一次请求。当请求发送时,它诞生,请求完成后,它就随之销毁了。我们可以通过此对象来获取参数,这个在上边的案例代码中已经有所介绍。我们还可以通过这个对象来获取Session、获取请求头、获取字符编码、获取Cookie啊等等等等。常用的是获取Cookie和Session。另外,request对象还可以请求转发
request.getRequestDispatcher("页面地址").forward();
来实现跳转页面。
Response
说完Request(其实才说了一点点),当然要说Response对象,有请求,自然就有响应。它就代表一次响应。服务器通过Response对象下的一系列方法来向客户端回送数据,常见的就是通过getWriter()方法获取输出流,然后写出数据。
Response对象拥有回写Cookie的能力,这个我正常会在做‘记住密码’时用到,这里就不细说Cookie的含义和功能了,不了解的童鞋可以自己去查阅资料。
哦对了,一般情况下,response对象要想回写中文的话,需要先设置ContentType为utf-8,使用这段代码就可以解决
response.setContentType("text/html;charset=UTF-8");
另外,response对象有一个重定位方法,来实现跳转页面,但是它的机理实际上和request的请求转发是不同的,在用法上也有区别,以下是代码
response.sendRedirect("页面地址");
Session
Session对象代表一次会话,在用户访问项目时,就会产生一个只属于那个用户的Session,它只为该用户服务,当用户关闭浏览器窗口时,它就销毁了。(当然,也可以通过invalidate()方法手动销毁)
Session是用来解决用户状态保持的问题的,我们常常会将用户登录的信息存放在Session中,当会话结束时,我们也就默认用户下线了。
我们可以通过request来获取session,再使用setAttribute(key,object)方法来将用户对象user存入到session里面,要获取时,再用相应的get方法就行了。要删除Attribute时,使用remove方法就可以了。
要注意的是,session是有时效性的,当超过了规定时间后,session就会自我销毁,常见案例是“您的登录已失效,请重新登录”,但是,我们可以通过以下方法来设置这个规定时间
session.setMaxInactiveInterval("毫秒值");//int类型
开头有说,session是只属于一个用户的,所以它还有个getId()方法来获取一个用户唯一标识,这个值,每个客户端都会不一样。
ServletContext
这个对象代表上下文,这样说可能不太好理解,实际上,这就是我们项目整体的一个总控。它在服务器启动时诞生,在服务器关闭时销毁。它可以直接在servlet中get到,或者通过request和sesson对象获取。一个项目只有唯一的一个context对象,它存储了我们项目的一些整体信息。它可以用来添加过滤器、监听器、Servlet,获取项目路径、服务器信息、启动参数等等。
String realPath=getServletContext().getRealPath("");//获取web项目根路径
它和request、session一样,也有自己的Attribute域,在这里存放的数据,是属于整个项目的,也就是说,每个用户都可以共享这些变量。
小结
监听器、过滤器的用法先不说了,如果掌握了以上内容,应该也能写出点东西了吧...
要说明的是,实际上这样的传统开发手法并没有实现前后端分离,这样去直接写jsp的话,其实会使得前后端的工作之间难以独立,往往前端人员将模板制作出来后交付于后端,后端人员需要再过一遍前端代码,然后在jsp中写入java代码,开发效率大大降低。
在下一篇文章中,我会谈谈我个人对前后端分离开发的看法。
这篇文章仅服务于入门javaweb的小伙伴们,也是我第一次写文章,请大佬们勿喷。