一.处理各种表单请求参数

1.日期类型的参数:注意要将日期进行格式化,然后转化为java中的date类型

2.单选按钮的参数:传过来的参数值可能会是中文,所以在java代码中要进行字符编码设置setCharacterEncoding();

3.多选按钮:注意返回的是字符串数组,所以要进行数组是否为空的判断,否则可能会出现空指针异常

4.下拉列表:在没有设置value的情况下,会将标签中的文字当做value进行处理

5.文本域:和普通文本框差不多

详情代码如下:

<%--
  Created by IntelliJ IDEA.
  User: Szy
  Date: 2018/10/16
  Time: 19:47
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/FormEleTest" method="post">
    <p><input type="date" name="birthday"></p>

    <hr>
    男<input type="radio" name="sex" value="男" checked>  <%--默认选中--%>
    女<input type="radio" name="sex" value="女">

    <hr>
    唱歌<input type="checkbox" name="hobby" value="唱歌">
    跳舞<input type="checkbox" name="hobby" value="跳舞">
    书法<input type="checkbox" name="hobby" value="书法">
    国画<input type="checkbox" name="hobby" value="国画">

    <hr>
    <%--如果不提供value属性,则会把标签之间的文本当做value考虑
        如果提供value,则优先使用value的值--%>
    <select name="city">
        <option value="北京">北京</option>
        <option value="上海">上海</option>
        <option value="陕西">陕西</option>
        <option value="深圳">深圳</option>
    </select>

    <hr>
    个人简介<textarea name="intro" cols="30" rows="10"></textarea>

    <p><input type="submit" value="提交"></p>
</form>
</body>
</html>
package level3;

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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;


//关于日期表单格式的测试
@WebServlet(urlPatterns = "/FormEleTest")
public class FormEleTest extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");   //设置字符编码,防止出现中文乱码
        //处理日期类型
        String birthday = req.getParameter("birthday");   //得到jsp中的birthday
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  //格式化日期为固定形式
        try {
            Date date = sdf.parse(birthday);  //转化为date类型
            System.out.println(date);   //打印到控制台
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //处理单选按钮
        String sex = req.getParameter("sex");
        System.out.println(sex);

        //处理多选按钮
        // 注意:因为是多选按钮,所以会有多个值,要用getParameterValues(),返回的是一个字符串数组类型
        String[] hobbies = req.getParameterValues("hobby");
        //System.out.println(Arrays.toString(hobbies));
        //但是如果对复选框一个按钮也没有选择,就会打印出错,出现空指针异常
        // 因此在这之前要对hobbies数组进行是否为空的判断
        if(hobbies != null) {
            System.out.println(Arrays.toString(hobbies));
        }

        //处理下拉列表
        String city = req.getParameter("city");
        System.out.println(city);

        //处理文本域   ps:处理文本域其实和处理普通文本框差不多
        String intro = req.getParameter("intro");
        System.out.println(intro);

    }
}

执行结果:

java学习day34---servlet(下)          java学习day34---servlet(下)

二.jstl的标签

1.c:choose 类似于 if elseif else

语法:
 

<c:choose>
  <c:when test="条件1">内容1</c:when>
  <c:when test="条件2">内容2</c:when>
  ...
  <c:when test="条件n">内容n</c:when>
  <c:otherwise>以上条件都不成立时</c:otherwise>
</c:choose>

2.c:out 用来输出特殊内容
它可以对${}输出的内容进行控制,可以控制是否忽略html代码

<c:out escapeXML="false" value="${作用域变量}"> 不忽略html
<c:out escapeXML="true" value="${作用域变量}"> 忽略html,(当做普通文本)

3.格式化日期或数字

<fmt:formatDate value="日期对象" pattern="日期格式"/>

<fmt:formatNumber value="数字对象" pattern="数字格式"/>


数字格式 `#` 和 `0` 其中0可以用来前置补零或后置补零,能够自动进行四舍五入

测试代码:

<%--
  Created by IntelliJ IDEA.
  User: Szy
  Date: 2018/10/22
  Time: 16:53
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--choose标签  相当于if-if-else语句  里面的并且可以有"and"和"&&"两种表达方式--%>
<c:choose>
    <c:when test="${salary < 3000}">低收入</c:when>
    <c:when test="${salary > 3000 and salary < 8000}">中等收入</c:when>
    <c:when test="${salary >= 8000 && salary < 15000}">较高收入</c:when>
    <c:otherwise>高收入</c:otherwise>
</c:choose>

<hr>
<%--escapeXML是是否忽略掉HTML语法  false是不忽略--%>
<c:out value="${text}"></c:out>
<hr>
<c:out value="${text}" escapeXml="false"></c:out>

<hr> <%--把日期格式化为预期的样子--%>
<fmt:formatDate value="${birthday}" pattern="yyyy-MM-dd"></fmt:formatDate>

<hr> <%--格式化数字,如保留几位小数,是否用0填充  ps:可以自动四舍五入--%>
<fmt:formatNumber value="${num}" pattern="####.##"></fmt:formatNumber><hr>
<fmt:formatNumber value="${num}" pattern="0000.##"></fmt:formatNumber>
</body>
</html>
package level3;

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.util.Date;

