【课程复习】Java Web、框架及项目简单回顾
JavaEE Day14 Servlet&HTTP&Request&BeanUtils介绍
Servlet类体系结构,两个子抽象类,需要继承HttpServlet而不是GenericServlet,并重写doget和dopost
一个servlet可以定义多个访问路径(注解): @WebServlet({"/demo4","/dd4"})
Hyper Text Transfer Protocol,定义客户端与服务器端通信时发送数据的格式,基于TCP/IP协议,默认80端口
基于请求响应,连接可以复用,请求过程无需建立新连接
request请求头格式:GET /login.html HTTP1.1,get不安全
request获取请求消息,response设置响应消息
Request对象的继承体系:ServletRequest-HttpServletRequest-tomcat创建了实现类
常见方法:getContextPath()、getRemoteAddr()、getRequestURI()、getParameter/Name/Values/Map()
get方式无乱码,post方式乱码解决:request.setCharacterEncoding("utf-8");
请求转发:服务器内部进行资源跳转(多个转发属于一个请求)---request.getRequestDispatcher(String path).forward(ServletRequest request,ServletResponse response),地址栏路径不会发生变化,只能转发到服务器内部资源
在有作用范围的对象中,可以在范围内共享数据(域对象),获取作用域对象(项目虚拟目录):ServletContext getServletContext()
request域:一次请求的范围内部,可以在请求转发过程中共享数据,setAttribute、getAttribute、removeAttribute
Druid连接池的Utils工具类
public class UserDao { //声明JDBCTemplate对象公用 private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); /** * 文档注释:登录方法 * @param loginUser 只有用户名和密码 * @return User 包含用户全部数据;没有查询到,返回null * 需要使用druid连接池才能实现,先创建一个工具类 */ public User login(User loginUser){ try { //1.编写sql String sql= "select * from user where username = ? and password = ?"; //2.调用query方法 User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), loginUser.getUsername(), loginUser.getPassword()); return user; } catch (DataAccessException e) { e.printStackTrace(); return null; } } }
BeanUtils简化数据封装
package cn.liujinhui.web.servlet; import cn.liujinhui.dao.UserDao; import cn.liujinhui.domain.User; import org.apache.commons.beanutils.BeanUtils; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.Map; @WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.设置编码 req.setCharacterEncoding("utf-8"); //2.获取请求参数 /*String username = req.getParameter("username"); String password = req.getParameter("password"); //3.封装user对象 User loginUser = new User(); loginUser.setUsername(username); loginUser.setPassword(password);*/ //2.获取所有请求参数 Map<String, String[]> map = req.getParameterMap(); //3.创建User对象 User loginUser = new User(); //3.2使用BeanU体力上封装 try { BeanUtils.populate(loginUser,map); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } //4.调用UserDao的login方法 UserDao userDao = new UserDao(); try { User user = userDao.login(loginUser); //5.判断uswr if(user==null){ //登录失败 req.getRequestDispatcher("/failServlet").forward(req,resp); }else{ //登录成功 //存储数据 req.setAttribute("user",user); req.getRequestDispatcher("/successServlet").forward(req,resp); } } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } }
Day15 Response
HTTP响应状态码:1-服务器未接收完成,2-成功(200),3-重定向、访问缓存,4-客户端错误,5-服务器错误
response(代表客户端)可以实现重定向(和转发都是实现资源跳转的方式)
package cn.liujinhui.web.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * 重定向 */ @WebServlet("/responseDemo1") public class ResponseDemo1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //访问/responseDemo1,会自动跳转到/responseDemo2资源 System.out.println("demo1..."); //1.设置状态码为302 /*response.setStatus(302); //2.设置响应头location response.setHeader("location","/day15/responseDemo2");*/ request.setAttribute("msg","attribute"); //更简单的重定向方法 //void sendRedirect(String location) response.sendRedirect("/day15/responseDemo2");//客户端发出 } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
请求转发forward与重定向redirect区别:转发由服务器发出,无需加项目虚拟目录
服务器输出字符到浏览器,通过字符输出流并设置其编码方式
response.setContentType("text/html;charset=utf-8");
sos.write("你好".getBytes("utf-8"));
通过画笔对象(BufferedImage.getGraphics();//画笔对象)和servlet实现输出验证码到浏览器(4个随机数+10条线)
前台可以修改请求连接加独一无二的时间戳new Date().getTime();
ServletContext代表整个web应用,与服务器通信,可以通过request对象或httpservletRequest对象获取this.getServletContext()
功能:获取文件的MIME类型-getMimeType(String file) ,实现数据共享,获取服务器真实路径context.getRealPath("WEB-INF/c.txt");
案例:点击超链接,实现图片下载
package cn.liujinhui.web.download; import cn.liujinhui.web.utils.DownLoadUtils; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; @WebServlet("/downloadServlet") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获取请求参数,文件名称 String filename = request.getParameter("filename"); System.out.println(filename); //2.使用字节输入流加载文件进内存 //2.1找到文件服务器路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/image/" + filename); System.out.println(realPath); //2.2用字节流关联 FileInputStream fis = new FileInputStream(realPath); //3.设置Response的响应头 //3.1设置响应头类型:content-type String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型 response.setHeader("content-type",mimeType); //3.2设置响应头打开方式content-disposition //解决中文文件名问题 //1.获取user-agent请求头 String agent=request.getHeader("user-agent"); //2.使用工具类方法编码文件名即可 filename = DownLoadUtils.getFileName(agent, filename); response.setHeader("content-disposition","attachment;filename="+filename); //4.将输入流的数据写出到输出流中 ServletOutputStream sos = response.getOutputStream(); byte[] buff=new byte[1024 * 8]; int len=0; while((len=fis.read(buff))!=-1){ sos.write(buff,0,len); } fis.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
前台
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>download</title> </head> <body> <a href="/day15/image/1.jpg">图片1</a> <a href="/day15/image/1.avi">视频</a> <hr> <a href="/day15/downloadServlet?filename=九尾.jpg">图片1</a> <a href="/day15/downloadServlet?filename=1.avi">视频</a> </body> </html>
Day16 Cookie&Session、JSP
会话:客户端与服务器进行资源访问交互,用于一次会话内的多次请求进行数据共享
客户端会话:Cookie,服务器端:Session
Cookie:添加response.addCookie(Cookie),获取request.getCookies()
默认关闭浏览器销毁cookie,可以设置生命周期进行持久化存储setMaxAge(int seconds)
设置cookie范围setPath(String path):设置cookie获取的范围
案例:记住上次访问时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sdf.format(date); System.out.println("编码前:"+str_date);//编码前的数据 //URL编码 str_date=URLEncoder.encode(str_date,"utf-8"); System.out.println("编码后:"+str_date);//编码后的数据 Cookie cookie = new Cookie("lastTime", str_date); cookie.setValue(str_date); //设置cookie的存活时间 cookie.setMaxAge(60 * 60 * 24 * 30);//一个月 response.addCookie(cookie); response.getWriter().write("<h1>您好,欢迎您首次访问</h1>");
Java Server Pages:服务器端页面
原理:转换为java文件并编译成字节码文件
<% 代码 %>:service的方法,<%! 代码 %>:成员变量,<=% 代码 %>:输出的变量,<%@ page import="java.net.URLEncoder" %>导包
jsp的内置对象:out-字符输出流对象
HttpSession保存数据:request.getSession();
tomcat通过session的序列化,在关闭服务器前将数据钝化到硬盘.ser,启动后tomcat自动读取ser文件反序列化/活化为内存中的session对象
默认失效时间30分钟,可以修改tomcat配置
案例:验证码存入session,servlet判断是否与输入一致
JavaEE Day17 JSP&MVC开发模式&EL&STL
JSP指令:导入资源文件 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
常见指令:page(import、contentType、errorPage、isErrorPage)、include、taglib
注释:html注释--<!-- -->,jsp注释--<%-- --%>(F12看不到)
内置对象:pageContext、request、session、response、application、page、out、configure、exception
MVC目的:实现MC代码分离,使一个程序有不同的表现形式,便于实现代码重用
EL,Expression Language 表达式语言,用于简化jsp页面中代码的编写,如${表达式}
jsp默认支持,可以在page中设置属性isELIgnored,或在表达式前加\,如\${3 > 4}
使用:
- 运算-判空${(not) empty str},/-div,%-mod,&&-and,||-or两种均可
- 获取值:${域名称.键名},如${request.zhangsan}
- 获取对象、list集合、map集合的值:${域名称.键名.属性名}
JSTL,Java Server Pages Tag Library---Apache提供的JSP标准标签库
需要导入标签库:taglib指令---<$@ taglib prefix = "c" uri=""%>
常用标签
- 有<c:if test=${not empty list}>无else
- <c:choose>,相当于switch,内部是<c:when test="">和<c:otherwise>
- <c:forEach>可以相当于传统for循环或forEach
案例:jstl+el将集合数据显示
<%@ page import="java.util.ArrayList" %> <%@ page import="java.util.List" %> <%@ page import="cn.itcast.domain.User" %> <%@ page import="java.util.Date" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>test</title> </head> <body> <% List list = new ArrayList(); list.add(new User("张三",23,new Date())); list.add(new User("李四",24,new Date())); list.add(new User("王五",25,new Date())); request.setAttribute("list",list); %> <table border="1" width="500" align="center"> <tr> <th>编号</th> <th>姓名</th> <th>年龄</th> <th>生日</th> </tr> <%--数据行--%> <c:forEach items="${list}" var="user" varStatus="s"> <c:if test="${s.count mod 2 == 0}"> <tr bgcolor="red"> <td>${s.count}</td> <td>${user.name}</td> <td>${user.age}</td> <td>${user.birStr}</td> </tr> </c:if> <c:if test="${s.count mod 2 != 0}"> <tr bgcolor="green"> <td>${s.count}</td> <td>${user.name}</td> <td>${user.age}</td> <td>${user.birStr}</td> </tr> </c:if> </c:forEach> </table> </body> </html>
五层架构:表示层、业务逻辑层(组合dao的方法完成复杂功能)、数据访问层(Mybatis)
案例:用户信息列表展示
使用面向接口的编程方式,类有缺陷只需要修改实现类,提高可扩展性和可维护性
JavaEE Day18 综合练习
Bootstrap中文网添加:内联表单按钮、分页组件、复选框
登录时点击验证码刷新,每次点击更新请求连接加时间戳
使用JDBCTemplate
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username, password);
点击按钮实现删除
<script> function deleteUser(id) { //用户安全提升 if (confirm("您确定要删除吗?")){ //访问路径 location.href = "${pageContext.request.contextPath}/delUserServlet?id="+id; } } </script> <c:forEach items="${users}" var="user" varStatus="s"> <tr> <td><input type="checkbox"></td> <td>${s.count}</td> <td>${user.name}</td> <td>${user.gender}</td> <td>${user.age}</td> <td>${user.address}</td> <td>${user.qq}</td> <td>${user.email}</td> <td><a class="btn btn-default btn-sm" href="update.html">修改</a> <a class="btn btn-default btn-sm" href="javascript:deleteUser(${user.id});">删除</a></td> </tr> </c:forEach>
重定向跳转,需要加虚拟目录,由浏览器发出response.sendRedirect(request.getContextPath()+"/userListServlet");
自定义PageBean实现分页查询,使用JSTL表达式判断页数显示按钮
使用StringBuilder为sql语句添加条件
JavaEE Day19 Filter&Listener
过滤器:实现Filter接口,重写doFilter(ServletRequest req, ServletResponse resp, FilterChain chain),执行代码、拦截(chain.doFilter(req, resp);)、执行放行后的代码
可以使用xml(<dispatcher></dispatcher>)或注解配置
配置拦截路径及拦截方式@WebFilter(value = "/user/*.jsp",dispatcherTypes = {DispatcherType.FORWARD,DispatcherType.REQUEST})enum枚举
过滤器链执行顺序:注解按字典序,xml按<filter-mapping>定义顺序
案例:登录验证,验证请求路径,登录了/请求路径中包括登录(想登录 )放行(执行chain.doFilter()即可),否则跳转到登录页面并提示未登录
package cn.itcast.web.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; /** * 完成登录验证的过滤器 */ @WebFilter("/*") public class LoginFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //0.强制转换,向下转型 HttpServletRequest request = (HttpServletRequest)req; //1.获取资源的请求路径URL和URI※ String uri = request.getRequestURI(); //2.判断是否包含登录相关的资源路径 //注意排除掉css、js、图片、验证码等资源 if (uri.contains("/login.jsp") || uri.contains("/loginServlet") || uri.contains("/css/")|| uri.contains("/js/") || uri.contains("/checkCodeServlet")|| uri.contains("/fonts/")){ //包含,证明用户就是想登录,放行 chain.doFilter(req, resp); }else { //不包含,验证用户是否登录 //3.从session中获取user Object user = request.getSession().getAttribute("user"); if(user != null){ chain.doFilter(req, resp); }else{ //没有登录,跳转登录页面 request.setAttribute("login_msg","您尚未登录,请登录"); request.getRequestDispatcher("/login.jsp").forward(request,resp); } } //chain.doFilter(req, resp); } public void init(FilterConfig config) throws ServletException { } }
案例:敏感词汇过滤,使用动态代理对象,代理对象 = Proxy.newProxyInstance();
package cn.itcast.web.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; /** * 敏感词汇过滤器 */ @WebFilter("/*") public class SensitiveWordsFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //req.setCharacterEncoding("gbk"); //1.创建代理对象,增强getParameter方法 ServletRequest proxy_req = (ServletRequest)Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //增强getParameter方法 //判断是否是该方法 if (method.getName().equals("getParameter")){ //增强返回值 //获取返回值 String value = (String)method.invoke(req,args); if (value != null){ for (String str : list) { if (value.contains(str)){ value = value.replaceAll(str,"***"); } } } return value; } //判断方法名是否是getParameterMap //判断方法名是否是getParameterValue //上述两个方法都能获取参数的值 return method.invoke(req,args); } }); //2.放行 chain.doFilter(proxy_req, resp); } private List<String> list = new ArrayList<String>(); public void init(FilterConfig config) throws ServletException { try{ //0.获取文件的真实路径,加载文件 ServletContext servletContext = config.getServletContext(); String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感词汇.txt"); //2.读取文件 BufferedReader br = new BufferedReader(new FileReader(realPath)); //3.将文件的每一行数据添加到list中 String line = null; while((line = br.readLine()) != null){ list.add(line); } br.close(); System.out.println(list); }catch (Exception e){ e.printStackTrace(); }
} }
Listener监听器,是web三大组件(Servlet,Filter,Listener)之一
注册监听:将事件、事件源、监听器ServletContextListener绑定在一起,当事件源上该发生某个事件后,执行监听器代码
需要给类名上加注解@WebListener
@Override public void contextInitialized(ServletContextEvent servletContextEvent) { //通常用于加载资源文件 //1.获取servletContextEvent对象 ServletContext servletContext = servletContextEvent.getServletContext(); //2.加载资源文件 String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");//配置文件中的路径 //3.获取真实路径 String realPath = servletContext.getRealPath(contextConfigLocation); //4.加载进内存 try{ FileInputStream fis = new FileInputStream(realPath); }catch (Exception r){ r.printStackTrace(); } System.out.println("ServletContext对象被创建了"); }
JavaEE Day20 JQuery基础
数组:$(js对象),入口函数$(function () {}),$(function () {alert("123");})
样式控制:$("#div1").css("background-color","red");
选择器:标签选择器、#id选择器、.类选择器、并集选择器
表单过滤选择器: :enabled、:disabled、 :checked、 :selected,如$("input[type='text']:disabled").val("aaa")
DOM操作:html()设置标签体所有内容,text()获取纯文本内容、val()获取元素value值
<script> $(function () { // 获取myinput 的value值 var value = $("#myinput").val(); alert(value); // 设置myinput 的value值 value = $("#myinput").val("李四"); // 获取mydiv的标签体内容 var html = $("#mydiv").html(); alert(html); // 设置mydiv的标签体内容 html = $("#mydiv").html("<p>aaa</p>"); // 获取mydiv文本内容 var text = $("#mydiv").text(); alert(text); //设置mydiv文本内容 text = $("#mydiv").text("bbbb"); }); </script>
属性操作:attr()自定义属性,prop()通用属性,removeXXX("")
class操作:addClass、removeClass、toggleClass(切换)
本文来自博客园,作者:哥们要飞,转载请注明原文链接:https://www.cnblogs.com/liujinhui/p/14886373.html