简单商城分享

分享一些我第一次写商城的东西
注释注释非常重要 它可以帮助你简化思路,还可以帮你减少犯错的几率。

  1. BaseServlet
public class BaseServlet extends HttpServlet{
public void service(HttpServletRequest req, HttpServletResponse resp) thorws ServletException,IOException{
//因为新建的servlet都要继承这个baseservlet要先执行service 所以这里重写了service方法
//通过接受从外面传来的method来判断并确定执行什么样的方法
String method = req.getParameter("method");
//判断传来的method是否为空如果为空就执行execute方法
if (null==method || "".equals(method) ||method.trim().equals("")){
method="execute";
}
//这里的this指的是要继承他的那个类的对象
Class claszz = this.getClass();
// 查找子类对象对应的字节码中的名称为method的方法.这个方法的参数类型是:HttpServletRequest.class,HttpServletResponse.class
 Method md = clazz.getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
 if(null!=md){
 String jspPath = (String) md.invoke(this, req, resp);
 if (null != jspPath) {
 req.getRequestDispatcher(jspPath).forward(req, resp);
 }
 }
}
public String execute(HttpServletRequest req, HttpServletResponse resp) throws Exception {
return null;
}
}
  1. 数据库
    正常连接数据库
//先加载驱动
Class.forName("com.mysql.jdbc.driver");
//获得数据库连接
Connection conn =DriverManager.getConnection("路径","用户名","密码");
//通过数据库的连接来操作数据库
String sql = "select * from Student where id=?";
PrepareStatement ps = conn.prepareStatement(sql);
st.setString(第几个问号,要操作的数据);
//通过resultSet来接受返回的结果集
ResuletSet rs = ps.excuteQuery();
接下来操作数据

我的C3P0是通过配置xml的方式

<property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost/store_40</property>
    <property name="user">root</property>
    <property name="password">123456</property>

我的项目是通过c3p0方式和一个JDBCUtil获得数据库连接池

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
把每一个连接都放在一个线程中通过dbutil来操作数据
QueryRunner qr= new QueryRunner(JDBCUtil.getDateSource);
String sql = “select * from product”;
qr.query(sql,new BeanListHandler(Product.class));

分页

