个人java学习路线-EL表达式和JSTL,文件的上传和下载

EL表达式介绍

EL:Expression Language 表达式语言
作用:代替jsp页面中表达式脚本在jsp页面中进行数据的输出(比jsp表达式脚本简洁)

EL和JSP对比

EL和JSP对比

    <%
        request.setAttribute("key","值");
    %>
    表达式脚本输出key的值:<%=request.getAttribute("key")%><br>
    EL表达式输出key的值:${key}<br>
    <%--表达式脚本输出不存在的key时输出null,EL输出空白--%>
    表达式脚本输出key的值不存在:<%=request.getAttribute("key1")%><br>
    EL表达式输出key的值不存在:${key1}<br>

EL表达式搜索域数据的顺序

EL表达式搜索域数据的顺序
    pageContext,request,session,application
    四个域中有相同的key时,按作用域从小到大顺序搜索
<%
    pageContext.setAttribute("key","pageContext");
    request.setAttribute("key","request");
    session.setAttribute("key","session");
    application.setAttribute("key","application");
%>
${key}<%--输出pageContext--%>

EL表达式输出Bean的普通属性,数组属性(List集合,map集合属性)

EL表达式输出Bean的普通属性,数组属性(List集合,map集合属性)
    ${person.age},不是直接输出person对象的age,而是找对应的get方法
<%
    Person person=new Person();
    person.setName("穷奇");
    person.setAge(6452);
    person.setPhones(new String[]{"18866663333","15577778888","16699998888"});

    List<String> cities=new ArrayList<>();
    cities.add("海内北经");
    cities.add("西山经");
    cities.add("西方");
    person.setCities(cities);

    Map<String,Object> map=new HashMap<>();
    map.put("key1","少昊氏之子");
    map.put("key2","毁信恶忠");
    map.put("key3","崇饰恶言");
    person.setMap(map);

    pageContext.setAttribute("person",person);

%>

输出Person:${person}<br>

输出Person的name属性:${person.name}<br>

输出Person的phones数组属性:${person.phones[0]}<br><%--加下标,挨个输出--%>

输出Person的cities集合属性:${person.cities}<br><%--输出全部--%>
输出Person的cities集合中单个属性:${person.cities[0]}<br><%--单个加中括号下标--%>

输出Person的map集合属性:${person.map}<br><%--输出全部--%>
输出Person的map集合中某个key的值:${person.map.key1}<br><%--map后面加点key值--%>

输出Person的age属性:${person.age}<br>

ps:EL表达式这里person.age,不是直接输出,而是找对应的get方法(Boolean的是is方法),所以类中如果没有get方法,就无法输出。

EL表达式—运算

关系运算

== eq
!= ne
< it
> gt
<= le
>= ge
${12==12}或${12 eq 12}<br>
${12!=12}或${12 ne 12}<br>
${12<12}或${12 lt 12}<br>
${12>12}或${12 gt 12}<br>
${12<=12}或${12 le 12}<br>
${12>=12}或${12 ge 12}<br>

逻辑运算

&& 	and
||		 or
! 		 not
${12==1 && 12 >11}或${12==1 and 12 >11}<br>
${12==1 || 12 >11}或${12==1 or 12 >11}<br>
${! true}或${not true}<br>

算术运算

和java一样
其中:
18 / 12     可以写成    18 div 12
18 % 12     可以写成    18 mod 12

empty运算

empty运算可以判断一个数据是否为空,如果为空,则输出true,不为空输出false.

以下几种情况为空:
1>.值为null
2>.值为空字符串
3>.值时Object类型数组,长度为零的时候
4>.list集合,元素个数为零
5>.map集合,元素个数为零
<%
    request.setAttribute("emptyNull",null);
    request.setAttribute("emptyString","");
    request.setAttribute("emptyArr",new Object[]{});
    request.setAttribute("emptyList",new ArrayList<>());
    request.setAttribute("emptyMap",new HashMap<String,Object>());
%>
1>.值为null<br>
${empty emptyNull}<br>
2>.值为空字符串<br>
${empty emptyString}<br>
3>.值时Object类型数组,长度为零的时候<br>
${empty emptyArr}<br>
4>.list集合,元素个数为零<br>
${empty emptyList}<br>
5>.map集合,元素个数为零<br>
${empty emptyMap}<br>

三元运算

和java一样
条件?语句1:语句2;

"."运算,和[]中括号运算符

