JavaWeb(二)

Request对象

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
   		resp.setHeader("content-type","text/html;charset=UTF-8");
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    //获取参数
        String name = req.getParameter("name");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println("=======================================");

        System.out.println(name);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("=======================================");
        resp.setCharacterEncoding("utf-8");
    //请求转发
    	

    }
<div style="text-align: center">
    <%--以post形式提交表单--%>
    <form action="${pageContext.request.contextPath}/hello" method="post">
        用户名:<input type="text" name="name"><br>
        密码:<input type="password" name="password"><br>
        爱好:
        <input type="checkbox" name="hobby" value="girl">女孩
        <input type="checkbox" name="hobby" value="code">代码
        <input type="checkbox" name="hobby" value="sing">唱歌
        <input type="checkbox" name="hobby" value="movie">电影

        <br>
        <input type="submit">
    </form>

</div>
  • 获取前端传递的参数
  • 请求转发

Cookie Session

会话

用户打开一个浏览器,点击了好很多超链接,访问了多个web资源,关闭浏览器,这个过程可以称之为会话

有状态会话

保存会话的两种技术

cookie

  • 客户端技术(响应,请求)

session

  • 服务器技术,可以保存用户的会话信息,可以把信息或数据放在session中
  • 从请求中拿到cookie信息
  • 服务器响应给客户端Cookie
 //cookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();
cookie.getName()//获得key
cookie.getValue()//获得value
new Cookie("lastLoginTime", ""+System.currentTimeMillis());//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie有效期
resp.addCookie(cookie);//响应给客户端一个cookie
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setHeader("content-type","text/html;charset=UTF-8");

        PrintWriter out = resp.getWriter();
        //cookie,服务器端从客户端获取
        Cookie[] cookies = req.getCookies();

        if(cookies!=null){
            out.write("您上一次访问的时间是");
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if(cookie.getName().equals("lastLoginTime")){
                    long l = Long.parseLong(cookie.getValue());
                    Date date = new Date(l);
                    out.write(date.toLocaleString());
                }
            }
        }else{
            out.write("这是您第一次访问本站");
        }
        //服务器给客户端响应一个cookie
        Cookie cookie = new Cookie("lastLoginTime", ""+System.currentTimeMillis());
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);

cookie一般会保存在本地的用户目录下appdata

一个网站cookie是否存在上限

  • 一个cookie只能保存一个信息
  • 一个web站点可以给浏览器发送多个cookie,最多存放20个
  • Cookie大小由限制4kb
  • 300个浏览器上限

删除cookie

  • 不设置有效期,关闭浏览器,自动失效
  • 设置有效期时间为0
//乱码问题
URLEncoder.encode("","utf-8")
URLDecoder.decode("","utf-8")

Session

  • 服务器会给每一个用户(浏览器)创建一个Session对象

  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在

  • 用户登录之后,整个网站都可以访问-》保存用户的信息

 //解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        //得到session
        HttpSession session = req.getSession();
        //给session存key-value
        session.setAttribute("name","ming");
        //获取session  ID
        String sessionId = session.getId();
        //判断Session是不是新的
        if(session.isNew()){
            resp.getWriter().write("session创建成功,ID"+sessionId);
        }else{
            resp.getWriter().write("session已经在服务器中存在,ID"+sessionId);
        }

注销session

//手动注销
HttpSession session = req.getSession();
session.removeAttribute("name");
session.invalidate();

xml设置

<session-config>
<!--设置session过期时间,单位为分钟-->
        <session-timeout>1</session-timeout>
    </session-config>

Sesision和Cookie的区别

  • cookie是把用户的数据写给用户的浏览器,浏览器保存(可保存多个)

  • session是把用户的数据写到用户独占的Session中,服务器保存(保存重要的信息,减少服务器资源的浪费)

  • Session对象由服务创建

session使用场景:

  • 保存登录用户的信息

  • 购物车信息

  • 在整个网站中经常用到的数据

JSP

JSP

Java Server Pages:java服务器端页面,也和servlet一样,用于动态web技术

最大的特点

  • 写jsp就像在写html
  • 区别
    • HTML只给用户提供静态的数据
    • jsp页面中可以嵌入java代码,为用户提供动态数据

JSP原理

jsp怎么执行的

  • 代码层面没有任何问题
  • 服务器内部工作
    • tomcat中有一个work目录
    • IDEA中使用Tomcat会在IDEA中生成一个work目录

C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2020.2\tomcat\Unnamed_WebDemo\work\Catalina\localhost\WEB01_war\org\apache\jsp

页面转变成了java程序

浏览器想服务器发送请求,不管访问什么资源,其实都是在访问Servlet

JSP最终也会被转换成为一个Java类,本质上就是一个servlet

在JSP页面中:

只要是java代码,就会原封不动的输出

如果是HTML代码,就会被替换为

out.write("<>")

这样的格式输出到前端

简化页面的编写