我的分页是通过一个jsp页面再加上一个Pagemodel的封装类完成的,jsp页面主要用来完成下面的页数与点击页面的跳转而Pagemodel则是传入三个参数1.要跳转的页面 2.总的记录条数(这个是要通过数据库获取的数据)3.每个页面所要显示的条数(这个是自己手动输入的)这个过程发现了一个转换。new ScalarHandler()返回的是object类型,必须先把object转化成其他类型,例如Long,String然后再转化为int类型。

  • jsp页面
    在这里插入图片描述

  • 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 list;//已经分好页的结果集,该list中只有10条记录
    //扩展属性
    //一共每页显示9个页码按钮
    private int startPage;//开始页码
    private int endPage;//结束页码
    //完善属性
    private String url;
    //一个构造方法把所有的相关数据计算出来,需要三个参数,当前页,总条数,每页条数。
    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 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;
    }

    比较难解决的一个点就是查询所有订单并且分页

    1 在dao层中先查询其中一页的订单
    2 遍历这个订单,把订单项orderItem和商品product编号相同的数据存到new MapListHandler();之中
    3 遍历这个list集合 然后new一个product对象和一个orderitem对象,把里面的数据通过一个BeanUtils的工具类自动填充到相应的类里面
    4 把product对象存到orderitem购物项中,再把orderItem存到order的list集合之中然后返回这个集合。
    5 通过jsp中EL和JSTL把数据展现到页面上

    工具类BeanUtils

    BeanUtils.populate(a,map);方法把map中有的数据填充到a上。
    在这里插入图片描述

    一般字符串与日期之间的转换

    String str = “1996-11-15”;
    String st;
    Date da;
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd”);
    //字符串转换成日期
    da = sdf.parse(str);
    //日期转换成字符串
    st = sdf.format(date);

    我使用的时间类型的转换器

    // 1_创建时间类型的转换器
    DateConverter dt = new DateConverter();
    // 2_设置转换的格式
    dt.setPattern(“yyyy-MM-dd”);
    // 3_注册转换器
    ConvertUtils.register(dt, java.util.Date.class);

    首页分类使用了JQ的post方法与redis缓存

    首先创建了一个公共页面header.jsp页面使用Ajax去跳转到Servlet然后获取分类的数据存放在redis中.

  • Jsp页面

  • $(function(){
    //向服务端CategoryServlet__>gteAllCats发起ajax请求,服务端经过处理,
    //将所有分类信息以JSON格式的数据返回,获取到返回的所有分类绑定在页面的显示分类区域
    var url="/store_v5/CategoryServlet";
    var obj={“method”:“findAllCats”};
    $.post(url,obj,function(data){
    //alert(data);

     //获取到服务端响应会的数据,经过观察data中存放的是一个JSON格式数组,遍历数组,动态的显示分类区域代码	
     $.each(data,function(i,obj){
     	var li="<li><a href='/store_v5/ProductServlet?method=findProductsByCidWithPage&num=1&cid="+obj.cid+"'>"+obj.cname+"</a></li>";
     	//把数据动态添加到上面。
     	$("#myUL").append(li);
     });
    

    },“json”);

});
Servlet中redis内容
Jedis jedis=JedisUtils.getJedis();
String jsonStr=jedis.get(“allCats”);
if(null==jsonStr||"".equals(jsonStr)){
//调用业务层获取全部分类
CategoryService CategoryService=new CategoryServiceImp();
List list = CategoryService.getAllCats();
//将全部分类转换为JSON格式的数据
jsonStr=JSONArray.fromObject(list).toString();
System.out.println(jsonStr);
//将获取到的JSON格式的数据存入redis
jedis.set(“allCats”, jsonStr);
System.out.println(“redis缓存中没有数据”);
//将全部分类信息响应到客户端
//告诉浏览器本次响应的数据是JSON格式的字符串
resp.setContentType(“application/json;charset=utf-8”);
resp.getWriter().print(jsonStr);
}else{
System.out.println(“redis缓存中有数据”);

		//将全部分类信息响应到客户端
		//告诉浏览器本次响应的数据是JSON格式的字符串
		resp.setContentType("application/json;charset=utf-8");
		resp.getWriter().print(jsonStr);
	}
	
	JedisUtils.closeJedis(jedis);

使用了一个JedisUtils工具类

private static JedisPoolConfig config;
private static JedisPool pool;

static{
	config=new JedisPoolConfig();
	config.setMaxTotal(30);
	config.setMaxIdle(2);
	//连接本地的ip地址及端口号
	pool=new JedisPool(config, "192.168.195.132", 6379);
}
//获取连接的方法
public static Jedis getJedis(){
	return pool.getResource();
}
//释放连接
public static void closeJedis(Jedis j){
	j.close();
}

随机生成订单编号用了UUidUtils工具类

public static String getId() {
	return UUID.randomUUID().toString().replace("-", "").toUpperCase();
}

通过这个方法生成32位随机字符串

最后是上传商品