@WebServlet(urlPatterns = "/JstlTabTest")
public class JstlTabTest extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //choose测试
        /**
         * 判断salary,salary<3000 ---> 低工资
         *            salary>3000 && salary < 8000 ---> 中等工资
         *            salary>=8000 ---> 高工资
         */
        req.setAttribute("salary", 4500);

        //out测试
        req.setAttribute("text", "<span style='color:red; font-size:5em;'>文字</span>");

        //fmt测试
        req.setAttribute("birthday", new Date());
        req.setAttribute("num", 123.456);

        //跳转页面
        req.getRequestDispatcher("jstlTab.jsp").forward(req, resp);
    }
}

测试结果:

java学习day34---servlet(下)

三.jsp指令

<%@ page contentType="页面的内容类型和编码" 
	import="要导入的java类"
        isELIgnored="是否忽略EL表达式的处理" 
	errorPage="出现错误时,要跳转的页面"
	isErrorPage="用在错误页面上,取值为true表示是错误页面,这时候才能在页面中使用exception变量"
%>

可以用exception说明具体异常,但只能配合jsp表达式和jsp脚本使用
<%@ taglib prefix="前缀" uri="标签的唯一标识" %>      作用是导入标签库
<%@ include file="另一个jsp页面" %>       作用是重用页面上的一些标签和代码

四.jsp原理(jsp本质上式servelt) 执行jsp代码底层会将其翻译成servlet代码

看如下示例代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%!
        int i = 100;   //定义在声明部分的变量,是实例变量,其优先级低于局部变量
        public int sum(int a, int b) {
            return a + b;
        }
    %>

    <% int i = 10; //在脚本部分的变量是一个局部变量 %>

    <%--输出--%>
    <%= i %>   <%--测试1:检测输出哪一个i变量--%>
    <%= i++ %>  <%--测试2:不断刷新页面后,i的值是否今次那个自增--%>
    <%= i++%>  <%--测试3:在注释掉第21行代码之后,不断刷新页面i变量是否会进行自增--%>

</body>
</html>

在<!%...%>的java代码里定义一个变量i,在<%...%>的HTML代码中定义一个变量i,然后按要求进行测试,得到测试结果

测试1:输出i的变量值为10

测试2:i不能进行自增

测试3:i从100开始,没刷新以此页面,i自增1

代码原理分析:

jsp 要工作,也必须编译为java类,如下代码

首先因为就近先打印局部变量(脚本中的值)i=10,刷新页面,方法重新调用,每次都会重置为初始值

注释掉之后,就用的是成员变量i=100,就算不断刷新页面,但底层用的是同一个jsp对象,所以值会进行自增

public class 类名 extends HttpJspBase{ // HttpJspBase 又是继承了HttpServlet
    
    public int i = 100;
    
    public int sum(int a, int b) {
        return a+b;
    }
    
    public void _jspService(HttpServletRequest request,
        HttpServletResponse response) {
        int i = 10;
        
        out.println(i++);
    }
}

因此,jsp的底层执行:

1) 当首次访问此jsp时,tomcat会把jsp转译为*.java的类(间接继承自HttpServlet)
2) 再把*.java类编译为*.class字节码
3) 把加载到虚拟机执行,生命周期类似于servlet的生命周期

五.大隐式对象(无需声明即可使用)

request     代表请求对象(可以获取请求参数,将变量存入request作用域)
response    代表响应对象(返回响应)
out         代表响应的字符输出流
pageContext  页面上下文对象,可以间接获得request等对象,并可以将变量存入page作用域

config        jsp的配置信息
page          当前jsp对象(this)
exception     代表的是异常信息(当页面isErrorPage="true"时有效)

session       变量作用范围是一次会话内有效
application   变量作用范围是整个应用程序有效

page作用域:        变量作用范围仅限于当前页面
request作用域:     变量的作用范围在一次请求内有效

六.cookie

1.cookie的创建

package level3.cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(urlPatterns = "/CreateCookieTest")
public class CreateCookieTest extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建一个cookie对象
        Cookie c = new Cookie("name", "zhangsan");
        //通过响应反馈给浏览器
        resp.addCookie(c);
        //成功后进行提示
        resp.getWriter().println("<html><body>cookie created...</body></html>");
    }
}

执行结果:

java学习day34---servlet(下)

结果可以在谷歌浏览器中查看,发现存在zhangsan这个cookie

java学习day34---servlet(下)

但是这是属于会话层的,一旦浏览器关闭,那么存储到信息会删除,如果想要让cookie存在的时间更长一些,可以使用c.setMaxAge("时间")来指定存储时间,存储的名字如果是中文,为防止乱码,需要将中文用URLEncoding.encode("中文","utf-8)进行解码

2.获取所有的cookie

package level3.cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(urlPatterns = "/GetCookieTest")
public class GetCookieTest extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            System.out.println(cookie.getName() + "---" + cookie.getValue());
        }
    }
}

执行结果

java学习day34---servlet(下)

七.Session

session 必须针对同一个浏览器,才能实现在请求存储信息,在之后的请求获取信息的效果

