带新手玩转MVC——不讲道理就是干(上)
前言:这几天更新了几篇博客,都是关于Servlet、JSP的理解,后来又写了两种Web开发模式,发现阅读量还可以,说明JSP还是受关注的,之前有朋友评论说JSP都过时了,谁还学这些东西,甚至还有朋友说学Servlet没用。。。。。。好吧,首先,我觉得任何东西存在就有价值,不说那些知识有没有过时,就算是有新的东西,大家都喜欢用新的技术,比如说SpringBoot,用起来很方便,上手也很快,还能跟别人吹吹牛逼啥的,但是这玩意一旦出现问题,你就无从下手,不知道如何去解决。最主要的是你要知道,这些新的框架新的技术都是从那些底层的知识一步一步封装改变来的,万变不离其宗,说技术新,那它新在哪,说技术过时了, 那它为什么过时了,这些都需要你自己亲身去体验,形成自己的知识体系,这样你才能提升。还有那些说学Servlet没用的朋友,项目里面的controller层难道不是servlet吗?天天跟servlet打交道,却说Servlet没用,我竟无言以对。
案例前言:
此案例是我整合Servlet,JSP,以及MVC模式,做的完整的案例,我觉得对刚学完Servlet和JSP以及理解MVC模式 的新手朋友很适合,新手缺练,但想练的时候却没有适合的案例,有的案例很复杂,不利于新手理解,此案例专为新手打造,希望对有需求的朋友有所帮助。
案例简介
这是一个Web注册登录案例,用MVC设计模式实现Web案例,我把此篇案例分为上下两篇,上篇实现注册功能,下篇实现登录功能。
案例(上)演示
注:此篇只实现注册板块,下篇实现登录板块。
案例准备和结构
环境准备
我用的开发工具是IDEA,如果有不会用IDEA的朋友可以看之前写过的博客《IDEA新手使用教程》https://www.cnblogs.com/zyx110/p/10666082.html,我建的这是一个Maven项目,如果有朋友不知道Maven,可以先看一下我之前写的介绍Maven的博客《Maven》https://www.cnblogs.com/zyx110/p/10619148.html,不知道如何配置Maven环境的可以看《Maven的安装与配置》https://www.cnblogs.com/zyx110/p/10801666.html不知道如何在IDEA中建Maven项目的朋友可以看《IDEA为新手专业打造》https://www.cnblogs.com/zyx110/p/10802098.html,此案例还会用到Tomcat,同样,不会在IDEA中配置Tomcat的朋友可以看《IDEA为新手专业打造》https://www.cnblogs.com/zyx110/p/10802098.html,好,完成这些,就可以开始敲代码了。
案例结构
案例代码
pom.xml
junit junit 4.11 test javax.servlet javax.servlet-api 3.1.0 provided commons-fileupload commons-fileupload 1.3.1 commons-io commons-io 2.4
实体类
package domain; /* * 用户的实体类 * */ public class User { private String username;//用户名 private String password;//密码 private String nickname;//昵称 private String sex;//性别 private String hobby;//爱好 private String path;//路径 @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", nickname='" + nickname + '\'' + ", sex='" + sex + '\'' + ", hobby='" + hobby + '\'' + ", path='" + path + '\'' + '}'; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getHobby() { return hobby; } public void setHobby(String hobby) { this.hobby = hobby; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } }
InitServlet类
简介:我在这用集合来模拟数据库,把用户注册的信息保存到ServletContext中,这个类的作用就是开了服务器后先访问这个InitServlet执行它里面的init()方法,加载init()里面的集合。
package servlet; import domain.User; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; @WebServlet("/initServlet") public class InitServlet extends HttpServlet { @Override public void init() throws ServletException { //创建一个List集合用于保存用户注册的信息 Listlist = new ArrayList (); //讲list保存到ServletContext域中 this.getServletContext().setAttribute("list",list); System.out.println("init启动了"); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html"); resp.getWriter().println("初始化完成"); } }
RegistServlet类
简介:这里面的难点在于有文件上传项,提交表单信息后不能再像以前那样用request.getParameter()接收参数了,想要实现文件上传,就要用第三方文件上传的一个组件fileupload,用fileupload里面的一些方法来接收表单的参数。
1 package servlet; 2 3 4 5 import domain.User; 6 7 import org.apache.commons.fileupload.FileItem; 8 9 import org.apache.commons.fileupload.FileUploadException; 10 11 import org.apache.commons.fileupload.disk.DiskFileItemFactory; 12 13 import org.apache.commons.fileupload.servlet.ServletFileUpload; 14 15 import utils.UploadUtils; 16 17 18 19 import javax.naming.Name; 20 21 import javax.servlet.ServletContext; 22 23 import javax.servlet.ServletException; 24 25 import javax.servlet.annotation.WebServlet; 26 27 import javax.servlet.http.HttpServlet; 28 29 import javax.servlet.http.HttpServletRequest; 30 31 import javax.servlet.http.HttpServletResponse; 32 33 import java.io.FileOutputStream; 34 35 import java.io.IOException; 36 37 import java.io.InputStream; 38 39 import java.io.OutputStream; 40 41 import java.util.ArrayList; 42 43 import java.util.HashMap; 44 45 import java.util.List; 46 47 import java.util.Map; 48 49 50 51 @WebServlet("/registServlet") 52 53 public class RegistServlet extends HttpServlet { 54 55 /* 56 57 * 用户注册的Servlet 58 59 * */ 60 61 @Override 62 63 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 64 65 //数据的接收 66 67 //文件上传基本操作 68 69 70 71 try { 72 73 //定义一个Map集合用于保存接收到的数据 74 75 Mapmap = new HashMap (); 76 77 //1、创建一个磁盘文件项工厂对象 78 79 DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); 80 81 82 83 //2、创建一个核心解析类 84 85 ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory); 86 87 //3、解析request请求,返回的是List集合, List集合中存放的是FileItem对象 88 89 List list = servletFileUpload.parseRequest(req); 90 91 //定义一个List集合,用于保存兴趣爱好数据 92 93 List hobbyList = new ArrayList (); 94 95 //4、遍历集合,获得每个FileItem,判断是表单项还是文件上传项 96 97 String url = null; 98 99 for (FileItem fileItem:list){ 100 101 //判断是表单项还是文件上传项 102 103 if (fileItem.isFormField()){ 104 105 //普通表单项 106 107 //接收表单项参数的值 108 109 String name = fileItem.getFieldName();//获得表单项name属性的值 110 111 String value = fileItem.getString("utf-8");//获得表单项的值 112 113 System.out.println(name+" "+value); 114 115 //接收复选框的数据 116 117 if ("hobby".equals(name)){ 118 119 String hobbyValue = fileItem.getString("utf-8"); 120 121 //接收到一个值,将值存入到hobbyList中 122 123 hobbyList.add(hobbyValue); 124 125 hobbyValue = hobbyList.toString().substring(1,hobbyList.toString().length()-1); 126 127 System.out.println(name +" "+hobbyValue); 128 129 //将爱好的数据存入到Map集合中 130 131 map.put(name,hobbyValue); 132 133 }else { 134 135 //将数据存入到Map集合中 136 137 map.put(name,value); 138 139 } 140 141 }else { 142 143 //文件上传项 144 145 //文件上传功能 146 147 //获得文件上传的名称 148 149 String fileName = fileItem.getName(); 150 151 if (fileName!=null&&!"".equals(fileName)){ 152 153 //通过工具类获得唯一文件名 154 155 String uuidFileName = UploadUtils.getUUIDFileName(fileName); 156 157 //获得文件上传的数据 158 159 InputStream is = fileItem.getInputStream(); 160 161 //获得文件上传的路径 162 163 String path = this.getServletContext().getRealPath("/img"); 164 165 //将输入流对接到输出流就可以了 166 167 url = path+"//"+uuidFileName; 168 169 OutputStream os = new FileOutputStream(url); 170 171 int len = 0; 172 173 byte[] b = new byte[1024]; 174 175 while ((len=is.read(b))!=-1){ 176 177 os.write(b,0,len); 178 179 } 180 181 is.close(); 182 183 os.close(); 184 185 186 187 } 188 189 190 191 } 192 193 } 194 195 System.out.println(map); 196 197 //获得ServletContext对象 198 199 ServletContext servletContext = this.getServletContext(); 200 201 List userList = (List ) servletContext.getAttribute("list"); 202 203 //校验用户名: 204 205 for (User u:userList){ 206 207 if (u.getUsername().equals(map.get("username"))){ 208 209 req.setAttribute("msg","用户名已经存在!"); 210 211 req.getRequestDispatcher("/regist.jsp").forward(req,resp); 212 213 } 214 215 } 216 217 //封装数据到User中 218 219 User user = new User(); 220 221 user.setUsername(map.get("username")); 222 223 user.setPassword(map.get("password")); 224 225 user.setSex(map.get("sex")); 226 227 user.setNickname(map.get("nickname")); 228 229 user.setHobby(map.get("hobby")); 230 231 user.setPath(url); 232 233 //将注册用户的信息存入到List集合中 234 235 236 237 userList.add(user); 238 239 for (User u : userList){ 240 241 System.out.println(u); 242 243 } 244 245 servletContext.setAttribute("list",userList); 246 247 //注册成功,跳转到登录页面 248 249 req.getSession().setAttribute("username",user.getUsername()); 250 251 resp.sendRedirect(req.getContextPath()+"/login.jsp"); 252 253 } catch (FileUploadException e) { 254 255 e.printStackTrace(); 256 257 } 258 259 260 261 262 263 264 265 266 267 } 268 269 270 271 @Override 272 273 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 274 275 doGet(req, resp); 276 277 } 278 279 }
文件上传的工具类UploadUtils
package utils; import java.util.UUID; /* * 文件上传的工具类 * */ public class UploadUtils { /* * 生成唯一的文件名 * */ public static String getUUIDFileName(String fileName){ int idx = fileName.lastIndexOf("."); String extention = fileName.substring(idx); String uuidFileName = UUID.randomUUID().toString().replace("-","")+extention; return uuidFileName; } // public static void main(String[] args) { // System.out.println(getUUIDFileName("1.jpg")); // } }
页面显示部分
regist.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 3 pageEncoding="UTF-8"%> 4 5 6 7 8 9 10 11 12 13注册 14 15 16 17 18 19 20 21class="reg"> 22 23 32 33 44 45 <% 46 47 String msg = ""; 48 49 if(request.getAttribute("msg")!=null){ 50 51 msg = (String)request.getAttribute("msg"); 52 53 } 54 55 %> 56 57146 147 148 149<%= msg %>
58 59 144 145
login.jsp
1 <%@page import="utils.CookieUtils"%> 2 3 <%@ page language="java" contentType="text/html; charset=UTF-8" 4 5 pageEncoding="UTF-8"%> 6 7 8 9 10 11 12 13 14 15登录页面 16 17 18 19 20 21 22 23class="login"> 24 25 36 37 <% 38 39 String username=""; 40 41 // 获得从客户端携带过来的所有的Cookie 42 43 // Cookie[] cookies = request.getCookies(); 44 45 // // 从Cookie的数组中查找指定名称的Cookie 46 47 // Cookie cookie = CookieUtils.findCookie(cookies, "username"); 48 49 // if(cookie != null){ 50 51 // username = cookie.getValue(); 52 53 // } 54 55 56 57 if(session.getAttribute("username")!=null){ 58 59 username = (String)session.getAttribute("username"); 60 61 } 62 63 64 65 String msg = ""; 66 67 if(request.getAttribute("msg")!=null){ 68 69 msg = (String)request.getAttribute("msg"); 70 71 } 72 73 74 75 %> 76 77128 129 130 131<%=msg %>
78 79 126 127
CSS
login.css
1 *{ 2 3 margin:0px; 4 5 padding:0px; 6 7 } 8 9 a{ 10 11 text-decoration: none; 12 13 } 14 15 ul{ 16 17 list-style: none; 18 19 } 20 21 body{ 22 23 background:rgba(238,238,238,0.5); 24 25 position:relative; 26 27 font-family: 微软雅黑; 28 29 background-color: lightblue; 30 31 } 32 33 img{ 34 35 width:225px;height:220px; 36 37 } 38 39 .content{ 40 41 width: 240px; 42 43 height: 270px; 44 45 background-color:burlywood; 46 47 margin-left: 105px; 48 49 margin-top: 20px; 50 51 } 52 53 .login{ 54 55 width:450px; 56 57 height:380px; 58 59 background: white; 60 61 position:absolute; 62 63 top:50%; 64 65 left:50%; 66 67 margin-left:-225px; 68 69 /*margin-top:-225px;*/ 70 71 margin-top:100px; 72 73 padding:5px 15px; 74 75 } 76 77 .login>.header{ 78 79 width:100%; 80 81 padding:10px 0px; 82 83 border-bottom: 1px solid #ccc; 84 85 overflow: hidden; 86 87 } 88 89 .login>.header>h1{ 90 91 font-size:18px; 92 93 font-weight: normal; 94 95 float:left; 96 97 } 98 99 .login>.header>h1>a{ 100 101 padding:5px; 102 103 margin-left:10px; 104 105 color:black; 106 107 } 108 109 .login>.header>h1>a:first-child{ 110 111 margin-left:50px; 112 113 color:#2C689B; 114 115 } 116 117 .div1{ 118 119 width: 100px; 120 121 } 122 123 124 125 .login>form{ 126 127 margin-top:30px; 128 129 padding:0 50px; 130 131 } 132 133 .input1{ 134 135 width:250px; 136 137 height:40; 138 139 line-height: 40px; 140 141 padding-left: 5px; 142 143 border:1px solid #d0d6d9; 144 145 background: #F9F9F9; 146 147 } 148 149 .td1{ 150 151 height: 40px; 152 153 width: 100px; 154 155 } 156 157 table{ 158 159 padding: 0px; 160 161 margin:0px; 162 163 } 164 165 td{ 166 167 padding:5px; 168 169 margin:10px; 170 171 } 172 173 .login>form>div>p{ 174 175 width:350px; 176 177 height:25px; 178 179 line-height: 25px; 180 181 font-size: 12px; 182 183 } 184 185 .login>form>div.idcode>input{ 186 187 width:150px; 188 189 margin-right:30px; 190 191 float: left 192 193 } 194 195 .login>form>div.idcode>span{ 196 197 float:right; 198 199 width:80px; 200 201 height:30px; 202 203 margin-top:10px; 204 205 border:1px solid #ccc; 206 207 208 209 } 210 211 .login>form>div.idcode>a{ 212 213 float: right; 214 215 color: black; 216 217 font-size: 12px; 218 219 margin-top:25px; 220 221 margin-left: 5px; 222 223 } 224 225 .clear{ 226 227 clear:both; 228 229 } 230 231 .login>form>.autoLogin{ 232 233 margin-top:20px; 234 235 font-size:14px; 236 237 line-height:15px; 238 239 color:#999; 240 241 height: 15px; 242 243 } 244 245 .login>form>.autoLogin>label>input{ 246 247 margin-right:5px; 248 249 } 250 251 .login>form>.autoLogin>label{ 252 253 float:left; 254 255 } 256 257 .login>form>.autoLogin>a{ 258 259 float:right; 260 261 color:#666; 262 263 font-size:14px; 264 265 } 266 267 .btn-red{ 268 269 margin:20px 0px; 270 271 } 272 273 #login-btn{ 274 275 width:100%; 276 277 height:50px; 278 279 background:#2C689B; 280 281 border-color:#2C689B; 282 283 text-align: center; 284 285 line-height:50px; 286 287 color:#fff; 288 289 font-size: 17px; 290 291 } 292 293 #login-btn:hover{ 294 295 cursor:pointer; 296 297 }
reg.css
1 *{ 2 3 margin:0px; 4 5 padding:0px; 6 7 } 8 9 a{ 10 11 text-decoration: none; 12 13 } 14 15 ul{ 16 17 list-style: none; 18 19 } 20 21 body{ 22 23 background:rgba(238,238,238,0.5); 24 25 position:relative; 26 27 font-family: 微软雅黑; 28 29 background-color: lightblue; 30 31 } 32 33 34 35 .input1{ 36 37 width:250px; 38 39 height:40; 40 41 line-height: 40px; 42 43 padding-left: 5px; 44 45 border:1px solid #d0d6d9; 46 47 background: #F9F9F9; 48 49 } 50 51 .td1{ 52 53 height: 40px; 54 55 width: 100px; 56 57 } 58 59 table{ 60 61 padding: 0px; 62 63 margin:0px; 64 65 } 66 67 td{ 68 69 padding:5px; 70 71 margin:10px; 72 73 } 74 75 .reg{ 76 77 width:450px; 78 79 height:500px; 80 81 background: white; 82 83 position:absolute; 84 85 top:50%; 86 87 left:50%; 88 89 margin-left:-225px; 90 91 /*margin-top:-225px;*/ 92 93 margin-top:100px; 94 95 padding:5px 15px; 96 97 } 98 99 .reg>.header{ 100 101 width:100%; 102 103 padding:10px 0px; 104 105 border-bottom: 1px solid #ccc; 106 107 overflow: hidden; 108 109 } 110 111 .reg>.header>h1{ 112 113 font-size:18px; 114 115 font-weight: normal; 116 117 float:left; 118 119 } 120 121 .reg>.header>h1>a{ 122 123 padding:5px; 124 125 margin-left:10px; 126 127 color:black; 128 129 } 130 131 .reg>.header>h1>a:first-child{ 132 133 margin-left:50px; 134 135 } 136 137 .reg>.header>h1>a:last-child{ 138 139 color:#2C689B; 140 141 } 142 143 144 145 146 147 .reg>form{ 148 149 margin-top:30px; 150 151 padding:0 50px; 152 153 } 154 155 .reg>form>div>input{ 156 157 width:350px; 158 159 height:40; 160 161 line-height: 40px; 162 163 padding-left: 5px; 164 165 border:1px solid #d0d6d9; 166 167 background: #F9F9F9; 168 169 } 170 171 .reg>form>div>p{ 172 173 width:350px; 174 175 height:25px; 176 177 line-height: 25px; 178 179 font-size: 12px; 180 181 } 182 183 .reg>form>div.idcode>input{ 184 185 width:150px; 186 187 margin-right:30px; 188 189 float: left 190 191 } 192 193 .reg>form>div.idcode>span{ 194 195 float:right; 196 197 width:80px; 198 199 height:30px; 200 201 margin-top:10px; 202 203 border:1px solid #ccc; 204 205 206 207 } 208 209 .reg>form>div.idcode>a{ 210 211 float: right; 212 213 color: black; 214 215 font-size: 12px; 216 217 margin-top:25px; 218 219 margin-left: 5px; 220 221 } 222 223 .clear{ 224 225 clear:both; 226 227 } 228 229 .btn-red{ 230 231 margin:20px 0px; 232 233 } 234 235 #reg-btn{ 236 237 width:100%; 238 239 height:50px; 240 241 background:#2C689B; 242 243 border-color:#2C689B; 244 245 text-align: center; 246 247 line-height:50px; 248 249 color:#fff; 250 251 font-size: 17px; 252 253 } 254 255 #reg-btn:hover{ 256 257 cursor:pointer; 258 259 }
img
案例结束
此篇为实现注册功能,欲知登录如何,请看下回案例。
*****************************************************************************************************
我的博客园地址:https://www.cnblogs.com/zyx110/