点运算,可以输出Bean对象中某个属性的值
[]中括号运算,可以输出有序集合中某个元素的值

   并且[]中括号运算,还可以输出map集合中key里含有特殊字符的key的值
        例如:
            map.put("a.a.a",aaaValue");
            request.setAttribute("map",map);

            用点运算显然无法访问:${map.a.a.a}
            []中括号运算可以访问:${map['a.a.a']}

EL表达式的11个隐含对象

EL表达式的11个隐含对象

        变量                   类型                       作用
    pageContext          pageContextImpl         它可以获取jsp中的九大内置对象

    pageScope            Map<String,Object>      它可以获取pageContext域中的数据
    requestScope         Map<String,Object>      它可以获取request域中的数据
    sessionScope         Map<String,Object>      它可以获取session域中的数据
    applicationScope     Map<String,Object>      它可以获取ServletContext域中的数据

    param                Map<String,String>      它可以获取请求参数的值
    paramValues          Map<String,String[]>    它也可以获取请求参数的值,获取多个值的情况

    header                Map<String,String>      它可以获取请求头的信息
    headerValues          Map<String,String[]>    它也可以获取请求头的信息,获取多个值的情况

    cookie                Map<String,Cookie>      它可以获取当前请求的Cookie信息

    initParam             Map<String,String>      它可以获取在web.xml中配置的<context-param>上下文参数

EL获取四个特定域中的属性

     pageScope               =====       pageContext域
     requestScope            =====       request域
     sessionScope            =====       session域
     applicationScope        =====       ServletContext域
 <%
     pageContext.setAttribute("key1","pageContext1");
     pageContext.setAttribute("key2","pageContext2");
     request.setAttribute("key2","request");
     session.setAttribute("key2","session");
     application.setAttribute("key2","application");
 %>

 ${key2}<br>
 ${requestScope.key2}<br>

页面输出:
pageContext2
request

pageContext对象的使用

   常用的:
       1>.协议
       2>.服务器ip
       3>.服务器端口
       4>.获取工程路径
       5>.获取请求方法
       6>.获取客户端ip地址
       7>.获取会话的id编号

其它方法

输出请求参数username的值:${param.username}<br>
输出请求参数password的值:${param.password}<br>
<hr>
输出请求参数username的第一个值: ${paramValues.username[0]}<br>
<hr>
输出请求头【User-Agent】的值:${header['User-Agent']}<br>
输出请求头【Connection】的值:${header.Connection}<br>
<hr>
输出请求头【User-Agent】数组的第一个值:${headerValues['User-Agent'][0]}<br>
<hr>
获取Cookie的名称:    ${cookie.JSESSIONID.name}<br>
获取Cookie的值: ${cookie.JSESSIONID.value}<br>
<hr>
输出web.xml中&lt;context-param&gt;的名字:${initParam.username}<br>
输出web.xml中&lt;context-param&gt;的值:${initParam.url}<br>

JSTL标签库core核心库使用

JSTL 标签库 全称是指 JSP Standard Tag Library JSP 标准标签库。是一个不断完善的开放源代码的 JSP 标签库。
EL 表达式主要是为了替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个 jsp 页面变得更佳简洁。

JSTL标签库使用

- 导入JSTL的jar包
- 引入jar包:(一般输入<c,idea就会自动引入了)
     <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

core核心库使用

1.<c:set/>
作用:往域中保存数据

<%--
1.<c:set/>
    作用:往域中保存数据
        域对象.setAttribute(key,value);
        scope属性设置保存到哪个域
            page表示PageContext(默认值)
            request表示Request域
            session表示Session域
            application表示ServletContextvar属性设置key
        value属性设置值
--%>
    保存之前:${requestScope.abc}<br>
    <c:set scope="request" var="abc" value="abcValue"/>
    保存之后:${requestScope.abc}<br>
    <hr>

网页输出:
  保存之前:
  保存之后:abcValue

2.<c:if/>
作用:做if判断

<%--
2.<c:if/>
    作用:if判断
    test属性表示判断的条件(使用EL表达式输出)
--%>
    <c:if test="${12==12}">
        <h1>12等于12</h1><br>
    </c:if>
    <hr>

输出:12等于12

3.<c:choose><c:when><c:otherwise>标签
作用:多路判断,类似switch…case…default

<%--
<c:choose><c:when><c:otherwise>标签
    作用:多路判断,类似switch..case...default
        注意:
            1.标签里不能用html注释,要使用jsp注释
            2.when标签的父标签一定要是choose标签(嵌套注意)
                <c:choose>
                  ...
                  <c:otherwise>
                     <c:choose>
                        <c:when...>
                        </c:when>
                        <c:otherwise>
                        </c:otherwise>
                     </c:choose>
                  </c:otherwise>
                </c:choose>

--%>
    <%
        request.setAttribute("height",178);
    %>
    <c:choose>
        <c:when test="${requestScope.height>190}">
            <h2>很高</h2>
        </c:when>
        <c:when test="${requestScope.height>180}">
            <h2>很高</h2>
        </c:when>
        <c:when test="${requestScope.height>170}">
            <h2>还行</h2>
        </c:when>
        <c:otherwise>
            <h2>可还行</h2>
        </c:otherwise>
    </c:choose>

4.<c:forEach/>标签
作用:遍历

属性:
  items          属性表示遍历的集合
    var            属性表示遍历到的数据
    begin          属性表示遍历的开始索引值,0开始
    end            属性表示遍历的结束索引值
    step           属性表示遍历的步长值,默认1
    varStatus      属性表示遍历到的数据的状态

       varStatus="status",后status的方法:
           Object getCurrent();    表示获取当前遍历到的数据
           int getIndex();         表示获取遍历的索引
           int getCount();         表示遍历的个数
           boolean isFirst();      表示当前遍历的数据是否是第一条
           boolean isLast();       表示当前遍历的数据是否是最后一条
           Integer getBegin();     获取begin属性值
           Integer getEnd();       获取end属性值
           Integer getStep();      获取step属性值
<%--
4.<c:forEach/>标签
    作用:遍历
    1.遍历1-10var属性表示循环的变量(也是当前正在遍历到的数据)
--%>
<c:forEach begin="1" end="10" var="i">
    ${i}
</c:forEach>
<br><hr>
<%--
    2.遍历Object数组
--%>
    <%
        request.setAttribute("arr",new String[]{"18855554433","19988887777","15533336666"});

    %>
    <c:forEach items="${requestScope.arr}" var="item">
        ${item}
    </c:forEach>
<hr>
    <%
        Map<String,Object> map=new HashMap<>();
        map.put("key1","value1");
        map.put("key2","value2");
        map.put("key3","value3");
        request.setAttribute("map",map);
    %>
    <c:forEach items="${requestScope.map}" var="maptest">
        ${maptest.key}:${maptest.value}
    </c:forEach>
<br><hr>
<%--
    遍历List集合中的Student--%>
    <%
        List<Student> studentList=new ArrayList<>();
        for (int i = 1; i <=10 ; i++) {
            studentList.add(new Student(i,"username"+i,"password"+i,18+i,"phone"+i));
        }
        request.setAttribute("stus",studentList);
    %>
    <table border="1px">
        <tr>
            <th>编号</th>
            <th>用户名</th>
            <th>密码</th>
            <th>年龄</th>
            <th>电话</th>
            <th>操作</th>
        </tr>


    <c:forEach begin="3" end="7" step="2" varStatus="status" items="${requestScope.stus}" var="stu">
        <tr>
            <td>${stu.id}</td>
            <td>${stu.username}</td>
            <td>${stu.password}</td>
            <td>${stu.age}</td>
            <td>${stu.phone}</td>
            <td>删除 , 修改</td>
        </tr>
    </c:forEach>
    </table>
<br><hr>

网页输出:

1 2 3 4 5 6 7 8 9 10
18855554433 19988887777 15533336666
key1:value1 key2:value2 key3:value3
编号	用户名	密码	年龄	电话	操作
4	username4	password4	22	phone4	删除 , 修改
6	username6	password6	24	phone6	删除 , 修改
8	username8	password8	26	phone8	删除 , 修改

文件的上传和下载

文件上传

步骤:
  1.要有一个form标签,method=post请求
  2.form标签的encType属性值必须为multipart/form-data值
  3.在form标签中使用input type=file添加上传的文件
  4.编写服务器代码(Servlet程序)接收,处理上传的数据

    encType=multipart/form-data 表示提交的数据,以多段(每一个表单项一个数据段)的形式 进行拼接,然后以二进制流的形式发送给服务器

commons-fileupload.jar常用API介绍说明-文件上传

commons-fileupload.jar需要依赖commons-io.jar这个包,所以这两个包我们都要引入

常用的类:

ServletFileUpload类,用于解析上传的数据
FileItem类,表示每一个表单项

常用的方法:

   boolean ServletFileUpload.isMultipartContent(HttpServletRequest request);
   判断当前上传的数据格式是否是多段的格式

   public List<FileItem> parseRequest(HttpServletRequest request)
   解析上传的数据

   boolean FileItem.isFormField()
   判断当前这个表单项,是否是普通的表单项,还是上传的文件类型
   true表示普通类型的表单项
   false 表示上传的文件类型

   String FileItem.getString()
   获取当前表单项的值

   String FileItem.getName();
   获取上传的文件名

   void FileItem.getName(file);
   将上传的文件写到    参数file所指向的硬盘位置

用例(Java代码):

public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //先判断上传的数据是否是多段数据(只有是多数据,才是文件上传的)
        if (ServletFileUpload.isMultipartContent(request)){
            //创建FileItemFactory工厂实现类
            FileItemFactory fileItemFactory=new DiskFileItemFactory();
            //创建用于解析上传数据的工具类ServletFileUpload类
            ServletFileUpload servletFileUpload=new ServletFileUpload(fileItemFactory);
            try {
                //解析上传数据,得到每一个表单项FileItem
                List<FileItem> list=servletFileUpload.parseRequest(request);
                //循环判断,每一个表单项,是普通类型,还是上传的文件
                for (FileItem fileItem:list){
                    if (fileItem.isFormField()){
                        //普通表单项
                        System.out.println("表单项的name属性值:"+fileItem.getFieldName());
                        //参数UTF-8解决乱码问题
                        System.out.println("表单项的value属性值:"+fileItem.getString("UTF-8"));

                    }else{
                        System.out.println("表单项的name属性值:"+fileItem.getFieldName());

                        String name=new String(fileItem.getName().getBytes("GBK"),"UTF-8");

                        System.out.println("上传的文件名:"+name);

                        fileItem.write(new File("C:\\Users\\Lenovo\\Desktop\\"+name));//上传的位置,这里上传后会直接传到桌面

                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

文件下载

 步骤:
        1.获取要下载的文件名
        2.读取要下载的文件内容
        3.把下载的文件内容回传给客户端
        4.在回传前,通过响应头告诉客户端返回的数据类型
        5.还要告诉客户端收到的数据是用于下载使用(还是使用响应头)

Java代码:

public class Download extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        1.获取要下载的文件名
        String downloadFileName="a.png";
//        2.读取要下载的文件内容(通过ServletContext对象可以读取)
        ServletContext servletContext=getServletContext();
//        3.把下载的文件内容回传给客户端
//        4.在回传前,通过响应头告诉客户端返回的数据类型
        String mimeType=servletContext.getMimeType("/file/"+downloadFileName);
        System.out.println("下载的文件类型:"+mimeType);
        response.setContentType(mimeType);
//        5.还要告诉客户端收到的数据是用于下载使用(还是使用响应头)
        //Content-Disposition响应头,表示收到的数据怎么处理
        //attachment表示附件,表示下载使用
        //filename=表示指定下载的文件名
        //url编码是把汉字转换成为%xx%xx的格式(十六进制)
        if (request.getHeader("User-Agent").contains("Firefox")){
            //如果是火狐浏览器使用Base64编码
            response.setHeader("Content-Disposition","attachment;filename==?UTF-8?B?"+ new BASE64Encoder().encode("希夫.jpg".getBytes("UTF-8"))+"?=");
        }else {
            //如果是IE或谷歌,使用URL编码操作
            response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("希夫.jpg","UTF-8"));
        }

        /*
            /   斜杠被服务器解析表示地址为http://ip:port/工程名/ 映射 到代码的Web目录
        */
        InputStream resourceAsStream=servletContext.getResourceAsStream("/file/"+downloadFileName);
        //获取响应的输出流
        OutputStream outputStream=response.getOutputStream();
        //读取输入流中的数据,复制给输出流,输出给客户端
        IOUtils.copy(resourceAsStream,outputStream);

        /*//火狐的编码
        String content="这是需要Base64编码的内容";
        //创建一个Base64编码器
        BASE64Encoder base64Encoder=new BASE64Encoder();
        //执行Base64编码操作
        String encodedString=base64Encoder.encode(content.getBytes("UTF-8"));
        System.out.println(encodedString);
        //火狐的解码
        //创建Base64解码器
         BASE64Decoder base64Decoder=new BASE64Decoder();
         //解码操作
        byte[] bytes=base64Decoder.decodeBuffer(encodedString);
        String str=new String(bytes,"UTF-8");
        System.out.println(str);*/
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值