BCSP-玄子Java开发之Java Web编程CH07_使用JSP/Servlet开发复杂业务

文章介绍了在JavaWeb环境中如何实现数据分页展示,包括设置每页数据量、计算总页数和获取指定页数据的步骤。同时,讲解了Servlet3.0的文件上传API,包括Part接口、@MultipartConfig注解的使用,以及如何控制上传文件的大小和类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BCSP-玄子Java开发之Java Web编程CH07_使用JSP/Servlet开发复杂业务

实现数据分页查

大量数据的展示

  • 页面冗长、数据定位不方便,需要拖动页面才能浏览更多的数据
  • 一次性查询大量数据,数据库查询压力大,浪费系统资源

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d5AyOCQK-1687706642193)(./assets/image-20230625120023570.png)]

分页展示大量数据

常见的数据分页展示案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B3JeGASW-1687706642194)(./assets/image-20230625120049398.png)]

分页功能要点

  • 每页显示数据量
  • 数据总量
  • 当前页码

实现分页的关键步骤

  • 确定每页需要展示的数据数量
  • 计算数据可以展示的总页数
  • 实现获取指定页码的数据记录

确定每页需要展示的数据数量

  • 根据需求,设定每页展示数据量或通过请求动态传递每页展示的数据量
  • 创建分页类( Page.java),封装分页相关信息
public class Page {
    private int totalPageCount = 0;    //总页数
    private int pageSize = 10;            //每页展示记录数
    private int totalCount;                   //记录总数
    private int currPageNo = 1;          //当前页码
    private List<Blog> blogsList;        //每页微博集合
    // 省略其他代码…
}

计算数据可以展示的总页数

  • 查询数据总量
select count(1) from 表名
  • 计算总页数
//每页微博集合
public void setTotalCount(int totalCount) {
    if (totalCount > 0){
        this.totalCount = totalCount;
        totalPageCount = this.totalCount % pageSize == 0 ?
                                    (this.totalCount / pageSize) :
                                    (this.totalCount / pageSize + 1);
    }
}

使用limit关键字分页查询数据

select … from blog LIMIT 5, 10
-- 从第6条数据开始 查询10条数据
  • 实现获取指定页码的数据记录
