黑马旅游网项目总结及常见问题解析

黑马旅游网项目总结

简述

  • 本项目在静态页面基础上,利用html+servlet进行编写,利用JDBC的druid数据池操作管理mysql数据库调用编写数据,采用redis进行缓存优化,使用MVC模式完成客户端的开发,其中Controller模块为servlet,View模块为html展示数据,Model模块为JavaBean完成业务逻辑操作,利用Maven进行项目的开发及管理。
  • 客户端网页使用html调用Ajax请求与后端完成交互,接收处理后台服务器返回的json数据,服务器构建为servlet-service-Dao操作模块。
  • 本项目分为注册登陆模块、线路模块、收藏模块,各个环节可运行成功,并不断完善相关细节。

准备工作

  • 导入其Maven构造的项目包其中包括相关静态网页,准备好的图片,及其在Maven项目包中导入的相关的jar包,若未对ideal进行Maven的project包进行配置,请参考Maven基础配置完成该环节,需在pom.xml配置所需要jar包,需要注意的是本项目调用的端口应当为未被占用过的端口,本项目设置tomcat7版本的插件,端口为8088,若设置已占用的端口,会报异常;
 <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <!-- tomcat7的插件, 不同tomcat版本这个也不一样 -->
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <port>8088</port>
                    <path>/travel</path>
                </configuration>
            </plugin>
  • 项目采取如下构建,创建相关Package黑马旅游网项目总结及常见问题解析_第1张图片
  • 为避免过多的servlet,设置BaseServlet 类继承了HttpServlet,将一个功能一个servlet类对象替换为一个表实现一个servlet类对象,新的servlet类继承BaseServlet类,BaseServlet类中用反射调用其子类对象的方法,BaseServle类及其子类的web路径配置如下所示:
public class BaseServlet extends HttpServlet {
     
    @Override
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
        //输出 会报错 配置Runner部分
        //System.out.println("BaseServlet的service方法执行了");
        //完成方法的分发 路径add拿到 获取方法对象 同过反射执行该方法
        //1.获取请求路径
        String uri = req.getRequestURI();  // /travel/user/add
        //2.获取方法名称
        String method = uri.substring(uri.lastIndexOf('/') + 1);//截取方法名称---add
        //3.获取方法对象Method
       //这里的this是谁调用 我是谁---这里是userServlet的对象
        //利用反射调用
        try {
     
            Method Method = this.getClass().getDeclaredMethod(method, HttpServletRequest.class, HttpServletResponse.class);
            Method.setAccessible(true);
            //4.执行方法
            Method.invoke(this,req,resp);
        } catch (NoSuchMethodException e) {
     
            e.printStackTrace();
        } catch (IllegalAccessException e) {
     
            e.printStackTrace();
        } catch (InvocationTargetException e) {
     
            e.printStackTrace();
        }
    }
	//子类注释
	@WebServlet("/user/*")//类似于/user/find  /user/add 都可实现

登陆模块

  • 模块完成了:注册功能(包含邮箱激活功能)、登录功能、返回姓名功能、退出功能

注册功能

  • 前端工作:利用js中的正则表达式完成对输入格式的校验工作,并利用Ajax完成异步传输,传输时会采用表单的序列化操作。
  • 服务器操作:接收前端传输的表格数据,通过request.getParameterMap()获取后,利用BeanUtils封装表单的数据,判断验证码是否正确,输入验证码正确则判断该用户是否存在,不存在添加该用户,反之返回错误信息,返回采用json数据格式。
注意
  • 前端操作采用正则化操作如下
				let name = $("#name").val();
				let reg_name = /^\w+$/;
				let boolean = reg_name.test(name);
  • 正则化验证 注意 这里不能是checkUsername(),应该为方法名称,JS中方法对象简述
				$("#username").blur(checkUsername);
  • 在返回验证码错误信息时,用return结束此次Ajax请求,否则用户密码错误不会返回错误信息。
  • 在操作数据库根据条件(姓名)查询返回user对象时,避免报错,应该加入try…catch判断,避免条件出错时出现异常。
	try {
     
        favoriteRanks = template.query(sql,new BeanPropertyRowMapper<favoriteRank>(favoriteRank.class),start,pageSize);
        }catch (Exception e){
     

        }
  • 为了推广软件,会在注册部分使用service操作判断邮箱是否激活,需要根据UuidUtils数据类产生唯一uid,利用MailUtils工具类传输,需设置发送邮箱,及其pom激活码,且只有目的邮箱为163时,发生跳转登陆操作,激活标记改为‘Y’,qq邮箱出现跳转失败现象。

