昨日内容回顾:
1、项目中用到的技术表单:接受用户输入的数据两个属性:action:表单提交的路径method:表单提交的方式Servlet:@WebServlet("/user")request.getParameter(name);dbutils:作用:在dao层进行增删改查的操作,简化了开发使用:创建核心对象QueryRunner准备sql ?给占位符赋值 Object []执行sql:添加、修改、删除:update 返回值int查询:query查询多条记录:new BeanListHandler(..)查询一条记录:new BeanHandler三层思想:作用:各自负责自己分工代码的书写web、service、dao域对象:存、取、移除数据资源跳转方式:请求转发重定向EL表达式:作用:在jsp里简化从域对象中取数据格式:${name}JSTL标签:c:if c:forEachajax:核心:局部更新 应用场景格式:$.post(url,{name:value},function(){},"text")
中文乱码问题:
如果请求方式是post,会发生乱码问题
请求过来时,拿到参数值就乱码了
@WebFilter("/*")public class EncodingFilter implements Filter {public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {//解决请求乱码request.setCharacterEncoding("utf-8");//解决响应乱码response.setContentType("text/html;charset=utf-8");chain.doFilter(request, response);}}//可以解决所有的请求、响应乱码问题
请求过来时是中文,但保存到数据库里乱码了
- 查看数据库的编码
- 修改jdbcUrl的值
1、校验用户名代码完善
UserServlet:
String msg = "";//判断if(user == null) {//用户名不存在 该用户名可用msg = "true";}else {//用户名存在,该用户名不可以使用msg = "false";}//以流的形式将msg响应过去response.getWriter().write(msg);
register.jsp
$.post(url,data,function(msg){//选中id为s_username的元素对象var user = $("#s_username");//函数体if(msg == "true"){//用户名可用,增加内容提user.html("<font color='green'>用户名可以使用!!</font>");}else{//用户名已被占用user.html("<font color='red'>用户名已被占用,清更换一个!!</font>");}})
做项目的思路
- 目标 (使用什么技术)
- 思路
- 鼠标失去焦点执行方法
- 获取用户的值,提交到服务器
- 服务器拿到用户名,去和数据库进行校验(三层)
- 校验后的结果,要么存在该用户,要么不存在,将结果响应过去
- 拿到结果进行判断
- 用代码实现(敲多)
2、用户注册
流程图:

问题1:按钮不是submit,如何提交表单数据?
<div class="sign_background_no6" id="btn" onclick="register()" >立即注册</div>//立即注册,并提交表单function register(){//提价表单$("#f4").submit();}<form id="f4" action="/dami/user" method="get"><input type="hidden" name="method" value="register">
问题2:在Servlet中如何处理不同的功能请求?
注意:以后的请求都要加上method参数名
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取method的参数值String method = request.getParameter("method");if("checkUsername".equals(method)) {//调用校验用户名方法this.checkUsername(request, response);}else if("register".equals(method)) {//调用注册方法this.register(request, response);}}
问题3:如何获取表单数据
原先的方式:
String name = request.getParameter("name");String sex = request.getParameter("sex");String username = request.getParameter("username");String password = request.getParameter("password");//...us.register(name,sex,username,password,.);
存在的问题:
- 当你表单中的参数很多时,光获取参数代码就要写很多行
- 方法传参时要传很多个参数,容易出现问题
改进的方式:
Map<String, String[]> map = request.getParameterMap();/*getParameterMap():获取参数列表中所有的参数名和参数值String:参数名String[]:参数值*///注册方法protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try {//获取表单中的数据Map<String, String[]> map = request.getParameterMap();//创建User对象User user = new User();//BeanUtils工具类(将map中的数据封装到User对象中)BeanUtils.populate(user, map);//调用service层UserService us = new UserService();us.register(user);} catch (IllegalAccessException | InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
问题4:将数据传到dao层,并注册用户
//调用service层UserService us = new UserService();us.register(user);//Service:public void register(User user) {ud.register(user);}//Dao:public void register(User user) {String sql = "insert into user values(?,?,?,?,?,?,?,?,?,?)";Object [] params = {null,user.getName(),user.getSex(),user.getPhone_number(),user.getArea(),user.getManager(),user.getUsername(),user.getPassword(),user.getPhoto(),null};try {qr.update(sql, params);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
问题5:注册成功后如何跳转
//Servlet//跳转到登录页面response.getWriter().write("<h1>注册成功,3秒后跳转到登录页面!!<h1>");response.setHeader("refresh", "3;url=/dami/login.jsp");
3、头像上传
IO流文件的复制:

文件上传、下载简略图:

问题1:get和post的区别?
get:提交的数据在地址栏上,提交的数据量有限 (大概最多是2kb左右)
post: 提交的数据在请求体中,一般来说无上限
思考:做文件上传应该采用get还是post?
使用post方式
文件上传:
浏览器的步骤:
- type的值必须为file
- 请求方式必须为post
- 将form的属性enctype的值设置为multipart/form-data
默认提交的数据是键值对的形式:

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

问题2:multipart/form-data设置之后,在Servlet中根据method获取的值变为null?
原因就是因为改变了数据的提交形式
服务器端的步骤:
- 在Servlet上加该注解@MultipartConfig:支持文件上传
作用:可以获取除了type=file类型的input里的参数名和值
问题3:加上该注解后,根据photo参数名获取的值为null
- 如果想获取文件的信息,我们要使用
Part part = request.getPart("photo");//调用write上传到指定的位置String path = "D:\\xm_upload";part.write(path+"//"+图片的名称);
问题4:如何获取上传图片的名称?
并上传到指定的地方
//获取图片信息,封装到Part对象Part part = request.getPart("photo");//获取上传的图片名称//Content-Disposition: form-data; name="photo"; filename="wukong.png"String str = part.getHeader("Content-Disposition");String filename = str.substring(str.indexOf("filename")+10, str.length()-1);//调用write上传到指定的位置String path = "D:\\xm_upload";part.write(path+"\\"+filename);
问题5:当头像名称相同时,会将之前的头像给覆盖了
public class UUIDUtils {public static String getUUID() {return UUID.randomUUID().toString().replaceAll("-", "");}}filename = UUIDUtils.getUUID()+filename;
问题6:如何通过服务器访问到指定上传图片位置的图片?
双击tomcat—-》选中Modules


问题7:user表中的photo字段存什么值呢?
存filename就可以
//设置photo属性值user.setPhoto(filename);
4、手机验证码登录
4.1 向手机发送验证码
思路分析:

代码实现:
login.jsp
<input onclick="sendCode()" id="zphone" type="button" value=" 获取手机验证码 " style="width: 138px;float: left;height: 53px;margin-left: 5px;">//发送验证码function sendCode(){//获取输入手机号的值var val = $("#phone_number").val();$.post("/dami/user",{method:"sendCode","phoneNumber":val},function(){})RemainTime();}
Servlet:
注意:不要忘了加if else判断
//发送验证码protected void sendCode(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取手机号String phoneNumber = request.getParameter("phoneNumber");//真实环境中 调用阿里云相关的api//Ali.sendCode(phoneNumber);//模拟环境String code = RandomUtils.getFourRandom();System.out.println("您收到的验证码为:"+code+",五分钟内有效,千万不要泄露喔!!!");}
4.2 手机验证码登录
login.jsp
<span id="sub" onclick="login()">登录</span>function login(){//获取输入手机号的值var val = $("#phone_number").val();//获取输入验证码的值var code = $("#code").val();//向服务器传递数据$.post("/dami/user",{"method":"login","phoneNumber":val,"code":code},function(msg){if(msg == "0"){$("#msg").html("该手机号尚未注册,请先去注册");}else if(msg =="2"){$("#msg").html("验证码输入错误")}else if(msg == "1"){alert("登录成功!!!!");}})}
Servlet:
//登录protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取手机号String phoneNumber = request.getParameter("phoneNumber");//获取验证码String code = request.getParameter("code");//1、判断手机号是否注册UserService us = new UserService();User user = us.checkPhoneNumber(phoneNumber);String msg = "";if(user != null) {//手机号已经存在 可以登录//判断验证码是否正确String sessionCode = (String) request.getSession().getAttribute("code");if((phoneNumber + code).equals(sessionCode)) {//验证码正确msg = "1";}else {//验证码错误msg = "2";}}else {//手机不存在 不能登录msg = "0";}response.getWriter().write(msg);}
注意:需要同时在sendCode中加以下的代码:
request.getSession().setAttribute("code", phoneNumber+code);
Service:
public User checkPhoneNumber(String phoneNumber) {// TODO Auto-generated method stubreturn ud.checkPhoneNumber(phoneNumber);}
Dao:
public User checkPhoneNumber(String phoneNumber) {//1、准备sqlString sql = "SELECT * FROM USER WHERE phone_number = ?";//2、给占位符复制Object [] param = {phoneNumber};//3、执行sqltry {User user = qr.query(sql, new BeanHandler<User>(User.class),param);return user;} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}
5、后台管理员系统
将资料中的admin目录拷贝到项目的WebContent中
需求:
1、管理员登录
根据用户名和密码进行登录登录成功后:跳转到/admin/main.jsp 需要将用户信息存到session域对象中在index.jsp页面 显示wukong,欢迎您 提示:使用EL表达式
2、管理员退出
3、点击用户管理,查询所有用户
跳转到user_list.jsp 取出用户的数据进行展示
作业:
1、第一天的两个案例
2、将小米商城的代码独自完成
