练习网上商城项目遇到一些问题解决记录

本文深入探讨了Java开发中的关键技巧,包括邮件发送配置、session监听销毁、文件上传处理、Redis使用、事务提交、分页模板实现、BeanUtils嵌套存储数据等,提供了丰富的代码示例和解决方案。

以下记录解释简略,仅作为自己以后再次遇到查阅

1.发送邮件,阿里云屏蔽25端口处理

// 1.创建一个程序与邮件服务器会话对象 Session

        Properties props = new Properties();
        //设置发送的协议
        props.setProperty("mail.transport.protocol", "SMTP");

        //设置发送邮件的服务器
        String smtpPort = "465";//端口
        props.setProperty("mail.smtp.port", smtpPort);
        props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.socketFactory.port", smtpPort);
        props.setProperty("mail.host", "smtp.163.com");
        props.setProperty("mail.smtp.auth", "true");// 指定验证为true

使用的是网易邮箱,改端口为465,配置SSL。

2.session监听销毁

public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        String filePath=session.getAttribute("filePath").toString();
        //当session销毁时,删除其保存的验证码图片
        DeleteFileUtil.deleteFile(filePath);
        System.out.println("销毁"+filePath);
    }

3.文件上传

/**
     * 添加上传商品
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public String addProduct(HttpServletRequest request, HttpServletResponse response) throws Exception{
        Product product=new Product();
        //存放提交的内容
        Map<String,String> map=new HashMap<String,String>();
        //用工具执行request.getInputStream(),对上传数据拆分封装
        DiskFileItemFactory fac=new DiskFileItemFactory();
        ServletFileUpload upload=new ServletFileUpload(fac);
        List<FileItem> list = upload.parseRequest(request);
        //遍历提交的数据
        for (FileItem item:list) {
            //如果是普通项,则把name作为键名,内容作为值存放到map
            if (item.isFormField()){
                map.put(item.getFieldName(),item.getString("utf-8"));
            }else{ //上传项
                //获取上传的文件名
                String fileName=item.getName();
                //改变文件名
                 fileName= UploadUtils.getUUIDName(fileName);
                //通过FileItem获取到输入流对象,通过输入流可以获取到图片二进制数据
                InputStream is=item.getInputStream();
                //获取到项目下文件上传的真实路径--products/3
                String realPath=getServletContext().getRealPath("/products/3/");
                //通过文件名生成一个随机八层子目录----作用-1.防止文件名重复--2.防止统一层目录下文件过多或者目录过多造成系统性能损耗
                String dir=UploadUtils.getDir(fileName);
                String path=realPath+dir;
                //创建目录
                File newDir=new File(path);
                if (!newDir.exists()){
                    //不存在则创建
                    newDir.mkdirs();
                }
                //在服务端创建一个空文件(后缀必须和上传到服务端的文件名后缀一致)
                File newFile=new File(newDir,fileName);
                if (!newFile.exists()){
                    //不存在则创建
                    newFile.createNewFile();
                }
                //建立和空文件对应的输出流
                OutputStream os=new FileOutputStream(newFile);
                //将输入流中的数据刷到输出流中
                IOUtils.copy(is,os);
                //释放资源
                IOUtils.closeQuietly(is);
                IOUtils.closeQuietly(os);
                //将图片路径存入map
                map.put("pimage","/products/3/"+dir+"/"+fileName);

            }
        }
          //利用BeanUtils将MAP中的数据填充到Product对象上
        BeanUtils.populate(product, map);
        product.setPid(UUIDUtils.getId());
        //设置上传时间
        product.setPdate(new Date());
        product.setPflag(0);
        //调用service,存入数据库
        productService.saveProduct(product);
        //返回商品列表
        response.sendRedirect("AdminProductServlet?method=findAllProduct&pflag=0&num=1");
        return null;
    }

4.Redis初使用

连接获取


        //连接Redis
        Jedis jedis = JedisUtils.getJedis();
        //获取里面键值对名
        String jsons = jedis.get("allCats");
        //如果Redis没有数据
        if (jsons==null||"".equals(jsons)){
            // 调用业务方法
            CategoryService categoryService = new CategoryServiceImpl();
            List<Category> allCategory = categoryService.findAll();
            jsons = JsonUtil.list2json(allCategory);
            //赋值
            jedis.set("allCats",jsons);
        }
        JedisUtils.closeJedis(jedis);

删除

 //删除Redis缓存,客户端访问时从新获取
        Jedis jedis = JedisUtils.getJedis();
        jedis.del("allCats");
        JedisUtils.closeJedis(jedis);

工具类


public class JedisUtils {
	//创建连接池
	private static JedisPoolConfig config;
	private static JedisPool pool;

	static{
		config=new JedisPoolConfig();
		config.setMaxTotal(30);
		config.setMaxIdle(2);

		pool=new JedisPool(config, "127.0.0.1", 6379);
	}


	//获取连接的方法
	public static Jedis getJedis(){
		return pool.getResource();
	}


	//释放连接
	public static void closeJedis(Jedis j){
		j.close();
	}
}

5.事务提交

Connection conn=null;
        try {
            conn=JDBCUtils.getConnection();
            //开启事务
            conn.setAutoCommit(false);

            orderDao.saveOrder(conn,order);
            for (OrderItem item:order.getList() ){
                orderDao.saveOrderItem(conn,item);
            }
            //成功,提交事务
            conn.commit();
        } catch (SQLException e) {
            //失败,回滚事务
            conn.rollback();
            e.printStackTrace();
        } finally {
            //关闭释放conn
            JDBCUtils.closeConn(conn);

        }

6.分页模板

//数量总计
       int totalRecerds=orderDao.gettotalRecerds();
//分页模型
        PageModel pm=new PageModel(num,totalRecerds,14);
        //分页的显示信息
        List list=orderDao.findOrdersWithPage(pm.getStartIndex(),pm.getPageSize());
        pm.setRecords(list);
        pm.setUrl("AdminOrderServlet?method=findAllOrder");
        return pm;

分页的模型


import java.util.List;

/**
 * 存放分页相关的数据
 */
