【课程复习】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>&nbsp;
                    <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(切换)

 

posted @ 2021-06-15 17:27  哥们要飞  阅读(54)  评论(0编辑  收藏  举报