每个用户访问服务器时,服务器会为他们创建一个独立的session

1) 首次创建session时,tomcat会产生一个名为`JSESSIONID=session的唯一标识` 的特殊cookie
   这个`JSESSIONID=1`就会随着响应返回给浏览器   
2) 浏览器会记录这个cookie。之后的所有请求会把此cookie发送给服务器。
   服务器根据cookie的值找到对应的session
3) jsessionid 这个cookie属于会话cookie,浏览器关闭就会消失

HttpSession session = request.getSession();  
首次调用getSession方法就是创建session对象
后续再调用getSession方法是获取第一次创建好的session对象

存入内容
session.setAttribute("变量名", 任意信息);
获取内容
Obejct 信息 = session.getAttribute("变量名");
删除内容
Obejct 信息 = session.removeAttribute("变量名");
让session失效(会清空session中所有内容)
session.invalidate();

1.创建session对象

package level3.session;

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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.HttpCookie;

@WebServlet(urlPatterns = "/CreateSessionTest")
public class CreateSessionTest extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建或获取session对象
        HttpSession session = req.getSession();
        //存入信息
        session.setAttribute("name", "李四");
        resp.getWriter().println("<html><body>session created...</body></html>");
    }
}

运行结果:

java学习day34---servlet(下)

2.获取session对象中已经存储的信息

package level3.session;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet(urlPatterns = "/GetSessionTest")
public class GetSessionTest extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取CreateSessionTest中创建的session对象信息
        HttpSession session = req.getSession();
        Object name = session.getAttribute("name");
        System.out.println(name);
    }
}

运行结果:

java学习day34---servlet(下)                java学习day34---servlet(下)

对比session和cookie
1) session是将信息存储于服务器端,cookie是将信息存储于浏览器端
2) session与cookie相比,更为安全
3) session的生命周期相对较短, 
    两次请求间隔超过30分钟,服务器会销毁session
    调用session.invalidate方法时,会立刻销毁
   cookie 
    会话cookie是浏览器关闭就销毁
    setMaxAge的cookie会根据设置的寿命存活一段时间
4) 存储的信息量上
    cookie 每个最大大小是4k左右
    session 理论上没有限制,但session要占用服务器内存,所以不太适合存储太多的内容
    信息要永久存储,还是需要使用数据库
5) cookie里数据都得是字符串,而session里可以存储任意类型

八.Session的应用---用户登录

如果未登录,跳转到登录页面,如果登陆成功了,则可以对商品进行管理

登录的实现代码

package level3.session;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet(urlPatterns = "/LoginTest")
public class LoginTest extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置字符编码
        req.setCharacterEncoding("utf-8");
        //获取jsp提交的信息
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        //对提交的用户信息进行判断,如果判断成功,存储登录标记,并跳转到欢迎界面
        if("zhangsan".equals(username) && "123".equals(password)) {
            HttpSession session = req.getSession();
            session.setAttribute("islogin", true);
            session.setAttribute("username", username);
            req.getRequestDispatcher("welcome.jsp").forward(req, resp);
        } else {
            //否则跳转到登录页面重新登录
            req.getRequestDispatcher("login.jsp").forward(req, resp);
        }
    }
}

登录的界面代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/LoginTest" method="post">
    <input type="text" name="username">
    <input type="text" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

添加商品代码

package level3.session;

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 javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet(urlPatterns = "/ProductAdd")
public class ProductAdd extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session中的登录标记
        HttpSession session = req.getSession();
        //如果登录标记为空,则跳转到登录页面,否则打印添加商品信息
        if(session.getAttribute("islogin") == null) {
            req.getRequestDispatcher("login.jsp").forward(req, resp);
            return;
        }
        System.out.println("添加商品成功!");
    }
}

九、请求重定向

请求转发:
 request.getRequestDispatcher("目录路径").forward(request,response);
请求重定向:
 response.sendRedirect("目录路径");
区别:
    1) 请求转发时,地址栏不会改变(是第一个servlet的地址)
       重定向,地址栏会发生变化(是最后一个servlet的地址)
    2) 请求转发时一次请求,跳转发生在服务器内部
       重定向是两次请求,第一次请求会返回302的状态码和目标地址,
          浏览器根据目标地址发送第二次请求,才完成整个流程
    3) 重定向是两次请求,所以不能利用request作用域存值取值
       但可以使用session作用域来存值取值       
       请求转发因为是同一次请求,所以可以使用request作用域存值取值
    4) 请求转发的目标只能是本项目的servlet或jsp
       重定向跳转的目标可以是任意的

请求转发和请求重定向的执行过程图解

java学习day34---servlet(下)java学习day34---servlet(下)

相关文章:

  • 2021-10-19
  • 2021-08-13
  • 2021-08-03
  • 2022-02-16
  • 2021-03-29
  • 2021-09-01
  • 2021-10-20
猜你喜欢
  • 2021-10-16
  • 2021-05-03
  • 2021-12-12
  • 2021-05-04
  • 2021-11-13
  • 2022-01-21
  • 2021-11-07
相关资源
相似解决方案