JSTL+BeanUtils+分页+文件上传,sitemesh用来进行前端模板

1、  输出

<%

    request.setAttribute("username","<h1>张三</h1>");

%>

<body>

  ${username }<!-- 会先在pageContext中找username,如果找不到去request -->

  <c:out value="${username}"default="查无此人" escapeXml="true"></c:out>

</body>

通过EL表达式${username}这种可以获得输出,如果访问连接为:http://localhost:8080/JSTL/01/01.jsp?hello=world

那么可以通过EL表达式:${param.hello }获得传过来的参数值world

 

2、 分页工程测试

http://localhost:8080/Shop07-MVC01/user.do?method=list

(1)构造model类,主要是用于存放分页的各种数据,如总数、总页数、起始页、每页数等,有两个,一个Pager.java用于存放上面的数据,一个SystemContext.java用于线程操作,使得每个用户都会操作自己的页码

package com.lxp.model;

import java.util.List;

public class Pager<E> {

    //第几页

    private int pageIndex;

    //每页显示多少条

    private int pageSize;

    //分页的开始值

    private int pageOffset;

    //总共多少条记录

    private int totalRecord;

    //总共多少页

    private int totalPage;

    //放置具体数据的列表

    private List<E> datas;

   

    public int getPageIndex() {

       return pageIndex;

    }

    public void setPageIndex(int pageIndex) {

       this.pageIndex = pageIndex;

    }

    public int getPageSize() {

       return pageSize;

    }

    public void setPageSize(int pageSize) {

       this.pageSize = pageSize;

    }

    public int getPageOffset() {

       return pageOffset;

    }

    public void setPageOffset(int pageOffset) {

       this.pageOffset = pageOffset;

    }

    public int getTotalRecord() {

       return totalRecord;

    }

    public void setTotalRecord(int totalRecord) {

       this.totalRecord = totalRecord;

    }

    public int getTotalPage() {

       return totalPage;

    }

    public void setTotalPage(int totalPage) {

       this.totalPage = totalPage;

    }

    public List<E> getDatas() {

       return datas;

    }

    public void setDatas(List<E> datas) {

       this.datas = datas;

    }

}

 

package com.lxp.model;

//与分页有关

public class SystemContext {

    private static ThreadLocal<Integer> pageSize = new ThreadLocal<Integer>();

    private static ThreadLocal<Integer> pageIndex = new ThreadLocal<Integer>();

    private static ThreadLocal<Integer> pageOffset = new ThreadLocal<Integer>();

    private static ThreadLocal<String> order = new ThreadLocal<String>();//升序还是降序

    private static ThreadLocal<String> sort = new ThreadLocal<String>();//根据哪一个字段来

    public static int getPageSize() {

       return pageSize.get();

    }

    public static void setPageSize(int _pageSize) {

       pageSize.set(_pageSize);

    }

    public static void removePageSize() {

       pageSize.remove();

    }

    public static int getPageIndex() {

       return pageIndex.get();

    }

    public static void setPageIndex(int _pageIndex) {

       pageIndex.set(_pageIndex);

    }

    public static void removePageIndex() {

       pageIndex.remove();

    }

    public static int getPageOffset() {

       return pageOffset.get();

    }

    public static void setPageOffset(int _pageOffset) {

       pageOffset.set(_pageOffset);

    }

    public static void removePageOffset() {

       pageOffset.remove();

    }

    public static String getOrder() {

       return order.get();

    }

    public static void setOrder(String _order) {

       order.set(_order);

    }

    public static void removeOrder() {

       order.remove();

    }

    public static String getSort() {

       return sort.get();

    }

    public static void setSort(String _sort) {

       sort.set(_sort);

    }

    public static void removeSort() {

       sort.remove();

    }

}

(2)写dao层,将分页需要的数据要进行获取

