所有的抽象方法都写在类的最后。
所有的抽象方法都写在类的最后。
操作路径不要使用"?"的形式完成
1. 如果使用地址重写处理参数,"?"对于整个程序的设计非常麻烦
2. 如果使用了表单提交,意味着需要传递一个隐藏域表示状态
要想使用Servlet进行多业务处理,可以从路径下手
http://localhost:8080/myproject/empservlet/edit
DispatcherServlet程序类
MVC的本质含义:
- 所有用户的请求使用Servlet统一进行处理
- 处理后的结果发给JSP进行显示
- 同时使用EL+JSTL简化Scriptlet
- 任何的一次提交都不要直接到jsp页面,必须经过Servlet
MVC模式中将请求交给Servlet处理的原因
1. Servlet可以实现数据的验证处理
2. 可以对数据进行一些先期的处理
3. Servlet是纯粹的Java程序,可以使用更多的可重用设计,简化代码
4. Servlet可以使用request属性,传递显示内容到JSP页面(请求转发)
多业务支持
概念:是指一个Servlet可以处理不同的用户操作
1. 不管程序使用了多少开发技术,要进行WEB的请求处理,只能使用Servlet中的doGet(), doPost(),两个方法实现
2. 要实现多业务的操作处理,最简单方案是在每次发送请求的时候设置一个请求标志位
初步实现
@WebServlet(urlPatterns="/empservlet")
//列表操作:http://localhost:8080/myproject/empservlet?status=list
//修改操作:http://localhost:8080/myproject/empservlet?status=edit
//增加操作:http://localhost:8080/myproject/empservlet?status=add
public class EmpServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String urlPage = "/errors.jsp";
String status = req.getParameter("status");
if(status!=null && "".equals(status)){
if("add".equals(status)){//有状态码,区分不同的用户请求
urlPage = this.add(req,resp);
}else if("edit".equals(status)){
urlPage = this.edit(req,resp);
}else if("list".equals(status)){
urlPage = this.list(req,resp);
}
}
req.getRequestDispatcher(urlPage).forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
this.doGet(req,resp);
}
public String list(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
System.out.println("*****【Servlet输出】列表雇员信息");
return "/emp_list.jsp";
}
public String add(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
System.out.println("*****【Servlet增加】列表雇员信息");
return "/forward.jsp";
}
public String edit(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
System.out.println("*****【Servlet修改】列表雇员信息");
return "/forward.jsp";
}
}
不能使用?的形式完成的原因
1. 如果使用了地址重写处理参数,那么这个"?"对于整个程序的设计非常致命
2. 如果使用了表单提交,意味着还需要传递一个隐藏域表示状态
MySQL数据库的安装与配置
MySQL的下一代产品:MariaDB(Google主要使用的数据库)
MySQL的默认端口为:3306
常用命令:
连接MySQL
mysql -uroot -p123456
查看帮助:
help
查看所有的数据库
show databases;
创建数据库,设置编码为utf8
create database mldn character set utf8;
切换数据库
use meiis;
创建数据表
create table member(
mid int auto_increment,
name varchar(50),
age int,
salary double,
birthday date,
note text,
constraint pk_mid primary key(mid)
);
查看所有数据表
show tables;
表中增加数据
insert into member(mid,name,age,salary,birthday,note) values(1001,"admin",18,5000.0,"1993-10-12","hello world");
取得当前增长后的session内容
select last_insert_id();
分页支持
select 字段 from 表格 where 条件 limit 开始数据行,长度;
Annotation配置Servlet
@WebServlet(urlPatterns="/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
resp.getWriter().print("<h1>hello world!</h1>");
}
}
配置Filter
@WebFilter(urlPatterns="/*")
public class MyFilter implements Filter {
}
配置监听器
@WebListener
public class MyListener implements ServletContextListener {
}
监听器(Listener)
作用:可以检测整个WEB的执行情况
上下文监听(ServletContext(application)的监听机制)
- 1. 对Servlet上下文状态监听:ServletContextListener
· 上下文初始化
public void contextInitialized(ServletContextEvent sce);
· 上下文销毁
public void contextDestroyed(ServletContextEvent sce);
· ServletContextEvent事件的方法
public ServletContext getServletContext();
- 2. 对Servlet上下文属性监听: ServletContextAttributeListener
· 属性增加
public void attributeAdded(ServletContextAttributeEvent event);
· 属性替换
public void attributeReplaced(ServletContextAttributeEvent event);
· 属性删除
public void attributeRemove(ServletContextAttributeEvent event);
实现对上下文的监听
public class MyListener implements ServletContextListener, ServletContextAttributeListener{}
web.xml中配置监听
<listener>
<listener-class>cn.my.listener.MyListener</listener-class>
</listener>
上下文是针对于整个服务器的监听,大部分情况需要进行的是用户(session)监听操作,需要使用以下两个接口
1. 对于session状态监听,使用HttpSessionListener
- 创建session:
public void sessionCreated(HttpSessionEvent se);
- session销毁
public void sessionDestroyed(HttpSessionEvent se)
- 事件:HttpSessionEvent
-- 取得当前session对象
public HttpSession getSession():
2. 对session属性进行监听,使用 HttpSessionAttributeListener
- 增加session属性
public void attributeAdded(HttpSessionBindingEvent event);
- 删除session属性
public void attributeRemoved(HttpSessionBindingEvent event);
- 替换session属性
public void attributeReplaced(HttpSessionBindingEvent event);
- 事件:HttpSessionBindingEvent 方法
-- 取得属性名称:
public String getName();
-- 取得属性内容:
public Object getValue();
-- 取得当前session:
public HttpSession getSession()
关于session的销毁
在session的运行过程中,客户端和服务器端并不会一直保持连接,用户关闭浏览器时,服务器只会认为该客户暂时离开,等下还会发出请求,所以不会销毁session。
需要销毁session的两种情况
1. session对象中invalidate()方法的调用,表示立刻销毁Session
2. 服务器有一个自己的销毁时间,Tomcat是30分钟,用户可以在conf/web.xml文件对其配置进行修改(session保存的时间越长,对服务器的负担就越大)
<session-config>
<session-timeout>30</session-timeout>
</session-config>
过滤器
Servlet实际上分为3中:普通Servlet(MVC),过滤Servlet(FIlter),监听Servlet(Listener)
过滤器实现
1. 过滤操作的使用是自动进行调用的
2. 实现过滤器需要实现 javax.servlet.Filter接口,该接口定义如下处理方法
- 初始化:
public void init(FilterConfig filterConfig) throws ServletException
- 执行过滤操作
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
- 销毁:
public void destroy()
建立一个过滤器
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("******过滤器初始化,初始化参数:" + filterConfig.getInitParameter("msg");
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException{
System.out.println("*******执行过滤******");
}
@Override
public void destroy(){
System.out.println("*******过滤器销毁*****");
}
}
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>cn.my.filter.MyFilter</filter-class>
<init-parm>
<param-name>msg</param-name>
<param-value>mlndjava</param-value>
</init-parm>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<!--过滤执行路径,如果设置为/*,表示所有的根目录下的内容都要求被过滤-->
<url-pattern>/*</url-pattern>
</filter-mapping>
所有的请求到了过滤器后被拦截,要想请求继续放行,需要FilterChain接口中的方法
public void doFilter(ServletRequest req, ServletResponse resp) throws IOException, ServletException
编写编码过滤器
public class EncodingFilter implements Filter {
private String charset = "UTF-8";
@Override
public void init(FilterConfig filterconfig) throws ServletException{
if(filterconfig.getInitParameter("charset")!=null){
this.charset = filterconfig.getInitParameter("charset");
}
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throw IOException, ServletException{
req.setCharacterEncoding(this.charset);
chain.doFilter(req,resp);
resp.setCharacterEncoding(this.charset);
}
@Override
public void destroy(){
}
}
web.xml中配置过滤器
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>cn.my.filter.EncodingFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
登录过滤
1. 设置过滤目录:例如/pages下的页面都必须登录后访问
2. 实例
- session属于HTTP协议范畴,要将ServletRequest变为HttpServletRequest
public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpSession session = request.getSession();
if(session.getAttribute("mid")!=null){//mid存在,代表已经登录
chain.doFilter(request,resp);
}else{
request.setAttribute("msg","你还未登录,请先登录");
request.getRequestDispatcher("/login.jsp").forward(request,resp);
)
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException{
}
@Override
public void destroy(){
}
}
- web.xml中配置filter
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>cn.my.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/pages/*</url-pattern>
</filter-mapping>
- 定义登录页面
<h1>${msg}</h1>
<%
if(request.getParameter("mid")!=null){
session.setAttribute("mid",request.getParameter("mid"));
}
%>
<form action="login" method="post">
登录用户名:<input type="text" name="mid" id="mid">
<input type="submit" value="提交">
</form>
<c:if>标签
<c:if test="" var=""></c:if>
- 1. test:进行数据的验证判断
- 2. var:保存判断的结果,此结果保存在page属性范围中
<c:if test="${allEmps!=null}" var="res">
有指定的属性存在
</c:if>
<h1>${res}</h1>
<c:forEach>标签
作用:实现迭代输出
核心参数:
- 1.items:表示每次要进行迭代输出的全部数据
- 2.var:表示每次迭代是取得单个对象的属性名称,自动保存在page属性范围内
<c:forEach items="" var="">
<c:if test="${allEmps!=null}">
<table border="1">
<tr>
<td>雇员姓名</td>
<td>雇员职位</td>
<td>部门编号</td>
<td>部门名称</td>
</tr>
<c:forEach items="${allEmps}" var="emp">
<tr>
<td>${emp.ename}</td>
<td>${emp.job}</td>
<td>${emp.dept.deptno}</td>
<td>${emp.dept.dname}</td>
</tr>
</c:forEach>
</table>
</c:if>
输出Map数据
Collection集合的目的是输出,Map集合的目的的是查找
MVC设计模式简介
JSP的核心功能:可以接收参数,进行显示,进行页面跳转
显示层(View):JSP, HTML, CSS, JavaScript
控制层(Controller):Servlet
- 接收数据,验证数据,调用业务,跳转页面
- 不负责数据的显示处理,只负责将数据交出给JSP
模型层(Module):
- 完成可重用类设计
MVC实现登录
1. 建立登录表单login.jsp,数据提交至servlet
2. Servlet接收表单参数,调用业务层(service)判断,根据结果跳转不同页面
3. 成功返回登录页index.jsp, 失败返回login.jsp
Servlet跳转
页面跳转的两种形式
1. 客户端跳转(页面改变,执行完跳转,无法传递reqeust属性)
2. 服务器端跳转(页面不改变,立刻无条件跳转,可以传递reqeust属性)
客户端跳转(重定向)
- 可以传递session,无法传递request属性
response.sendRedirect("show.jsp");
服务器端跳转
JSP页面中进行服务器跳转的2种方式
<jsp:forward page="" />
使用pageContext对象
pageContext.forward("");
通过Servlet实现服务器端跳转,必须依靠javax.servlet.RequestDispatcher接口
public RequestDispatcher getRequestDispatcher(String path)
req.getRequestDispatcher("/show.jsp").forward(req,resp)
99%情况下都使用服务器端跳转,且传递的属性范围都是reqeust属性范围。
取得内置对象
PageContext对象不能再Servlet中取得,它属于JSP页面
取得session对象(通过HttpServletRequest接口)
public HttpSession getSession()
取得application对象
GenericServlet类中的方法
public ServletContext getServletContext()
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext app = super.getServletContext();
System.out.println(app.getRealPath("/")+"*******");
}
HttpSession接口对象取得依靠的是HttpServletRequest(http协议)
ServletContext接口对象取得依靠的是GenericServlet(不受协议控制)
GenericServlet 和 HttpServlet 的区别
GenericServlet属于HttpServlet的父类,本身不受协议控制,HttpServlet只为Http服务
HttpServlet中的service()方法负责分配用户请求的处理,找到与之匹配的doXXX()方法
Servlet与表单
Servlet要接收表单数据的路径
- 假设input.jsp页面保存在了/pages/back/demo目录之中
1. Servlet设置在根目录中,在表单页面设置<base>属性
- web.xml配置Servlet
<servlet>
<servlet-name>inputServlet</servlet-name>
<servlet-class>com.my.servlet.InputServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>inputServlet</servlet-name>
<url-pattern>/input</url-pattern>
</servlet-mapping>
在表单jsp页面设置base路径,定义根目录
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServername()
+":"+request.getServerPort()+path+"/";
request.setCharacterEncoding("utf-8");
%>
<base href="<%=basePath%>"/>
表单路径
<form action="input" method="post">
</form>
Servlet程序
Servlet建立需要有web.xml文件,否则Servlet程序无法部署
需要继承 javax.servlet.http.HttpServlet 父类
Servlet程序属于Java程序,java程序保存在“/WEB-INF/classes”目录中(安全性很高),要进行Servlet的访问,需要在web.xml文件进行相关路径配置
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>cn.my.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
访问HelloServlet的路径
http://localhost:8080/myproject/hello
分页算法:
目的:减少数据的读取数量
实现基础分页
1. 基于算法分页
- 查询全部数据,将需要显示的部分进行显示输出,不需要现实的部分不进行输出
- 优点:可以在任意的数据库之间进行移植
- 缺点:性能不高
2. 基于数据库的分页
- 使用SQL语句直接进行分页
- 从前台表单接收参数currentpage, linesize
分页控制条
首页 上一页 下一页 尾页
Servlet(服务器端小程序)
Java版的CGI技术
采用了多线程的方式处理,性能更高
JSP是在Servlet之后发展起来的,与Servlet属于互补的关系
JSP能做的事情,Servlet都能做,但是反之不行
Eclipse EE创建WEB项目
1. 新建-Dynamic Web Project
2. WebContent是项目根目录,所有的JSP文件在该目录进行保存
3. WebContent中新建一个hello.jsp,会出错,原因是需要一些开发包的支持
- jsp-api.jar
- servlet-api.jar
4. 为项目建立服务器
- 选中项目-【run as】-【run on server】
- Manually define a new server
- 对应的Tomcat版本
MyEclipse使用
1. 创建WEB项目(新建-Web Project)
2. WebRoot 是整个项目的根目录,,相当于虚拟目录的路径
Tomcat配置虚拟目录
一个Tomcat服务器可以发布多个项目,每个项目自己的目录成为项目虚拟目录
配置步骤
1. 在E盘建立一个自己的mldnweb目录
2. 将Tomcat的 webapps/root 目录中的WEB-INF文件夹拷贝到 E:\mldnweb目录之中,此文件夹必须存在,且包含一个web.xml文件
3. 修改Tomcat的 conf/server.xml 文件
<Context path = "/mldn" docBase="e:\mldnweb" />
配置含义:
<Context> : 表示配置一个新的上下文环境
path:表示访问目录
docBase:表示该虚拟目录对应的真实路径
要想默认提供程序文件列表,可以修改 Tomcat 的conf/web.xml的文件内容
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
配置Tomcat
1. 修改连接端口号:conf/server.xml
<Connector port="80" protocol = "HTTP/1.1"....>
2. 配置域名
3. 调整内存参数
修改startup.bat文件
SET JAVA_OPTS = -server -Xmx20g -Xms20g-XX:PermSize=2g-XX:MaxPermSize=2g