昨日内容回顾:

  1. 1、项目中用到的技术
  2. 表单:接受用户输入的数据
  3. 两个属性:action:表单提交的路径
  4. method:表单提交的方式
  5. Servlet
  6. @WebServlet("/user")
  7. request.getParameter(name);
  8. dbutils
  9. 作用:在dao层进行增删改查的操作,简化了开发
  10. 使用:
  11. 创建核心对象QueryRunner
  12. 准备sql
  13. 给占位符赋值 Object []
  14. 执行sql
  15. 添加、修改、删除:update 返回值int
  16. 查询:query
  17. 查询多条记录:new BeanListHandler(..)
  18. 查询一条记录:new BeanHandler
  19. 三层思想:
  20. 作用:各自负责自己分工代码的书写
  21. webservicedao
  22. 域对象:存、取、移除数据
  23. 资源跳转方式:
  24. 请求转发
  25. 重定向
  26. EL表达式:
  27. 作用:在jsp里简化从域对象中取数据
  28. 格式:${name}
  29. JSTL标签:
  30. c:if c:forEach
  31. ajax
  32. 核心:局部更新 应用场景
  33. 格式:
  34. $.post(url,{name:value},function(){},"text")

中文乱码问题:

  1. 如果请求方式是post,会发生乱码问题
  • 请求过来时,拿到参数值就乱码了

    1. @WebFilter("/*")
    2. public class EncodingFilter implements Filter {
    3. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    4. //解决请求乱码
    5. request.setCharacterEncoding("utf-8");
    6. //解决响应乱码
    7. response.setContentType("text/html;charset=utf-8");
    8. chain.doFilter(request, response);
    9. }
    10. }
    11. //可以解决所有的请求、响应乱码问题
  • 请求过来时是中文,但保存到数据库里乱码了

    • 查看数据库的编码
    • 修改jdbcUrl的值

1、校验用户名代码完善

UserServlet:

  1. String msg = "";
  2. //判断
  3. if(user == null) {
  4. //用户名不存在 该用户名可用
  5. msg = "true";
  6. }else {
  7. //用户名存在,该用户名不可以使用
  8. msg = "false";
  9. }
  10. //以流的形式将msg响应过去
  11. response.getWriter().write(msg);

register.jsp

  1. $.post(url,data,function(msg){
  2. //选中id为s_username的元素对象
  3. var user = $("#s_username");
  4. //函数体
  5. if(msg == "true"){
  6. //用户名可用,增加内容提
  7. user.html("<font color='green'>用户名可以使用!!</font>");
  8. }else{
  9. //用户名已被占用
  10. user.html("<font color='red'>用户名已被占用,清更换一个!!</font>");
  11. }
  12. })

做项目的思路

  • 目标 (使用什么技术)
  • 思路
    • 鼠标失去焦点执行方法
    • 获取用户的值,提交到服务器
    • 服务器拿到用户名,去和数据库进行校验(三层)
    • 校验后的结果,要么存在该用户,要么不存在,将结果响应过去
    • 拿到结果进行判断
  • 用代码实现(敲多)

2、用户注册

流程图:

Day02笔记 - 图1

问题1:按钮不是submit,如何提交表单数据?

  1. <div class="sign_background_no6" id="btn" onclick="register()" >
  2. 立即注册
  3. </div>
  4. //立即注册,并提交表单
  5. function register(){
  6. //提价表单
  7. $("#f4").submit();
  8. }
  9. <form id="f4" action="/dami/user" method="get">
  10. <input type="hidden" name="method" value="register">

问题2:在Servlet中如何处理不同的功能请求?

注意:以后的请求都要加上method参数名

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. //获取method的参数值
  3. String method = request.getParameter("method");
  4. if("checkUsername".equals(method)) {
  5. //调用校验用户名方法
  6. this.checkUsername(request, response);
  7. }else if("register".equals(method)) {
  8. //调用注册方法
  9. this.register(request, response);
  10. }
  11. }

问题3:如何获取表单数据

原先的方式:

  1. String name = request.getParameter("name");
  2. String sex = request.getParameter("sex");
  3. String username = request.getParameter("username");
  4. String password = request.getParameter("password");
  5. //...
  6. us.register(name,sex,username,password,.);