JSP基础语法

任何语言都有自己的语法,JAVA中有,JSP作为java技术的一种应用,拥有一些自己扩充的语法,JAVA语法都支持

<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%=变量或者表达式%>
--%>
<%=new java.util.Date()%>

jsp脚本片段

<%
    int sum=0;
    for (int i=1;i<=100;i++){
        sum+=i;
    }
    out.print("<h1>sum"+sum+"</h1>");

%>

jsp声明<%! %>

<%! 
    static{
    System.out.prinln("Loading");
}
private int globalVar = 0;
public void fun(){
    System.out.prinln("Loading");
}
    %>

jsp声明:会被编译到jsp生成的类中,其他的,就会被生成到_jspService方法中

在jsp中嵌入java代码即可

jsp指令

<%@ page errorPage="xxx.jsp" %>//定制错误页面
<%@ page import="java.util.*" %>//导入包
<%@ include file="xxx.jsp">//包含其他页面,是合成页面

//xml配置错误页面
<error-page>
        <error-code>404</error-code>
        <location>xxx.jsp</location>
    </error-page>

jsp标签

<jsp:include page="/xxx.jsp"/>  拼接页面。  

JSP内置对象和作用域

内置对象

	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(ServletContext)
  • config (ServletConfig)
  • out
  • paget
  • exception
<%--内置对象--%>
<%
    pageContext.setAttribute("name1",1);//保存的数据只在一个页面中有效
    request.setAttribute("name2",2);//保存的数据只在一次请求中有效,请求转发会携带这个数据
    session.setAttribute("name3",3);//保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
    application.setAttribute("name4",4);//保存的数据只在服务器中有效,从打开服务器到关闭服务器
%>
<%--脚本片段中的代码,会被原封不动的生成到.JSP.java--%>
<%
    /*取值*/
   String name1 = (String) pageContext.findAttribute("name1");
   String name2 = (String) pageContext.findAttribute("name2");
   String name3 = (String) pageContext.findAttribute("name3");
   String name4 = (String) pageContext.findAttribute("name4");


%>
<%--使用EL表达式输出--%>
<h1>取出的值为:</h1>
<h1>${name1}</h1>
<h1>${name2}</h1>
<h1>${name3}</h1>
<h1>${name4}</h1>

request:客户端向服务器发送请求,产生的数据,用户看完就没用了

session:客户端向服务器发送请求,产生的数据,用户看完一会还有用

application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用

JSP标签 JSTL标签 EL表达式

EL表达式:${}

 <!-- JSTL表达式依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!-- 标签库 -->
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>
  • 获取数据

  • 执行运算

  • 获取web开发的常用对象

  • 调用java方法

    jsp标签

//请求转发
<jsp:forward page="1.jsp">
    <jsp:param name="name" value="ming"/>
    <jsp:param name="age" value="20"/>
</jsp:forward>




.jsp 获取值
名字:<%=request.getParameter("name")%>
年龄:<%=request.getParameter("age")%>

JSTL表达式

JSTL标签库的使用即使为了弥补HTML标签的不足,自定义许多标签可以使用

核心标签:

格式化标签

SQL标签

XML标签

JSTL标签库使用步骤:

  • 引入对应的taglib

  • //引入JSTL核心标签库,我们才能使用JSTL标签
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
  • 使用其中的方法

<form action="">
    <%--
    EL表达式获取表单中的数据
    ${param.参数名}}
    --%>
    <input type="text" name="username" value="${param.username}">
</form>
<c:if test="${param.username=='admin'}" var="isAdmin">
    <c:out value="Welcome"/>
</c:if>
<c:out value="${isAdmin}"/>
<c:forEach var="i" items="${xx}" begin="1" end="5" step="1">
    <c:out value="${i}"/>
</c:forEach>

JavaBean

实体类:

JavaBean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法

一般用来与数据库的字段做映射 ORM

ORM:对象关系映射

  • 表->类
  • 字段->属性
  • 行记录->对象

MVC三层架构

Model View Control 模型 视图 控制器

控制器:Servlet

  • 接收用户请求
  • 交给业务层去做
  • 视图跳转

视图:JSP

  • 展示数据模型
  • 提供用户操作

Servlet和JSP都可以写java代码:

为了易于维护和使用,Servlet专注于处理请求,JSP专注于显示数据

Model:

  • 业务处理:业务逻辑(service)
  • 数据持久层:CRUD(Dao)

过滤器Filter

用来过滤网站的数据

  • 处理中文乱码
  • 登录验证

Filter开发步骤

  • 导包
  • 编写过滤器
    • 导包不要错
    • 实现接口
    • 配置filter
import javax.servlet.*;
import java.io.IOException;

public class ChractorFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        
    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    }
}

web.xml注册过滤器

 <filter>
        <filter-name>filterCode</filter-name>
        <filter-class>com.company.ChractorFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filterCode</filter-name>
        <url-pattern>/hello</url-pattern>
    </filter-mapping>