public class PageModel {
    //基本属性
    private int currentPageNum;//当前页数,由用户指定				*
    private int pageSize = 5;//每页显示的条数,固定的				*
    private int totalRecords;//总记录条数,数据库查出来的			    *
    private int totalPageNum;//总页数,计算出来的					*
    private int startIndex;//每页开始记录的索引,计算出来的			    *
    private int prePageNum;//上一页							    *
    private int nextPageNum;//下一页							    *

    private List records;//已经分好页的结果集


    //扩展属性
    //一共每页显示9个页码按钮
    private int startPage;//开始页码
    private int endPage;//结束页码

    //完善属性
    private String url;


    //要想使用我的分页,必须给我两个参数。一个是要看哪一页,另一个是总记录条数

    /**
     * @param currentPageNum 当前页数
     * @param totalRecords   总记录条数
     * @param pageSize       每页显示的条数
     */
    public PageModel(int currentPageNum, int totalRecords, int pageSize) {
        this.currentPageNum = currentPageNum;
        this.totalRecords = totalRecords;
        this.pageSize = pageSize;

        //计算查询记录的开始索引
        startIndex = (currentPageNum - 1) * pageSize;
        //计算总页数
        totalPageNum = totalRecords % pageSize == 0 ? (totalRecords / pageSize) : (totalRecords / pageSize + 1);


        startPage = currentPageNum - 4; //5
        endPage = currentPageNum + 4;  //13
        //看看总页数够不够9页
        if (totalPageNum > 9) {
            //超过了9页
            if (startPage < 1) {
                startPage = 1;
                endPage = startPage + 8;
            }
            if (endPage > totalPageNum) {
                endPage = totalPageNum;
                startPage = endPage - 8;
            }
        } else {
            //不够9页
            startPage = 1;
            endPage = totalPageNum;
        }
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public int getStartPage() {
        return startPage;
    }

    public void setStartPage(int startPage) {
        this.startPage = startPage;
    }

    public int getEndPage() {
        return endPage;
    }

    public void setEndPage(int endPage) {
        this.endPage = endPage;
    }

    public int getPrePageNum() {
        prePageNum = currentPageNum - 1;
        if (prePageNum < 1) {
            prePageNum = 1;
        }
        return prePageNum;
    }

    public int getNextPageNum() {
        nextPageNum = currentPageNum + 1;
        if (nextPageNum > totalPageNum) {
            nextPageNum = totalPageNum;
        }
        return nextPageNum;
    }


    public int getCurrentPageNum() {
        return currentPageNum;
    }


    public void setCurrentPageNum(int currentPageNum) {
        this.currentPageNum = currentPageNum;
    }


    public int getPageSize() {
        return pageSize;
    }


    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }


    public int getTotalRecords() {
        return totalRecords;
    }


    public void setTotalRecords(int totalRecords) {
        this.totalRecords = totalRecords;
    }


    public int getTotalPageNum() {
        return totalPageNum;
    }


    public void setTotalPageNum(int totalPageNum) {
        this.totalPageNum = totalPageNum;
    }