需要

  1. 准备工作
    *_Form method=”post”
    *_Form
    *_Form enctype=”multiprt/form-data”

  2. 利用工具实现上传思路
    1_导入commons-fileupload-1.2.1.rar之后
    2_执行很简单的3行语句
    3_获取到一个集合(对象)
    将每对分割线中间的内容封装在FileItem对象上.
    4_遍历集合
    5_如果当前的FileItem对象是普通项
    将普通项上name属性的值作为键,将获取到的内容作为值,放入MAP中
    {username<>tom,password<>1234}
    6_如果当前的FileItem对象是上传项
    通过FileItem获取到输入流对象,通过输入流可以获取到图片二进制数据
    在服务端创建一个空文件(后缀必须和上传到服务端的文件名后缀一致)
    建立和空文件对应的输出流
    将输入流中的数据刷到输出流中
    释放资源
    向map中存入一个键值对的数据 userhead<=> /image/11.bmp
    {username<
    >tom,password<>1234,userhead<=>image/11.bmp}
    7_利用BeanUtils将MAP中的数据填充到user对象上
    8_调用servcie_dao将user上携带的数据存入数据仓库,重定向到查询全部商品信息路径

  3. 代码

    			 //存储表单中数据
    Map<String,String> map=new HashMap<String,String>();
    //携带表单中的数据向servcie,dao
    Product product=new Product();
    try {
    	//利用req.getInputStream();获取到请求体中全部数据,进行拆分和封装
    	DiskFileItemFactory fac=new DiskFileItemFactory();
    	ServletFileUpload upload=new ServletFileUpload(fac);
    	List<FileItem> list=upload.parseRequest(req);
    	//4_遍历集合
    	for (FileItem item : list) {
    		if(item.isFormField()){
    			//5_如果当前的FileItem对象是普通项
    			//将普通项上name属性的值作为键,将获取到的内容作为值,放入MAP中
    			// {username<==>tom,password<==>1234}
    			map.put(item.getFieldName(), item.getString("utf-8"));
    		}else{
    			//6_如果当前的FileItem对象是上传项
    			//获取到原始的文件名称
    			String oldFileName=item.getName();
    			//获取到要保存文件的名称   1222.doc  123421342143214.doc
    			String newFileName=UploadUtils.getUUIDName(oldFileName);
    			
    			//通过FileItem获取到输入流对象,通过输入流可以获取到图片二进制数据
    			InputStream is=item.getInputStream();
    			//获取到当前项目下products/3下的真实路径
    			//D:\tomcat\tomcat71_sz07\webapps\store_v5\products\3
    			String realPath=getServletContext().getRealPath("/products/3/");
    			String dir=UploadUtils.getDir(newFileName); // /f/e/d/c/4/9/8/4
    			String path=realPath+dir; //D:\tomcat\tomcat71_sz07\webapps\store_v5\products\3/f/e/d/c/4/9/8/4
    			//内存中声明一个目录
    			File newDir=new File(path);
    			if(!newDir.exists()){
    				newDir.mkdirs();
    			}
    			//在服务端创建一个空文件(后缀必须和上传到服务端的文件名后缀一致)
    			File finalFile=new File(newDir,newFileName);
    			if(!finalFile.exists()){
    				finalFile.createNewFile();
    			}
    			//建立和空文件对应的输出流
    			OutputStream os=new FileOutputStream(finalFile);
    			//将输入流中的数据刷到输出流中
    			IOUtils.copy(is, os);
    			//释放资源
    			IOUtils.closeQuietly(is);
    			IOUtils.closeQuietly(os);
    			//向map中存入一个键值对的数据 userhead<===> /image/11.bmp
    			// {username<==>tom,password<==>1234,userhead<===>image/11.bmp}
    			map.put("pimage", "/products/3/"+dir+"/"+newFileName);
    		}
    

使用了UploadUtils工具类
这个工具类还不太明白先放到这里

public class UploadUtils {
/**
 * 获取随机名称
 * @param realName 真实名称
 * @return uuid
 */
public static String getUUIDName(String realName){
	//realname  可能是  1.jpg   也可能是  1
	//获取后缀名
	int index = realName.lastIndexOf(".");
	if(index==-1){
		return UUID.randomUUID().toString().replace("-", "").toUpperCase();
	}else{
		return UUIDUtils.getId()+realName.substring(index);
	}
}
/**
 * 获取文件真实名称
 * @param name
 * @return
 */
public static String getRealName(String name){
	// c:/upload/1.jpg    1.jpg
	//获取最后一个"/"
	int index = name.lastIndexOf("\\");
	return name.substring(index+1);
}

/**
 * 获取文件目录
 * @param name 文件名称
 * @return 目录
 */
public static String getDir(String name){
	//任意一个对象都有一个hash码   131313213
	int i = name.hashCode();
	//将hash码转成16禁止的字符串
	String hex = Integer.toHexString(i);
	System.out.println(hex);
	int j=hex.length();
	for(int k=0;k<8-j;k++){
		hex="0"+hex;
	}
	return "/"+hex.charAt(0)+"/"+hex.charAt(1)+"/"+hex.charAt(2)+"/"+hex.charAt(3)+"/"+hex.charAt(4)+"/"+hex.charAt(5)+"/"+hex.charAt(6)+"/"+hex.charAt(7);
}

@SuppressWarnings("unused")
public static void main(String[] args) {
	//String s="G:\\day17-基础加强\\resource\\1.jpg";
	//String s="1.jgp";
	//String realName = getRealName(s);
	//System.out.println(realName);
	
	//String uuidName = getUUIDName(realName);
	//System.out.println(uuidName);
	
	String dir = getDir("ASDFSADF");
	// /b/b/5/6/3/b/a/1/  234234.jpg
	// /f/e/d/c/4/9/8/4/  2341242314321.bmp
	System.out.println(dir);
	
	
	
}

}
为了保证数据正常要提前加上过滤器

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	HttpServletRequest myreq = (HttpServletRequest)request;
	User user = (User)myreq.getSession().getAttribute("user");
	if(user!=null){
		chain.doFilter(request, response);
	}else{
		myreq.setAttribute("msg", "请先登陆");
		myreq.getRequestDispatcher("/jsp/login.jsp").forward(request, response);
	}
}

设置限制的路径

<filter>
    <display-name>PriviledgeFilter</display-name>
    <filter-name>PriviledgeFilter</filter-name>
    <filter-class>store.web.fitler.PriviledgeFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>PriviledgeFilter</filter-name>
    <url-pattern>/jsp/cart.jsp</url-pattern>
    <url-pattern>/jsp/order_info.jsp</url-pattern>
    <url-pattern>/jsp/order_list.jsp</url-pattern>
  </filter-mapping>

EncodingFilter咱不知道作用的一个过滤器
public class EncodingFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
	// TODO Auto-generated method stub

}

