分享一些我第一次写商城的东西
注释注释非常重要 它可以帮助你简化思路,还可以帮你减少犯错的几率。
- 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;
}
}
- 数据库
正常连接数据库
//先加载驱动
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位随机字符串
最后是上传商品
需要
-
准备工作
*_Form method=”post”
*_Form
*_Form enctype=”multiprt/form-data” -
利用工具实现上传思路
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上携带的数据存入数据仓库,重定向到查询全部商品信息路径 -
代码
//存储表单中数据 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();
}
}