import javax.servlet.*;
import java.io.IOException;

public class ChractorFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    //web服务器启动就开始初始化了
    }

    @Override
    public void destroy() {

    }

    @Override
    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("执行后");

        //chain
        /*
        过滤中的所有代码,在过滤特定请求的时候都会执行
        必须要让过滤器继续同行
        * */
    }
}

监听器

实现一个监听器的接口

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class OnlineListen implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext servletContext = se.getSession().getServletContext();
        Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");
        if(onlineCount==null){
            onlineCount = new Integer(1);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count+1);
        }
        servletContext.setAttribute("OnlineCount",onlineCount);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext servletContext = se.getSession().getServletContext();
        Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount");
        if(onlineCount==null){
            onlineCount = new Integer(0);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count-1);
        }
        servletContext.setAttribute("OnlineCount",onlineCount);
    }
}

注册监听器

<listener>
    <listener-class>com.company.OnlineListen</listener-class>
</listener>

看情况是否使用

过滤器 监听器常见应用

监听器在GUI中的应用

import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame("中秋节快乐");//新建一个窗体
        Panel panel = new Panel(null);//面板
        frame.setLayout(null);//设置窗体布局
        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(0,0,255));//设置背景颜色

        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(0,255,0));//设置背景颜色

        frame.add(panel);
        frame.setVisible(true);

        //监听事件,关闭事件
        frame.addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {
                System.out.println("打开");
            }

            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("关闭ing");
                System.exit(0);

            }

            @Override
            public void windowClosed(WindowEvent e) {
                System.out.println("关闭");

            }

            @Override
            public void windowIconified(WindowEvent e) {

            }

            @Override
            public void windowDeiconified(WindowEvent e) {

            }

            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("激活");

            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                System.out.println("未激活");

            }
        });
    }
}

Filter实现权限拦截

用户登录之后才能进入主页,用户注销后就不能进入主页了

JDBC

java连接数据库

需要jar包的支持:

  • java.sql
  • javax.sql
  • mysql.connector-java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class TestJdbc {
    public static void main(String[] args) throws Exception {
        //配置信息
        String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC";
        String username = "root";
        String password = "123456";

        //加载驱动
       // Class.forName("com.mysql.jdbc.Driver");

        //连接数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //向数据库发送SQL的对象Statement:CRUD
        Statement statement = connection.createStatement();
        String sql = "select * from attribution_statistics";
        ResultSet resultSet = statement.executeQuery(sql);
        while(resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("id="+resultSet.getObject("country"));
            System.out.println("id="+resultSet.getObject("province"));
            System.out.println("id="+resultSet.getObject("city"));
            System.out.println("id="+resultSet.getObject("amount"));
        }
        //关闭连接资源,先开后关
        resultSet.close();
        statement.close();
        connection.close();
    }
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class TestJdbc {
    public static void main(String[] args) throws Exception {
        //配置信息
        String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC";
        String username = "root";
        String password = "123456";

        //加载驱动
       // Class.forName("com.mysql.jdbc.Driver");

        //连接数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //编写sql
        String sql = "insert into users(id,name,password) values(?,?,?)";
        //预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        
        preparedStatement.setInt(1,1);//给第一个占位符赋值为1
        preparedStatement.setString(2,"22");//给第二个占位符赋值为1
        preparedStatement.setString(3,"333");//给第三个占位符赋值为1
        //执行sql
        int i = preparedStatement.executeUpdate();
        if(i>0){
            System.out.println("success");
        }


        //关闭连接,释放资源
        preparedStatement.close();
        connection.close();
        
    }
}

JDBC事务

Junit单元测试

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>

简单使用

@Test只有在方法上有效,只要加了这个注解的方法,就可以直接运行

import org.junit.Test;

public class TestJdbc {


    @Test
    public void test(){
        System.out.println("Hello");

    }
}

失败的时候控制台报红,try catch提取异常

import org.junit.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class TestJdbc {


    @Test
    public void test() {
        //配置信息
        String url = "jdbc:mysql://localhost:3306/blogdb?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC";
        String username = "root";
        String password = "123456";
        Connection connection=null;
        try {
            //加载驱动
            // Class.forName("com.mysql.jdbc.Driver");

            //连接数据库
             connection = DriverManager.getConnection(url, username, password);

            //通知数据库开启事务
            connection.setAutoCommit(false);
            //编写sql
            String sql = "update account set money = money-100 where nam ='A'";
            //预编译
            connection.prepareStatement(sql).executeUpdate();

            int i = 1 / 0;
            String sql2 = "update account set money = money-100 where nam ='A'";
            connection.prepareStatement(sql2).executeUpdate();
            connection.commit();
        }catch(Exception e){
            try {
                connection.rollback();//事务回滚
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }finally {
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

posted @ 2020-10-05 19:41  yourText  阅读(198)  评论(0编辑  收藏  举报