@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
	//1.强转
	HttpServletRequest request=(HttpServletRequest) req;
	HttpServletResponse response=(HttpServletResponse) resp;
	//System.out.println("@@@@@@@@@@@@@@@@@@");		
	//2.放行
	chain.doFilter(new MyRequest(request), response);
}

@Override
public void destroy() {
	// TODO Auto-generated method stub

}

}

//之前的MyRequest增强了request.getParameter(“name”);方法
//增强了所有的获取参数的方法request.getParameterValues(“name”);
//增强了所有的获取参数的方法request.getParameterMap();
class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
private boolean flag=true;

public MyRequest(HttpServletRequest request) {
	super(request);
	this.request=request;
}

@Override
public String getParameter(String name) {  
	if(name==null || name.trim().length()==0){
		return null;
	}
	String[] values = getParameterValues(name);
	if(values==null || values.length==0){
		return null;
	}
	
	return values[0];
}

@Override
/**
 * hobby=[eat,drink]
 */
public String[] getParameterValues(String name) {
	if(name==null || name.trim().length()==0){
		return null;
	}
	Map<String, String[]> map = getParameterMap();
	if(map==null || map.size()==0){
		return null;
	}
	
	return map.get(name);
}

@Override
/**
 * map{ username=[tom],password=[123],hobby=[eat,drink]}
 */
public Map<String,String[]> getParameterMap() {  
	
	/**
	 * 首先判断请求方式
	 * 若为post  request.setchar...(utf-8)
	 * 若为get 将map中的值遍历编码就可以了
	 */
	String method = request.getMethod();
	if("post".equalsIgnoreCase(method)){
		try {
			request.setCharacterEncoding("utf-8");
			return request.getParameterMap();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}else if("get".equalsIgnoreCase(method)){
		Map<String,String[]> map = request.getParameterMap();
		if(flag){
			for (String key:map.keySet()) {
				String[] arr = map.get(key);
				//继续遍历数组
				for(int i=0;i<arr.length;i++){
					//编码
					try {
						arr[i]=new String(arr[i].getBytes("iso-8859-1"),"utf-8");
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
				}
			}
			flag=false;
		}
		//需要遍历map 修改value的每一个数据的编码
		
		return map;
	}
	
	return super.getParameterMap();
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值