    public int getStartIndex() {
        return startIndex;
    }


    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }


    public void setPrePageNum(int prePageNum) {
        this.prePageNum = prePageNum;
    }


    public void setNextPageNum(int nextPageNum) {
        this.nextPageNum = nextPageNum;
    }


    public List getRecords() {
        return records;
    }


    public void setRecords(List records) {
        this.records = records;
    }


}

分页jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
	<%--分页显示的开始 --%>

<c:if test="${page.totalPageNum>1}">
    	<div style="text-align:center">
    		第${page.currentPageNum}/共${page.totalPageNum}<a href="${pageContext.request.contextPath}/${page.url}&num=1" style="color: #0000cc">首页</a>
    		<a href="${pageContext.request.contextPath}/${page.url}&num=${page.prePageNum }" style="color: #0000cc">上一页</a>
    		<%--显示的页码,使用forEach遍历显示的页面 --%>
    		<c:forEach begin="${page.startPage}" end="${page.endPage}" var="pagenum">
    			<a href="${pageContext.request.contextPath}/${page.url}&num=${pagenum}" style="color: #0000cc">${pagenum}</a>
    		</c:forEach>
    		
    		<a href="${pageContext.request.contextPath}/${page.url}&num=${page.nextPageNum}" style="color: #0000cc">下一页</a>
    		<a href="${pageContext.request.contextPath}/${page.url}&num=${page.totalPageNum}" style="color: #0000cc">末页</a>
    		<input type="text" id="pagenum" name="pagenum" size="1"/><input type="button" value="前往" onclick="jump()" />
    		<script type="text/javascript">
    			function jump(){
    				var totalpage = ${page.totalPageNum};
    				var pagenum = document.getElementById("pagenum").value;
    				//判断输入的是一个数字
    				var reg =/^[1-9][0-9]{0,1}$/;
    				if(!reg.test(pagenum)){
    					//不是一个有效数字
    					alert("请输入符合规定的数字");
    					return ;
    				}
    				//判断输入的数字不能大于总页数
    				if(parseInt(pagenum)>parseInt(totalpage)){
    					//超过了总页数
    					alert("不能大于总页数");
    					return;
    				}
    				//转向分页显示的Servlet
    				window.location.href="${pageContext.request.contextPath}/${page.url}&num="+pagenum;
    			}
    		</script>
    	</div>
</c:if>
    	<%--分页显示的结束--%>

7.嵌套存储数据BeanUtils

String sql="select * from orders where uid=? ORDER BY ordertime DESC limit ?,?";
        //取出该用户所有订单
        List<Order> orderList = runner.query(sql, new BeanListHandler<Order>(Order.class), user.getUid(), startIndex, pageSize);

        //遍历所有订单
        for (Order order:orderList ){
            sql="SELECT * FROM product p,orderitem o WHERE p.pid=o.pid AND o.oid=? ";
            List<Map<String, Object>> mapList = runner.query(sql, new MapListHandler(), order.getOid());
            //每个订单的详情查询遍历
            for (Map<String, Object> map:mapList ){
                OrderItem orderItem=new OrderItem();
                Product product=new Product();
                // 1_创建时间类型的转换器
                DateConverter dt = new DateConverter();
                // 2_设置转换的格式
                dt.setPattern("yyyy-MM-dd");
                // 3_注册转换器
                ConvertUtils.register(dt, java.util.Date.class);
                try {
                    //将查询出的数据填充到对象上
                    BeanUtils.populate(orderItem, map);
                    BeanUtils.populate(product, map);
                    //将商品添加到详情订单对象
                    orderItem.setProduct(product);
                    //再将详情添加到总订单上
                    order.getList().add(orderItem);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }

8.在web.xml设置session过期时间

<session-config>
        <session-timeout>15</session-timeout>
    </session-config>

9.jsp时间显示问题

设置直接显示时间,Value为传入时间,pattern为格式

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
创建时间:<fmt:formatDate value="${v.ordertime}" type="both" pattern="yyyy-MM-dd HH:mm:ss"/>

10.jsp从sql读取double类型后面多一个点问题

Value为传入数字,pattern为格式

<fmt:formatNumber value=" ${ o.total }" pattern="#.00"/>

11.html回退上一页

onclick="history.go(-1)"

12.使用jq或js提交表单无效

检查表单是否有name="submit"的元素,表单里面不能有name="submit"的元素,否则在提交的 时候,该对象会和submit();方法发生混淆造成该submit is not a function错误!!

13.在HTML中设置正则验证,达到限制输入效果。

<input type="text">仅可以输入数字
则添加

oninput = "value=value.replace(/[^\d]/g,'')"

这样即可

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值