Javaweb学习
1.Servlet
Servlet接口有两个默认实现类,GenericServlet、HttpServlet(继承自GenericServlet类)
Servlet接口有如下方法:
void init(ServletConfig var1) throws ServletException;
?
ServletConfig getServletConfig();
?
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
?
String getServletInfo();
?
void destroy();
GenericServlet 没有重写 service 函数,HttpServlet 重写了 service 函数,处理了多种请求方式。
开发一个Servlet程序,需要:
-
建立一个空的Maven项目,删掉src目录,以后在项目里建module,空的即是主工程;主工程包含多个Module,子项目可以使用父工程的所有,配置xml文件,添加依赖项。
-
新建Module,编写maven子工程,配置项目的web-info下的web.xml为最佳配置,编写一个实现Servlet接口的类
-
把开发好的java类部署到web服务器中:注册Servlet,配置映射路径,映射路径可有多个(/hello/*),可自定义后缀( *.do),可通配所有( / *)
-
配置Tomcat,设置项目为 s1,启动测试,如下代码访问链接为:http://localhost:8080/s1/hiii
package com.wang.servlet;
?
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.io.PrintWriter;
?
public class HelloServlet extends HttpServlet {
?
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.write("Hello, Hello, Hello!");
}
?
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<?xml version="1.0" encoding="UTF-8"?>
?
hi
com.wang.servlet.HelloServlet
hi
/hiii
?
浏览器发送请求给web服务器,web服务器(如Tomcat服务器)获取请求,交给servlet,servlet通过service函数,处理请求得到响应,交给web服务器,传给浏览器作为响应。
1.1 ServletContext
可共享数据、可获取初始化参数、可请求转发、可读取资源文件
// 文件1设置参数
this.getServletContext().setAttribute("userName", new String("wang"));
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println("ServletContext1执行");
// 文件2读取参数、资源、请求转发
// 实现共享数据
String name = (String)this.getServletContext().getAttribute("userName");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println(name);
?
// 实现请求转发
RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/ser1");
dispatcher.forward(req, resp);
?
// 实现获取资源配置文件
// 不在resources目录下的properties文件,需要在主工程下的xml里面配置build标签,再重启IDEA即可
InputStream stream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/wang/servlet/aa.properties");
Properties properties = new Properties();
properties.load(stream);
String user = (String)properties.get("user");
Object pwd = properties.get("pwd");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println(user);
resp.getWriter().println(pwd);
1.2 HttpServletResponse
-
实现打印文字信息
-
实现文件下载
String res = "D:\\idea_java_projects\\javaweb_servlet_2\\servlet_response\\src\\main\\resources\\壁纸.jpg"; String fileName = res.substring(res.lastIndexOf("\\") + 1); // 设置浏览器可下载,即设置消息头参数 resp.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(fileName,"utf-8")); FileInputStream fis = new FileInputStream(res); ServletOutputStream os = resp.getOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = fis.read(buffer)) != -1) { os.write(buffer, 0, len); } System.out.println("成功!"); os.close(); fis.close();
-
实现图片验证码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 图片验证码实现 // 设置网页的刷新率,每5秒刷新一次 resp.setHeader("refresh", "5"); // 创建保存在内存中的image BufferedImage image = new BufferedImage(200,50,BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); g.setColor(Color.orange); g.drawRect(0,0,200,50); g.setColor(Color.blue); g.setFont(new Font("宋体", Font.BOLD, 30)); g.drawString(getNum() ,30, 40); // 告知浏览器以图片形式打开 resp.setContentType("image/jpg"); // 删除网站缓存 resp.setDateHeader("expires", -1); resp.setHeader("Cache-Control", "no-cache"); resp.setHeader("Pragma", "no-cache"); // 图片写给浏览器 ImageIO.write(image,"jpg",resp.getOutputStream()); } protected String getNum() { String num = new Random().nextInt(99999999) + ""; StringBuffer stringBuffer = new StringBuffer(); for (int i = 0; i < 8 - num.length(); i++) { stringBuffer.append(new Random().nextInt(10) + ""); } return stringBuffer.append(num).toString(); }
-
实现重定向
req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); String username = req.getParameter("username"); String pwd = req.getParameter("pwd"); String[] hobbies = req.getParameterValues("hobby"); System.out.println("================="); System.out.println(username+":"+pwd+";"+ Arrays.toString(hobbies)); System.out.println("================="); // 请求转发 req.getRequestDispatcher("/success.jsp").forward(req, resp); // 重定向 resp.sendRedirect("/servlet_response_war/success.jsp");
1.3 HttpServletRequest
主要使用 getParameter、getParameterValues、getRequestDispatcher等
重定向:访问路径(url)发生变化,请求两次,需要加上web应用的名字,因返回根目录
请求转发:访问路径(url)不变,请求一次,不能加上web应用的名字,因返回项目目录
<%-- form 表单的 action 设置为转向的路径 --%>
2.Cookie and Session
Cookie
req.getCookies();
cookie.getName();
cookie.getValue();
cookie.setMaxAge(); // 设置有效期为0,手动删除cookie
resp.addCookie();
// 手动删除cookie下的last_time,即清除缓存
Cookie cookie = new Cookie("last_time", System.currentTimeMillis() + "");
cookie.setMaxAge(0);
resp.addCookie(cookie);
Session
// 设置编码格式
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
// Session1 : 设置session信息
HttpSession session = req.getSession();
session.setAttribute("name", "王");
if (session.isNew()) {
resp.getWriter().write("session 创建成功,Id为" + session.getId());
} else {
resp.getWriter().write("session 已创建,Id为" + session.getId());
}
// Session2 : 获取session信息
HttpSession session = req.getSession();
String name = (String)session.getAttribute("name");
System.out.println(name);
// Session3 : 手动删除Session信息
HttpSession session = req.getSession();
session.removeAttribute("name");
session.invalidate();
亦可在 xml 文件中配置 session 的存活时间
3
3.JSP
Java Server Pages:Java代码原封不动,HTML以网页形式读取,JSP帮助简化网页
JSP 基本语法和指令:
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page errorPage="error.jsp" %>
Title
<%--变量、表达式--%>
<%= new Date(System.currentTimeMillis()) %>
<%--Java片段--%>
<% for (int i = 0; i < 5; i++) {%>
Hello World!
<% } %>
<%= global_var%>
<%--变量声明--%>
<%! int global_var = 10;%>
<%--JSP注释--%>
<%= 1/0 %>
9大内置对象:
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
pageContext、Request、Response、Session、Application、config、out、page、exception
从底层到高层(作用域):以下均可以 setAttribute
PageContext(当前页面)
Request(一次请求,请求转发,放新闻)
Session(一次会话,关闭浏览器消失,加购物车)
Application(关闭服务器消失,多用户 聊天记录)
// 实现请求转发,请求转发会将请求的数据携带
pageContext.forward();
JSP标签
<%--包含某个页面--%>
<%--请求转发至某个页面,可携带参数--%>
JSTL核心标签:c:if,c:choose,c:when,c:forEach (不常用) EL表达式 ${}
<%
int[] nums = new int[]{2,4,6,3,9};
request.setAttribute("nums", nums);
%>
JavaBean 实体类
4.MVC
View:视图(JSP,展示数据,提供用户操作)
Controller:控制器(Servlet,处理请求、控制视图跳转,响应交给业务层)
Model: 控制业务操作、增删改查数据,包括业务层(Service)、数据持久层(Dao)、JavaBean(实体类 :pojo、entity、vo、dto)
5.过滤器 (重要)
filter 过滤器过滤网站的数据,导包,实现Filter接口,配置web.xml
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
System.out.println("执行前");
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("执行后");
}
filter1
com.wang.filter.Filter1
filter1
/servlet/*
且过滤器在服务器打开时就初始化,服务器关掉后才会销毁。
6.监听器
Listener 实现监听器接口,配置web.xml
public void sessionCreated(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer count = (Integer)context.getAttribute("OnlineCount");
if (count == null) {
count = 1;
} else {
count++;
}
context.setAttribute("OnlineCount", count);
}
?
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer count = (Integer)context.getAttribute("OnlineCount");
if (count == null) {
count = 0;
}else {
count--;
}
context.setAttribute("OnlineCount", count);
}
com.wang.listener.Listener1
当前有<%= request.getServletContext().getAttribute("OnlineCount")%> 人在线
报错异常java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/ConditionalTagSupport,应该从 http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/ 下载jakarta-taglibs-standard-1.1.2.zip这个包,解压缩后将standard和jstl两个包放入tomcat下的lib下即可
界面显示不出来其实是因为 其他jsp放在head.jsp后面,用一个标签session,前一个在head,后一个在相应页面,不能擅自给head添加session,不然界面跑到下面去!!!
8.其他
文件上传
-
为保证服务器安全,上传文件应该放在外界无法直接访问的目录,比如web-inf文件下
-
为防止覆盖,要为上传文件产生一个唯一文件名(时间戳,uuid,md5,位运算算法)
-
要限制上传文件的最大值(服务器耗钱)
-
限制上传文件的类型,判断后缀名是否合法
ServletFileUpload 负责处理上传的文件数据,将表单中的每个输入项封装成一个FileItem对象,在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象。所以需要在进行解析工作前构造好DiskFileItemFactory 对象,通过ServletFileUpload对象的构造方法或者setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性。
1、创建DiskFileItemFactory 对象,处理文件上传路径或者缓存文件大小限制
2、创建ServletFileUpload 对象,传入1的对象作为构造函数参数,可监听文件上传进度、处理乱码问题、设置单个文件的最大值、设置总共能够上传文件的大小
3、处理上传文件:ServletFileUpload 对象将前端请求解析封装成FileItem对象,读取FileItem的数据,进行后续处理
邮件发送
需要 mail.jar 包和 activation.jar 包
设置服务器、邮箱发送协议等信息,新建 Session 对象,通过 Session 得到 transport 对象,使用邮箱的用户名和密码 connect 邮件服务器,创建发送邮件 MimeMessage 对象,发送邮件,关闭连接。
MimeBodyPart()描述一个邮件的一部分,比如文字、图片、附件,MimeMultipart()作为一个容器,包含其他数据,并设置 alternative / related / mixed,最后将 MimeMultipart 放到 MimeMessage 中。
异步处理,多线程,email 继承 Thread 类,实现多线程,防止网页一直加载页面不出来,影响用户体验。