登陆功能

  • 前端工作:利用Ajax完成异步传输,传输时采用表单的序列化操作。
				$("#registerForm").submit(function () {
     
						// 发送异步请求 serialize()序列化表单中的内容
						$.post("/travel/user/registerUser",$(this).serialize(),function (data) {
     
							if (data.flag){
     
								//没有该信息
								location.href="register_ok.html"
							}else {
     
								//已经存在该信息
								$("#msg").html(data.errorMsg);
							}
						},"json")
					}
  • 服务器操作:接收前端传输的表格数据,通过request.getParameterMap()获取后,利用BeanUtils封装表单的数据,需要判断验证码是否正确,判断该用户是否存在,判断密码是否正确,判断激活码是否为‘Y’,不存在返回错误信息,返回采用json数据格式。
注意
  • 在登陆页面时 需要设置session存储user对象的数据,在后续模块判断用户是否登陆时 需要调用该session属性进行判断。

返回姓名与退出功能

  • 主要是完成对前端页面的优化。
  • 前端工作:利用Ajax完成异步传输,实现姓名返回与退出功能。
  • 服务器操作:退出功能的实现即销毁对应session中存储的user对象,返回姓名功能,读取session中存储的user对象的姓名。
注意
  • 出现后端调试成功,前端无法显示登陆者姓名信息,猜想为浏览器缓存导致,使用另一浏览器返回姓名成功。

线路模块

  • 模块完成了导航栏部分、线路查询功能、线路详情功能、线路收藏功能。

导航栏配置

  • 该模块完成了Header.html中导航栏部分,对于常用的数据,可存储到redis中,方便加载。
  • 前端工作:启动服务器,处理返回信息
  $.post("/travel/category/findAllName",{
     },function (data) {
     
            var lis = '';
            for (var i=0;i<data.length;i++){
     
                lis += '';
            }
            lis += '
  • 收藏排行榜
  • '
    ; //进行添加 $("#cat_li").html(lis); });
    • 服务器操作:启动服务器,使用JedisUtil创建Jedis连接池,连接redis服务器,判断reids缓存中是否存在Category对象,若存在进行增删改查工作的完成,不存在时调用Dao方法存储Category对象。
    注意
    • 该环节需要调用redis数据库,启动项目时注意手动打开redis客户端
    • 该环节进行操作时,需要有序操作,故使用sorted数据类型,调用含score的redis对象操作。

    线路查询

    • 该模块使用分页查询完成线路信息的展示,
    • 客户端传递当前页面currentPage、当前种类id值cid、查询字符rname,对返回PageBean对象进行处理完成前端操作
    • 服务器处理接收的currentPage、cid、rname数据,并调用相关service操作,设置PageBean对象中每页查询个数、当前页数、总个数、总页数、根据cid start pageSize rname获取的路线信息
    • 在完成Dao层操作时,根据不同参数的传递信息(即不同的前端信息传输),进行不同的字符拼接操作
            List params = new ArrayList();
            StringBuilder sb = new StringBuilder(sql);
            if (cid>0){
         
                sb.append(" and cid = ?");
                params.add(cid);
            }
            if (rname!=null&&rname.length()>0){
         
                sb.append(" and rname like ?");
                params.add("%"+rname+"%");
            }
            sql = sb.toString();
    
    注意
    • 前端处理服务器传输对象时会将不需要跳转的超链接标签加上如下操作
    <a href="javascript:void(0)">
    
    • 页面加载中调用function函数的定位问题,需定义在${}
    • 在进行前端操作时,进行优化分页页码的操作,使每一页的分页页码都为10条
    • 后端服务器Dao操作处理时,template.query方法返回为List对象,template.queryForObject方法返回为int类型/User类型对象

    详细信息查询

    • 在存储路线信息时,在图片与名称部位增添超链接,并传递该路线的rid值,进行跳转操作
    • 前端向服务器传递该线路的rid信息,服务器在service层进行操作,通过rid获取对应route对象,通过route对象中的sid获得其售卖seller对象,再根据rid获取其图片对象,最终将获取的信息存储到route对象中。

    你可能感兴趣的:(Java,java,javascript,html,mysql,redis)