存在的问题:

  • 当你表单中的参数很多时,光获取参数代码就要写很多行
  • 方法传参时要传很多个参数,容易出现问题

改进的方式:

  1. Map<String, String[]> map = request.getParameterMap();
  2. /*
  3. getParameterMap():获取参数列表中所有的参数名和参数值
  4. String:参数名
  5. String[]:参数值
  6. */
  7. //注册方法
  8. protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  9. try {
  10. //获取表单中的数据
  11. Map<String, String[]> map = request.getParameterMap();
  12. //创建User对象
  13. User user = new User();
  14. //BeanUtils工具类(将map中的数据封装到User对象中)
  15. BeanUtils.populate(user, map);
  16. //调用service层
  17. UserService us = new UserService();
  18. us.register(user);
  19. } catch (IllegalAccessException | InvocationTargetException e) {
  20. // TODO Auto-generated catch block
  21. e.printStackTrace();
  22. }
  23. }

问题4:将数据传到dao层,并注册用户

  1. //调用service层
  2. UserService us = new UserService();
  3. us.register(user);
  4. //Service:
  5. public void register(User user) {
  6. ud.register(user);
  7. }
  8. //Dao:
  9. public void register(User user) {
  10. String sql = "insert into user values(?,?,?,?,?,?,?,?,?,?)";
  11. Object [] params = {null,user.getName(),user.getSex(),user.getPhone_number(),user.getArea(),
  12. user.getManager(),user.getUsername(),user.getPassword(),user.getPhoto(),null};
  13. try {
  14. qr.update(sql, params);
  15. } catch (SQLException e) {
  16. // TODO Auto-generated catch block
  17. e.printStackTrace();
  18. }
  19. }

问题5:注册成功后如何跳转

  1. //Servlet
  2. //跳转到登录页面
  3. response.getWriter().write("<h1>注册成功,3秒后跳转到登录页面!!<h1>");
  4. response.setHeader("refresh", "3;url=/dami/login.jsp");

3、头像上传

IO流文件的复制:

Day02笔记 - 图2

文件上传、下载简略图:

Day02笔记 - 图3

问题1:get和post的区别?

get:提交的数据在地址栏上,提交的数据量有限 (大概最多是2kb左右)

post: 提交的数据在请求体中,一般来说无上限

思考:做文件上传应该采用get还是post?

  1. 使用post方式

文件上传:

浏览器的步骤

  • type的值必须为file
  • 请求方式必须为post
  • 将form的属性enctype的值设置为multipart/form-data

默认提交的数据是键值对的形式:

Day02笔记 - 图4

设置multipart/form-data之后提交的数据形式:以二进制的形式

Day02笔记 - 图5

问题2:multipart/form-data设置之后,在Servlet中根据method获取的值变为null?

  1. 原因就是因为改变了数据的提交形式

服务器端的步骤:

  • 在Servlet上加该注解@MultipartConfig:支持文件上传
    作用:可以获取除了type=file类型的input里的参数名和值

问题3:加上该注解后,根据photo参数名获取的值为null

  • 如果想获取文件的信息,我们要使用
    1. Part part = request.getPart("photo");
    2. //调用write上传到指定的位置
    3. String path = "D:\\xm_upload";
    4. part.write(path+"//"+图片的名称);

问题4:如何获取上传图片的名称?

并上传到指定的地方

  1. //获取图片信息,封装到Part对象
  2. Part part = request.getPart("photo");
  3. //获取上传的图片名称
  4. //Content-Disposition: form-data; name="photo"; filename="wukong.png"
  5. String str = part.getHeader("Content-Disposition");
  6. String filename = str.substring(str.indexOf("filename")+10, str.length()-1);
  7. //调用write上传到指定的位置
  8. String path = "D:\\xm_upload";
  9. part.write(path+"\\"+filename);

问题5:当头像名称相同时,会将之前的头像给覆盖了

  1. public class UUIDUtils {
  2. public static String getUUID() {
  3. return UUID.randomUUID().toString().replaceAll("-", "");
  4. }
  5. }
  6. filename = UUIDUtils.getUUID()+filename;

问题6:如何通过服务器访问到指定上传图片位置的图片?

双击tomcat—-》选中Modules

Day02笔记 - 图6