public Pager<T> find(String sqlId,Map<String,Object>para) {

       int pageSize = SystemContext.getPageSize();

       int pageOffset = SystemContext.getPageOffset();

       String order = SystemContext.getOrder();

       String sort = SystemContext.getSort();

       Pager<T> pages = new Pager<T>();

       SqlSession session = null;

       try {

           session = MyBatisUtil.createSession();

           if(para==null)

              para = new HashMap<String, Object>();

           para.put("pageSize", pageSize);

           para.put("pageOffset", pageOffset);

           para.put("order", order);

           para.put("sort", sort);

           List<T> datas = session.selectList(sqlId,para);

           pages.setDatas(datas);

           pages.setPageOffset(pageOffset);

           pages.setPageSize(pageSize);

           int totalRecord = session.selectOne(sqlId+"_count",para);//总数约定为查询一个+ _count

           pages.setTotalRecord(totalRecord);

       } finally {

           MyBatisUtil.close(session);

       }

       return pages;

}

(3)相应的xml文件中的分页sql配置

<select id="find"resultType="User" parameterType="map">

    <!-- 如果有多个查询条件,不好加逻辑,可以使用 select * from t_user where 1=1  然后

       <if test="">and 条件1</if>

       <if test="">and 条件2</if>

       或者使用下面的<where>标签

     -->

       select * from t_user

<!--       <if test="name!=null">

           where (username like '%${name}%' or nickname like'%${name}%')

       </if>-->

       <where>

           <if test="name!=null">(username like'%${name}%' or nickname like '%${name}%')</if>

           <if test="type!=null">and type=#{type}</if>

       </where>

       <if test="sort!=null">

           order by ${sort}

           <choose>

              <when test="order!=null">${order}</when>

              <otherwise>asc</otherwise>

           </choose>

       </if>

       limit #{pageOffset},#{pageSize}

</select>

(4)写Filter类,用来对前端提交的请求进行分页预处理

package com.lxp.web;

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import com.lxp.model.SystemContext;

public class SystemContextFilter implements Filter{

    public void destroy() {}

    public void doFilter(ServletRequest req, ServletResponse resp,

           FilterChain chain) throws IOException, ServletException{

       int pageOffset = 0;

       int pageSize = 15;

       String sort = req.getParameter("sort");

       String order = req.getParameter("order");

       try {

           try {

               if(req.getParameter("pager.offset")==null){  

                   pageOffset=0;  

                } else

                pageOffset = Integer.parseInt(req.getParameter("pager.offset"));

           } catch(NumberFormatException e) {

              e.printStackTrace();

           }

           SystemContext.setPageOffset(pageOffset);

           SystemContext.setPageSize(pageSize);

           SystemContext.setSort(sort);

           SystemContext.setOrder(order);

           chain.doFilter(req, resp);

       } finally {

           SystemContext.removePageOffset();

           SystemContext.removePageSize();

           SystemContext.removeSort();

           SystemContext.removeOrder();

       }

    }

    public void init(FilterConfig arg0) throws ServletException {}

}

(5)web.xml对filter进行声明