起始行偏移量 = (当前页页码 - 1* 每页展示的记录数

不同数据库实现分页的SQL语句之间存在差异,因此在实际应用中根据数据库的不同,需要修改相应的SQL语句

页面边界控制

  • 当前页码:页面初次打开时,页码默认是第1页
String pageIndex = request.getParameter(“pageIndex”);//获得当前页码
if (pageIndex == null || (pageIndex = pageIndex.trim()).length() == 0) {
    pageIndex = "1";
}
  • 首页:当页面处于首页时,不可执行上一页操作
if (currPageNo < 1) { currPageNo = 1; }
  • 末页:当页面处于末页时,不可执行下一页操作
// 如果页码大于总页数,设置页面值为最大页数
if (pageObj.getCurrPageNo() > pageObj.getTotalPageCount()){
    pageObj.setCurrPageNo(pageObj.getTotalPageCount());
}

前端实现分页功能

  • 当页面处于首页时,不显示“首页”、“上一页”
  • 当页面处于末页时,不显示“末页”、“下一页”
当前页数:[<%=pageObj.getCurrPageNo()%>/<%=pageObj.getTotalPageCount()%>]&nbsp;
<% if (pageObj.getCurrPageNo() > 1) {%> 
    <a href="../control/blog?opr=allBlogList&keyword=<%=keyword%>&pageIndex=1">首页</a>
    <a href="../control/blog?opr=allBlogList&keyword=<%=keyword%>
            &pageIndex=<%=pageObj.getCurrPageNo()-1%>">上一页</a>
<%} if (pageObj.getCurrPageNo() < pageObj.getTotalPageCount()) {%>
    <a href="../control/blog?opr=allBlogList&keyword=<%=keyword%>
            &pageIndex=<%=pageObj.getCurrPageNo()+1%>">下一页</a>
    <a href="../control/blog?opr=allBlogList&keyword=<%=keyword%>
            &pageIndex=<%=pageObj.getTotalPageCount()%>">末页</a>
<%}%>

实现文件上传

常见的文件上传功能

  • 发表朋友圈、微博
  • 发布抖音、快手视频
  • 上传证件照片

Servlet 3.0 文件上传API

Part接口代表上传的文件或表单数据,Part接口的常用方法

方法说明
String getName()获取控件的name属性
long getSize()获取上传文件大小,单位是字节
InputStream getInputStream()获取输入流,用于检索文件的内容
void write(String fileName)将上传的文件写入磁盘
String getHeader(String name)获取指定part请求头信息
Collection<String> getHeaders(String name)获取指定名称的所有请求头信息
Collection<String> getHeaderNames()获取所有请求头的名称
String getContentType()获取文件MIME类型

MIME

Multipurpose Internet Mail Extensions

  • 描述消息类型的因特网标准
  • 包含文本、图像、音频、视频以及其他应用程序专用的数据
类型/子类型扩展名
application/pdfpdf
application/x-javascriptjs
image/gifgif
image/jpegjpeg
image/jpegjpg

@MultipartConfig注解

标注在 Servlet 上

  • 表示Servlet希望处理请求的MIME类型是 multipart/form-data
  • 标注@MultipartConfig注解后,可通过HttpServletRequest.getPart()方法或HttpServletRequest.getParts()方法获取Part对象
属性名称说明
fileSizeThreshold是否将文件缓存到磁盘的大小阈值。当文件小于该值时,文件存储在内存中;否则缓存到磁盘中。默认为0,即文件被直接缓存到磁盘
location指定缓存上传文件的临时目录,默认为""
maxFileSize每个上传文件的最大体量,以字节为单位。默认值为-1L,表示不限制大小
maxRequestSize整个multipart/form-data请求所允许的最大体量,默认值为-1L,表示不限制大小

通过Servlet API实现单文件上传

  • 编写文件上传表单
<form action="UploadServlet" enctype="multipart/form-data" method="post">
    用户名:<input  type="text"  name="user"><br>
    上传文件:<input  type="file"  name="ufile"><br>
    <input type="submit" value="上传">
</form>

enctype属性常用取值

  • application/x-www-form-urlencode(默认值)
  • multipart/form-data
  • text/plain
  • 创建文件上传的Servlet并添加@MultipartConfig注解
@WebServlet(name="UploadServlet", urlPatterns = "/UploadServlet")
@MultipartConfig
public class UploadServlet extends HttpServlet {}
  • 通过Part对象获取上传文件信息
Part part = request.getPart("ufile");           //获取Part对象
// 对应表单中name 属性为“ufile”的 input标签
String fileName = extractFileName(part); //提取文件名
  • 从请求头中提取文件名
private String extractFileName(Part part) {
    String contentDisp = part.getHeader("content-disposition");
    String[] items = contentDisp.split(";");
    for (String s : items) {
        if (s.trim().startsWith("filename")) {
            return s.substring(s.indexOf("=") + 2, s.length()-1);
        }
    }
    return "";
}
  • 将文件写入指定目录
String uploadFilePath = request.getSession()
            .getServletContext().getRealPath("upload/");
			// 服务器文件目录 绝对路径
part.write(uploadFilePath + File.separator + fileName);

如果写入文件的目录不存在,则需要先创建该目录

通过Servlet API实现多文件上传

  • 编写文件上传表单
<form action="UploadServlet" enctype="multipart/form-data" method="post">
    用户名:<input  type="text"  name="user"><br>
    上传文件1:<input  type="file"  name="ufile1"><br>
    上传文件2:<input  type="file"  name="ufile2"><br>
    <input type="submit" value="上传">
</form>
  • 获取上传文件的Part对象集合,循环处理上传文件
  • 通过Part对象获取上传文件信息
Collection<Part> parts = request.getParts();
for (Part part : request.getParts()) {
    if(part.getName().startsWith("ufile")){ //判断是否是上传文件
        String fileName = extractFileName(part);
        part.write(uploadFilePath + File.separator + fileName);
    }
}

控制上传文件类型

  • 定义允许上传的图片类型
private String ALLOW_IMG_TYPE = "image/gif;image/png;image/jpeg";
  • 获取上传文件的类型
String contentType = part.getContentType(); // 获取上传文件类型
  • 判断上传文件类型是否符合规定
List<String> allowTypes = Arrays.asList(ALLOW_IMG_TYPE.split(";"));
if(!(contentType==null  ||  "".equals(contentType.trim())) 
        && allowTypes.contains(contentType)){
    String fileName = extractFileName(part); //提取文件名
    part.write(uploadFilePath + File.separator + fileName); //写入文件
    message = "上传成功!";
}else{message = "上传失败,文件类型只能是gif格式、jpg格式和png格式!"; }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DoFI9m6p-1687706642195)(./assets/image-20230625121708298.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ms8mH4Gy-1687706642195)(./assets/image-20230625121710629.png)]

控制上传文件大小

通过@MultipartConfig注解设置上传文件大小

@WebServlet(name="UploadServlet", urlPatterns = "/UploadServlet")
@MultipartConfig(maxFileSize=1024*1024*2) //设置文件最大为2MB
public class UploadServlet extends HttpServlet {}

获取注解中设置的值

private static MultipartConfig config 
            = UploadServlet.class.getAnnotation(MultipartConfig.class);

根据文件上传结果,封装提示信息

try { // 省略其他代码
    part.write(uploadFilePath + File.separator + fileName); //将文件写入指定目录
    message = "上传成功后的文件名是:"+fileName+",文件大小是:"+
                part.getSize()+"bytes!";
}catch(IllegalStateException e){
        message = "上传失败,文件太大,文件的最大限制是:"+
        config.maxFileSize() +"bytes!";
}
  • 上传文件大小超限,运行效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qBkOtkFW-1687706642196)(./assets/image-20230625121949360.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值