Day02笔记 - 图7

问题7:user表中的photo字段存什么值呢?

  1. filename就可以
  1. //设置photo属性值
  2. user.setPhoto(filename);

4、手机验证码登录

4.1 向手机发送验证码

思路分析:

Day02笔记 - 图8

代码实现:

login.jsp

  1. <input onclick="sendCode()" id="zphone" type="button" value=" 获取手机验证码 " style="width: 138px;float: left;height: 53px;margin-left: 5px;">
  2. //发送验证码
  3. function sendCode(){
  4. //获取输入手机号的值
  5. var val = $("#phone_number").val();
  6. $.post("/dami/user",{method:"sendCode","phoneNumber":val},function(){
  7. })
  8. RemainTime();
  9. }

Servlet:

注意:不要忘了加if else判断

  1. //发送验证码
  2. protected void sendCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. //获取手机号
  4. String phoneNumber = request.getParameter("phoneNumber");
  5. //真实环境中 调用阿里云相关的api
  6. //Ali.sendCode(phoneNumber);
  7. //模拟环境
  8. String code = RandomUtils.getFourRandom();
  9. System.out.println("您收到的验证码为:"+code+",五分钟内有效,千万不要泄露喔!!!");
  10. }

4.2 手机验证码登录

login.jsp

  1. <span id="sub" onclick="login()">登录</span>
  2. function login(){
  3. //获取输入手机号的值
  4. var val = $("#phone_number").val();
  5. //获取输入验证码的值
  6. var code = $("#code").val();
  7. //向服务器传递数据
  8. $.post("/dami/user",{"method":"login","phoneNumber":val,"code":code},function(msg){
  9. if(msg == "0"){
  10. $("#msg").html("该手机号尚未注册,请先去注册");
  11. }else if(msg =="2"){
  12. $("#msg").html("验证码输入错误")
  13. }else if(msg == "1"){
  14. alert("登录成功!!!!");
  15. }
  16. })
  17. }

Servlet:

  1. //登录
  2. protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. //获取手机号
  4. String phoneNumber = request.getParameter("phoneNumber");
  5. //获取验证码
  6. String code = request.getParameter("code");
  7. //1、判断手机号是否注册
  8. UserService us = new UserService();
  9. User user = us.checkPhoneNumber(phoneNumber);
  10. String msg = "";
  11. if(user != null) {
  12. //手机号已经存在 可以登录
  13. //判断验证码是否正确
  14. String sessionCode = (String) request.getSession().getAttribute("code");
  15. if((phoneNumber + code).equals(sessionCode)) {
  16. //验证码正确
  17. msg = "1";
  18. }else {
  19. //验证码错误
  20. msg = "2";
  21. }
  22. }else {
  23. //手机不存在 不能登录
  24. msg = "0";
  25. }
  26. response.getWriter().write(msg);
  27. }

注意:需要同时在sendCode中加以下的代码:

  1. request.getSession().setAttribute("code", phoneNumber+code);

Service:

  1. public User checkPhoneNumber(String phoneNumber) {
  2. // TODO Auto-generated method stub
  3. return ud.checkPhoneNumber(phoneNumber);
  4. }

Dao:

  1. public User checkPhoneNumber(String phoneNumber) {
  2. //1、准备sql
  3. String sql = "SELECT * FROM USER WHERE phone_number = ?";
  4. //2、给占位符复制
  5. Object [] param = {phoneNumber};
  6. //3、执行sql
  7. try {
  8. User user = qr.query(sql, new BeanHandler<User>(User.class),param);
  9. return user;
  10. } catch (SQLException e) {
  11. // TODO Auto-generated catch block
  12. e.printStackTrace();
  13. }
  14. return null;
  15. }

5、后台管理员系统

将资料中的admin目录拷贝到项目的WebContent中

需求:

1、管理员登录

  1. 根据用户名和密码进行登录
  2. 登录成功后:跳转到/admin/main.jsp 需要将用户信息存到session域对象中
  3. index.jsp页面 显示wukong,欢迎您 提示:使用EL表达式

2、管理员退出

3、点击用户管理,查询所有用户

  1. 跳转到user_list.jsp 取出用户的数据进行展示

作业:

1、第一天的两个案例

2、将小米商城的代码独自完成