<filter>

       <filter-name>SystemContextFilter</filter-name>

       <filter-class>com.lxp.web.SystemContextFilter</filter-class>

    </filter>

    <filter-mapping>

       <filter-name>SystemContextFilter</filter-name>

       <url-pattern>/*</url-pattern>

</filter-mapping>

(6)导入pager-taglib.jar,主要是用于在jsp页面进行与分页相关的标签编写

(7)写pager.jsp页面,这个主要是用于分页配置,可以作为一个单独的页面动态include进去,所以单独写出来

<%@ page language="java"import="java.util.*" pageEncoding="UTF-8"%>

<%@taglib prefix="pg"uri="http://jsptags.com/tags/navigation/pager"%>

<%@ taglib prefix="c"uri="http://java.sun.com/jsp/jstl/core"%>

<pg:pager maxPageItems="15"items="${param.items }" export="curPage=pageNumber"url="${param.url}">

    <c:forEach items="${param.params}" var="p">

       <pg:param name="${p}"/>

    </c:forEach>

    <pg:last>

       共${param.items}记录,共${pageNumber }页,

    </pg:last>

       当前第${curPage }页

    <pg:first>

       <a href="${pageUrl }">首页</a>

    </pg:first>

    <pg:prev>

       <a href="${pageUrl }">上一页</a>

    </pg:prev>

    <pg:pages>

       <c:if test="${curPage eq pageNumber}">

           [${pageNumber }]

       </c:if>

       <c:if test="${curPage ne pageNumber }">

           <a href="${pageUrl }">${pageNumber }</a>

       </c:if>

    </pg:pages>

    <pg:next>

       <a href="${pageUrl }">下一页</a>

    </pg:next>

    <pg:last>

       <a href="${pageUrl }">尾页</a>

    </pg:last>

</pg:pager>

(8)在使用该pager.jsp的页面进行相应的参数配置,如table标签下的一个td中

<td colspan="6">

              <jsp:include page="/inc/pager.jsp">

                  <jsp:param value="${users.totalRecord}"name="items"/>

                  <jsp:param value="user.do"name="url"/>

                  <jsp:param value="method,name"name="params"/>

              </jsp:include>

           </td>

 

 

3、BeanUtils使用方式:

(1)导入jar包

(2)创建一个Model类User

package com.lxp.model;

import java.util.Date;

public class User {

    private int id;

    private String username;

    private int age;

    private String password;

    private Date born;

    public int getId() {

       return id;

    }

    public void setId(int id) {

       this.id = id;

    }

    public String getUsername() {

       return username;

    }

    public void setUsername(String username) {

       this.username = username;

    }

    public int getAge() {

       return age;

    }

    public void setAge(int age) {

       this.age = age;

    }

    public String getPassword() {

       return password;

    }

    public void setPassword(String password) {

       this.password = password;

    }

    public Date getBorn() {

       return born;

    }

    public void setBorn(Date born) {

       this.born = born;

    }

    public String toString() {

       return "User[age=" + age + ",born=" + born + ", id=" + id

              + ",password=" + password + ",username=" + username + "]";

    }

}

(3)测试中只需要使用BeanUtils.copyProperty(new User(),”age”,1)这种形式就可以对User类的属性进行赋值

package com.lxp.test;

import java.util.Date;

import org.apache.commons.beanutils.BeanUtils;

import org.apache.commons.beanutils.ConvertUtils;

import org.apache.commons.beanutils.Converter;

import org.junit.Test;

import com.lxp.model.DateConverter;

import com.lxp.model.User;

public class Test01 {

    @Test

    public void test01() {

       try {

           User u = new User();

           String value = "张三";

           String key = "username";

           BeanUtils.copyProperty(u, "age", 1);

           BeanUtils.copyProperty(u, key, value);

           User u2 = new User();

           BeanUtils.copyProperties(u2, u);

           //BeanUtils无法自动拷贝日期,因为日期的格式太多,所以不知道该转换

           //成何种形式,就需要自己定义相应的转换器来完成转换

           /*

            * 定义转换器步骤

            * 1、创建一个类让其实现Converter接口

            * 2、覆盖这个接口中的convert方法,该方法中实现转换

            * 3、在时下拷贝之前注册转换器

            */

           ConvertUtils.register(new DateConverter(), Date.class);

           BeanUtils.copyProperty(u, "born","1923-12-23");

           System.out.println(u.getBorn());

           System.out.println(u2);

       } catch (Exception e) {

       }

    }

}

(4)对于特殊的情况,当User中有Date类型时,BeanUtils是不知道该如何进行转换的,因为日期的类型很多,这个时候就需要自己手动写个转换器类,该类需要实现Converter接口

package com.lxp.model;

import java.util.Date;

import java.text.SimpleDateFormat;

import org.apache.commons.beanutils.Converter;

public class DateConverter implements Converter{

/*

 * 该方法两个参数,第一个参数表示转换的类型,如果要拷贝一个字符串到日期中,此时

 * 就是日期类型,第二个参数表示转换的值

 */

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    @Override

    public <T> T convert(Class<T> clz, Object value) {

       if(clz!=Date.class) {

           return null;

       }

       try {

           if (value instanceof String) {

              return (T) sdf.parse((String) value);

           }

       } catch (Exception e) {

       }

       return null;

    }

}

(5)调用方式如上面的(3)所示,对User相应的Date属性进行赋值之前,需要先进行注册即可ConvertUtils.register(new DateConverter(), Date.class);

 

 

注意:如果要实现这种方式:

(1)有一个Point的Model类

package com.lxp.model;

public class Point {

    int x;

    int y;

    public int getX() {

       return x;

    }

    public void setX(int x) {

       this.x = x;

    }

    public int getY() {

       return y;

    }

    public void setY(int y) {

       this.y = y;

    }

}

(2)User类中有这个Point的引用

    private Point point;

public Point getPoint() {

       return point;

    }

    public void setPoint(Point point) {

       this.point = point;

    }

(3)如果想通过输入“12,13”这种方式就能够给User类中的Point进行x和y赋值的话,如下所示,需要写一个转换类BeanUtils.copyProperty(u,"point", "12,13");

package com.lxp.model;

import java.util.Date;

importjava.text.SimpleDateFormat;

importorg.apache.commons.beanutils.Converter;

public class PointConverterimplements Converter{

    public <T> T convert(Class<T> clz, Object value) {

       if(clz!=Point.class) {

           return null;

       }

       try {

           if (value instanceof String) {

              String value2 = (String) value;

              String[] params = value2.split(",");

              Point p = new Point();

              p.setX(Integer.parseInt(params[0]));

              p.setY(Integer.parseInt(params[1]));

              return (T) p;

           }

       } catch (Exception e) {

       }

       return null;

    }

}

 

 

4、文件上传(使用commons-fileupload.jar以及commons-io.jar这两个jar文件)

(1)普通的实现方式:

①有ServletFileUpload获得是否是Multipart形式提交,如果是,执行②

②创建一个ServletFileUpload对象upload。

③由上面的upload创建一个FileItemIterator对象

④获取iterator值,获取FileItemStram对象fis,并通过这个对象通过openStream()方法获得InputStrame对象

⑤使用fis判断是否是表单,如果是表单的话就直接获取表单中的参数和值就可以了,这里通过Streams.asString(is)来获得表单的值。如果不是表单说明是文件上传,可以通过FileOutputStream来进行byte写入。

public voiddoPost(HttpServletRequest request, HttpServletResponse response)

           throws ServletException,IOException {

       file02(request,response);

       request.setCharacterEncoding("utf-8");

       boolean isMultipart =ServletFileUpload.isMultipartContent(request);

       InputStream is = null;

       FileOutputStream fos = null;

       try {

           if (isMultipart) {

              ServletFileUpload upload = newServletFileUpload();

              FileItemIterator iter =upload.getItemIterator(request);

              while (iter.hasNext()) {

                  FileItemStream fis =iter.next();

                  //是multipart就表示需要使用字节数据进行传递,需要使用输入流

                  is = fis.openStream();

                  if (fis.isFormField()) {

                     System.out.println(fis.getFieldName());

                     System.out.println(newString(Streams.asString(is).getBytes("ISO-8859-1"),"gbk"));//通过该方法可以将流中的数据转换为String

                  } else {

                      System.out.println(fis.getName());

                     String path =request.getSession().getServletContext().getRealPath("/upload");

                     path = path + "/"+ fis.getName();

                     fos = newFileOutputStream(path);

                     byte[] buf = newbyte[2014];

                     int len = 0;

                     while((len=is.read(buf))>0){

                         fos.write(buf,0,len);

                     }

                  }

              }

           }

       } catch (Exception e) {

       } finally {

           if(is!=null) is.close();

           if(fos!=null) fos.close();

       }

    }

 

(2)使用自己创建的一个新类来创建一个封装,然后servlet直接简单调用就好了,这个类需要继承HttpServletRequestWrapper。将表单提交上来的数据如果是以Multipart形式提交的,首先创建MultipartRequestWrapper对象,然后将提交上来的数据封装在Map中,servlet直接调用这里面的相应的getParameter方法即可获得,以前通过req.getParameter()方法获得的值,从而达到统一。另外,这里文件上传是通过Streams.copy(is, new FileOutputStream(PATH + "/upload/" + fis.getName()), true);这个方法来获得的,不是上面的byte形式,比较简单。

注意:在IE中,传过来的fis.getName就是c:/……这种全路径,那么可以使用

//对于IE上传的文件会得到完整的绝对路径,需要将绝对路径字符串进行截取文件名

String fname = FilenameUtils.getName(fis.getName());//得到文件名

这个方法可以实现兼容,就可以直接获得文件名,而不用管IE还是火狐

 

 

public class MultipartRequestWrapper extends HttpServletRequestWrapper{

    private Map<String,String[]>params = new HashMap<String, String[]>();

    private static final String PATH = "D:\\MyEclipse-8.6\\Workspaces\\MyEclipse8.6\\FileUploadTest01\\WebRoot\\";

    public MultipartRequestWrapper(HttpServletRequest request) {

       super(request);

       setParams(request);

    }

    private void setParams(HttpServletRequest request) {

       try {

           request.setCharacterEncoding("UTF-8");

       } catch (UnsupportedEncodingException e1) {

           // TODO Auto-generatedcatch block

           e1.printStackTrace();

       }

       //判断是否是multipart类型

       boolean isMul = ServletFileUpload.isMultipartContent(request);

       if(isMul) {

           ServletFileUpload upload = new ServletFileUpload();

           try {

              FileItemIterator iter =upload.getItemIterator(request);

              InputStream is = null;

              while (iter.hasNext()) {

                  FileItemStream fis = iter.next();

                  is = fis.openStream();

                  if (fis.isFormField()) {

                     setFormParams(fis.getFieldName(),is);//主要是针对类似于checkbox这种多name

                  } else {

                     //要输入流中有数据(>0)才进上传,否则不进行

                     if(is.available()>0) {

                         //对于IE上传的文件会得到完整的绝对路径,需要将绝对路径字符串进行截取文件名

                         String fname = FilenameUtils.getName(fis.getName());//得到文件名

                         //完成文件上传

                         System.out.println(PATH+"upload\\"+ fname);

                         Streams.copy(is, new FileOutputStream(PATH + "/upload/"

                                + fname), true);

                         params.put(fis.getFieldName(), new String[] { fis

                                .getName() });

                     }

                  }

              }

           } catch (Exception e) {

              // TODO: handleexception

           }

       } else {

           //如果不是Multipart直接通过请求获取值

           params = request.getParameterMap();

       }

    }

    private void setFormParams(String paramKey,InputStream is) throws IOException {

       if(params.containsKey(paramKey)) {

           //说明表单域中已经存在了值,需要向paramsString的数组中添加

           String[] values = params.get(paramKey);

           values = Arrays.copyOf(values, values.length+1);//数组长度加1

           values[values.length-1] = Streams.asString(is);

           params.put(paramKey, values);

       } else {

           params.put(paramKey, new String[]{Streams.asString(is)});

       }

    }

    public Map<String,String[]> getParameterMap() {

       return params;

      

    }

    public String getParameter(String name) {

       String[] values = params.get(name);

       if(values!=null) {

           return values[0];

       }

       return null;

    }

    @Override

    public String[] getParameterValues(String name) {

       String[] values = params.get(name);

       if(values!=null) {

           return values;

       }

       return null;

    }

}

 

你可能感兴趣的:(JSTL+BeanUtils+分页+文件上传,sitemesh用来进行前端模板)