JavaWeb概述 什么是javaweb?
JavaWeb是指,通过java语言编写可以通过浏览器访问的程序的总称,叫做javaweb。
javaweb是基于请求和响应来开发的
什么是请求?
请求是指客户端给服务器发送数据,叫做Request
什么是响应?
响应实质服务器给客户端传回数据,叫做响应Response
请求和响应的关系?
Web资源的分类
web资源按照实现的技术和呈现的效果不同,分为静态资源和动态资源
静态资源 :html,css,js,txt,mp4,jpg图片等
动态资源 :jsp页面,servlet程序
Servlet技术 1.什么是Servlet Servlet是一种运行在服务器端(一般指的是 Web 服务器)的 Java 应用程序 ,可以生成动态的 Web 页面,它是属于客户与服务器响应的中间层。因此,可以说,JSP就是Servlet。两者可以实现同样的页面效果,不过,编写 JSP 和编写 Servlet 相比,前者成本低得多
Servlet是JavaEE规范之一,规范就是接口
Servlet就是JavaWeb的三大组件之一:Servlet程序,Filter过滤器,Listener监听器
Servlet就是运行在服务器上的一个java小程序,它可以接收客户端发过来的请求,并响应数据给客户端 。
2.Servlet实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.me.servlet;import javax.servlet.*;import java.io.IOException;public class HelloServlet implements Servlet { @Override public void init (ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig () { return null ; } @Override public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("Hello Servlet 被访问了!" ); } @Override public String getServletInfo () { return null ; } @Override public void destroy () { } }
到web.xml去配置servlet程序的访问地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?xml version="1.0" encoding="UTF-8" ?> <web-app xmlns ="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version ="4.0" > <servlet > <servlet-name > HelloServlet</servlet-name > <servlet-class > com.me.servlet.HelloServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > HelloServlet</servlet-name > <url-pattern > /hello</url-pattern > </servlet-mapping > </web-app >
或者使用@WebServlet注解
3.继承Httpservlet实现Servlet程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package com.me.servlet;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class HelloServlet2 extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("调用了doGet方法" ); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("调用了doPost方法" ); } }
IDEA快速生成Servlet
自动继承HttpServlet
自动重写get和post
自动配置到xml的servlet
我们只需要配置servletmap和写get和post方法
请求与与响应 HttpServletRequest
请求转发
请求重定向
1 resp.sendRedirect("重定向地址" );
HttpServletResponse
与Request类似,Response表示所有响应信息,我们如果需要设置返回给客户端的信息可以通过HttpServletResponse设置相应的信息返回
两个输出流
字节流 常用于下载,传输二进制数据
字符流 返回字符串
两种流只能使用一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class ResponseServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); resp.setCharacterEncoding("UTF-8" ); writer.write("世界你好" ); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
4.ServletConfig类
是Servlet程序的配置信息类
作用
可以获取Servlet程序的别名Servlet-name的值
获取初始化参数 Init-param
获取ServletContext对象
5.ServletContext 1.介绍 ServletContext官方叫Servlet上下文。服务器会为每一个工程创建一个对象 ,这个对象就是ServletContext对象。这个对象全局唯一 ,而且工程内部的所有servlet都共享 这个对象。所以叫全局应用程序共享对象。
ServletContext对象是一个域对象
域对象是指可以像map一样存取数据的对象,叫做域对象,域是指存取数据的操作范围
存
取
删
Map
put()
get()
remove()
域对象
setAttribute()
getAttribute()
removeAttribute()
2.具体实现
1 2 3 4 5 6 7 8 public class HelloServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); String name="King" ; context.setAttribute("name" ,name); }
1 2 3 4 5 6 7 8 9 10 11 public class GetServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); String name= (String) context.getAttribute("name" ); resp.setContentType("text/html" ); resp.setCharacterEncoding("utf-8" ); resp.getWriter().print("名字" +name); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <servlet > <servlet-name > hello</servlet-name > <servlet-class > HelloServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello</url-pattern > </servlet-mapping > <servlet > <servlet-name > getname</servlet-name > <servlet-class > GetServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > getname</servlet-name > <url-pattern > /getname</url-pattern > </servlet-mapping >
3.测试结果
6.servlet生命周期 1.当客户端向 Web 服务器提出第一次 Servlet 请求时,Web 服务器会实例化一个 Servlet,并且调用 init()方法;如果 Web 服务器中已经存在了一个 Servlet 实例,将直接使用此实例;
2.然后调用 service()方法,service()方法将根据客户端的请求方式来决定调用对应的 doXXX()方法;
3.当 Servlet 从 Web 服务器中消亡时,Web 服务器将会调用 Servlet的destroy()方法
Listener监听器 1.什么是Listener监听器
Listener 监听器它是Javaweb的三大组件之一。JavaWeb的三大组件分别是:servlet程序、Fiter过滤器、Listener监听器。
Listener它是JavaEE的规范,就是接口
监听器的作用是,监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些相应的处理。
Filter过滤器 1.什么是Fliter过滤器
Filter过滤器它是JavaWeb的三大组件之一。三大组件分是:Servlet程序、Listener监听器、Filter过滤器。
Filter过滤器它是JavaEE的规范。也就是接口
Filter过滤器它的作用是:拦截请求,过滤响应。
常见的拦截请求
Filter的实现
写一个类实现Filter接口
初始化方法:表示的是过滤器初始化时的动作。 public void init(FilterConfig config) ;
消亡方法:表示的是过滤器消亡时候的动作。 public void destroy() ;
过滤函数:表示的是过滤器过滤时的动作。 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) ;
在web.xml配置Filter
1 2 3 4 5 6 7 8 <filter > <filter-name > myfilter</filter-name > <filter-class > filter.MyFilter</filter-class > </filter > <filter-mapping > <filter-name > myfilter</filter-name > <url-pattern > /</url-pattern > </filter-mapping >
或者使用@WebFilter注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package com.atguigu.web;import com.atguigu.pojo.User;import javax.servlet.*;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import java.io.IOException;public class DoFilter implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { } @Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest httpServletRequest= (HttpServletRequest) servletRequest; HttpSession session = httpServletRequest.getSession(); Object user=session.getAttribute("name" ); if (user==null ){ servletRequest.getRequestDispatcher("/pages/user/login.html" ).forward(servletRequest, servletResponse); } else { filterChain.doFilter(servletRequest, servletResponse); } } }
1 2 3 4 5 6 7 <filter > <filter-name > DoFilter</filter-name > <filter-class > com.atguigu.web.DoFilter</filter-class > </filter > <filter-mapping > <filter-name > DoFilter</filter-name > <url-pattern > /admin/*</url-pattern >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package com.atguigu.web;import com.atguigu.pojo.User;import com.atguigu.service.UserService;import com.atguigu.service.impl.UserServiceImpl;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class LoginServlet extends HttpServlet { private UserService userService=new UserServiceImpl (); @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username" ); String password = req.getParameter("password" ); User loginUser = userService.login(new User (null , username, password, null )); if (loginUser==null ){ System.out.println("登录失败" ); req.getRequestDispatcher("/pages/user/login.html" ).forward(req, resp); } else { req.getSession().setAttribute("name" , username); req.getRequestDispatcher("/pages/user/login_success.html" ).forward(req, resp); } } }
效果是,没有登录前无法访问admin目录下后的文件
登录后即可访问
JavaEE三层架构 分层的目的就是为了解耦,解耦就是为了降低代码的耦合度,方便后期的维护
1.Web层/视图展现层
获取请求的参数,封装成为Bean对象
调用Service层处理业务
回传,响应数据给客户端
2.Service 业务层
3.DAO 持久层
只负责跟数据库交互
CRUD
Create 增
Read 查
Update 改
Delete 删
Cookie与Session 1.什么是Cookie与Session
Cookie是保存在客户端 的纯文本文件。比如txt文件。所谓的客户端就是我们自己的本地电脑。当我们使用自己的电脑通过浏览器进行访问网页的时候,服务器就会生成一个证书并返回给我的浏览器并写入我们的本地电脑。这个证书就是cookie。通俗点讲就是我们在浏览网页的时候,服务器给的我们一个身份令牌,而且这个身份是唯一的,没有人和你一样,你拥有了这个身份,服务器才能认识你。但是呢Cookie具有不可跨域名性,就是假如我们现在在访问百度,那么我们不会带上谷歌的cookie。
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器 上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。每个用户访问服务器都会建立一个session,那服务器是怎么标识用户的唯一身份呢?事实上,用户与服务器建立连接的同时,服务器会自动为其分配一个SessionId。
Session的使用需要Cookie的支持,因为单独的Session还是无法知道当前访问服务器的是否是同一个客户端,它要根据存储在Cookie中的JSESSIONID来进行判断[这个Cookie是客户端自动创建的],如果客户端关闭了Cookie,那么Session是没有什么效果的。这个时候,需要使用URL重写的方式,将JSESSIONID直接放置在URL中,访问服务器的时候可以直接进行解析。
2.Cookie与Session的实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8" ); resp.setCharacterEncoding("utf-8" ); resp.setContentType("text/html" ); PrintWriter out = resp.getWriter(); Cookie[] cookies = req.getCookies(); if (cookies!=null ){ out.write("您上一次访问的时间为:" ); for (int i = 0 ; i < cookies.length; i++) { if (cookies[i].getName().equals("LastLoginTime" )){ long timeStamp = Long.parseLong(cookies[i].getValue()); Date date=new Date (timeStamp); out.print(date.toLocaleString()); } } } else { out.write("这是你第一次访问本站" ); } Cookie cookie=new Cookie ("LastLoginTime" ,String.valueOf(System.currentTimeMillis())); cookie.setMaxAge(20 *60 *60 ); resp.addCookie(cookie); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8" ); resp.setCharacterEncoding("utf-8" ); resp.setContentType("text/html" ); HttpSession session = req.getSession(); session.setAttribute("name" ,"未来" ); if (session.isNew()){ resp.getWriter().write("session创建成功为" +session.getId()); } else { resp.getWriter().write("session在服务器中存在了,为" +session.getId()); } }
3.总结 1,session 在服务器端,cookie 在客户端(浏览器) 2,session 默认被存在在服务器的一个文件里(不是内存) 3,session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id) 4,session 可以放在 文件、数据库、或内存中都可以。 5,用户验证这种场合一般会用 session
文件传输 文件上传 1.为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。
2.为防止文件覆盖的现象发生,要为上传文件产生—个唯一的文件名
3.要限制上传文件的最大值。
4.可以限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。
要有一个form标签,method=post
form标签的enctype必须为 multipart/form-data
在标签中使用input type=file添加上传的文件
编写服务器接收,处理上传的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <form action ="http://localhost:8080/SggWeb/uploadServlet" method ="post" enctype ="multipart/form-data" > 用户名:<input type ="text" name ="username" /> <br > 头像:<input type ="file" name ="photo" > <br > <input type ="submit" value ="上传" > </form > </body > </html >
1.导包
Commons-io 是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率,Commons-io提供了很多有关IO操作的类
commons-fileupload为apache出品的文件上传组件,用来接收浏览器上传的组件,该组件有多个类组成
2.文件上传 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 package com.me.servlet;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileItemFactory;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import javax.servlet.Servlet;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.File;import java.io.IOException;import java.util.List;public class UploadServlet extends HttpServlet { @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if (ServletFileUpload.isMultipartContent(req)){ FileItemFactory fileItemFactory=new DiskFileItemFactory (); ServletFileUpload servletFileUpload=new ServletFileUpload (fileItemFactory); try { List<FileItem> list = servletFileUpload.parseRequest(req); for (FileItem fileItem : list) { if (fileItem.isFormField()){ System.out.println("表单的name" +fileItem.getFieldName()); System.out.println("表单的value" +fileItem.getString("UTF-8" )); } else { System.out.println("表单的name" +fileItem.getFieldName()); System.out.println("上传的文件名" +fileItem.getName()); fileItem.write(new File ("d:\\" +fileItem.getName())); } } } catch (Exception e) { e.printStackTrace(); } } } @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
文件下载
1.实现代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package com.me.servlet;import org.apache.commons.io.IOUtils;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URLEncoder;public class DownloadServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String filename="11.png" ; ServletContext servletContext = getServletContext(); String mimeType = servletContext.getMimeType("/file/" + filename); System.out.println("下载的文件类型为" +mimeType); resp.setContentType(mimeType); resp.setHeader("Content-Disposition" ,"attachment;filename=" + URLEncoder.encode(filename,"UTF-8" )); InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + filename); OutputStream outputStream=resp.getOutputStream(); IOUtils.copy(resourceAsStream, outputStream); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String filePath="D:\\JavaSE\\JavaWeb\\JavaWeb\\WebDownload\\src\\main\\resources\\奥日.jpg" ; String fileName=filePath.substring(filePath.lastIndexOf("\\" )+1 ); resp.setHeader("Content-Disposition" ,"attachment;filename=" + URLEncoder.encode(fileName,"UTF-8" )); FileInputStream in = new FileInputStream (filePath); int len=0 ; byte [] buffer=new byte [1024 ]; ServletOutputStream out = resp.getOutputStream(); while ((len=in.read(buffer))!=-1 ){ out.write(buffer,0 ,len); } out.close(); in.close(); }
JSON 1.什么是JSON JSON (JavaScr ipt Object Notaticn)是一种轻量级的数据交换格式 。易于人阅读和编写。同时也易于机器解析和生成。JSON采用完全独立于语言的文本格式,而且很多语言都提供了对json的支持(包括C,C++,C#,Java,JavaScript,Perl,Python等)。这样就使得JSON成为理想的数据交换。
定义:
json是由键值对组成。
由花括号包围。
每个键由引号引起来。
键和值之间使用冒号进行分隔。
多组键值对之间进行逗号进行分隔。
json就是个对象
2. JSON在JS中的使用 1 2 3 4 5 6 7 8 9 var jsonOBJ{ "key1" :"string" , "key2" :123 , "key3" :[1 ,"str" ,false ], "key4" :{ "key5" :"445" "key" :1231 } }
json对象和json字符串
对象和字符串是json的两种存在方式
JSON.stringify() 把json对象转换成为 json字符串
JSON.parse() 把json字符串转换成为 json对象
3.JSON在JAVA中的使用
Google Gson是一个简单的基于Java的库,用于将Java对象序列化为JSON,反之亦然。 它是由Google开发的一个开源库。
1 2 3 4 5 6 7 8 9 10 11 12 public static void test1 () { User user1=new User (1 , "hah" , "100234s" ); Gson gson = new Gson (); String userJson = gson.toJson(user1); System.out.println(userJson); User userString = gson.fromJson(userJson, User.class); System.out.println(userString.toString()); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void test2 () { Gson gson=new Gson (); List<User> list=new ArrayList <>(); list.add(new User (1 , "hah" , "100234s" )); list.add(new User (2 , "hah" , "100234s" )); list.add(new User (3 , "hah" , "100234s" )); list.add(new User (4 , "hah" , "100234s" )); String userListString = gson.toJson(list); System.out.println(userListString); List<User> list2= gson.fromJson(userListString, new UserListType ().getType()); System.out.println(list2.get(0 )); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public static void test3 () { Gson gson=new Gson (); Map<Integer,User> map1=new HashMap <>(); map1.put(4 ,new User (1 , "hah" , "100234s" )); map1.put(5 ,new User (2 , "hah" , "100234s" )); map1.put(6 ,new User (3 , "hah" , "100234s" )); map1.put(7 ,new User (4 , "hah" , "100234s" )); String userMapList = gson.toJson(map1); System.out.println(userMapList); Map<Integer,User> map2=gson.fromJson(userMapList, new UserMapType ().getType()); System.out.println(map2.get(4 )); }
List和Map 都需要写一个类去继承TypeToken并且使用相应泛型,否则无法转换成真正的Bean对象,而是map对象
AJAX 1.什么是AJAX
AJAX即“A synchronous J avascript A nd X ML””(异步JavaScript 和XML),是指一种创建交互式网页应用的网页开发技术。
ajax是一种浏览器通过js异步发起请求。局部更新页面的技术。
2.AJAX使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function ajaxRequest ( ) { var xmlHttpRequest=new XMLHttpRequest (); xmlHttpRequest.open ("get" ,"http://ip:port//servlet" ,true ); xmlHttpRequest.send (); if (xmlHttpRequest.readyState ==4 &&xmlHttpRequest.status ==200 ){ var obj=JSON .parse (xmlHttpRequest.responseText ); document .getElementById ().innerText ="编号" +obj.id +"姓名" +obj.name ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package com.me.servlet;import com.google.gson.Gson;import com.me.pojo.User;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class JavaScriptAjax extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("ajaxa请求过来了" ); User user=new User (12 , "66" , "6854" ); Gson gson=new Gson (); String personJson = gson.toJson(user); resp.getWriter().write(personJson); } }
3.JQuery的AJAX
$ajax
url 表示请求的地址
type 表示请求的类型get或者post
data 表示发送给服务器的数据
格式有两种
1.name=value&name=value
2.{key=value}
success 请求成功,响应的回调函数
dataType 响应 的数据类型
1 2 3 4 5 6 7 8 9 10 $.ajax ({ url :"http://ip:port//servlet" , data :"action=JQueryAjax" , type :"GET" , success :function (data ) { $("#msg" ).html ("编号" +data.id +"姓名" +data.name ); } dataType :"json" })
serialize()可以把表单中所有表单项的内容都获取到,并以name=value&name=value的形式进行拼接。
书城项目 1.环境搭建
在IDEA中建好相应的包,导入相关的页面资源
[
2.创建需要的数据库和表
1 2 3 4 5 6 7 8 9 10 11 12 13 CREATE DATABASE `book` USE `book`CREATE TABLE t_user( `id` INT PRIMARY KEY AUTO_INCREMENT, `username` VARCHAR (30 ) NOT NULL UNIQUE , `password` VARCHAR (32 ) NOT NULL , `email` VARCHAR (200 ) );INSERT INTO t_user(`username`,`password`,`email`)VALUES ('admin' ,'admin' ,'admin@guigu.com' );SELECT * FROM t_user;
3.创建数据库表对于的JavaBean对象
数据库的数据是可以为null的,所以基本数据类型要是用包装类进行==null比较
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 package com.atguigu.pojo;public class User { private Integer id; private String username; private String password; private String email; public User () { } public User (Integer id, String username, String password, String email) { this .id = id; this .username = username; this .password = password; this .email = email; } public Integer getId () { return id; } public void setId (Integer id) { this .id = id; } 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 getEmail () { return email; } public void setEmail (String email) { this .email = email; } @Override public String toString () { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + '}' ; } }
4.编写工具类jdbcUtils 1.导入相关依赖的包
Druid 是一个数据库连接池 。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。Druid是阿里巴巴开发的号称为监控而生的数据库连接池!
mysql-connector-java 是MySQL提供的JDBC驱动包 ,用JDBC连接MySQL数据库时必须使用该jar包,它的主要用途有三个:
与数据库建立连接
发送 SQL 语句
处理结果
junit是一个Java语言的单元测试框架,用于编写和运行可重复的测试。他是用于单元测试框架体系xUnit的一个实例
Hamcrest是一个书写匹配器对象时允许直接定义匹配规则的框架.有大量的匹配器是侵入式的,例如UI验证或者数据过滤,但是匹配对象在书写灵活的测试是最常用.使用Hamcrest进行单元测试.
2.编写jdbc配置文件 1 2 3 4 5 6 username =root password =123456 url =jdbc:mysql://localhost:3306/book?characterEncoding=utf8&useSSL=false driverClassName =com.mysql.jdbc.Driver initialSize =5 maxActive =10
3.编写JdbcUtils 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 package com.atguigu.utils;import com.alibaba.druid.pool.DruidDataSource;import com.alibaba.druid.pool.DruidDataSourceFactory;import java.io.InputStream;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;public class JdbcUtils { private static DruidDataSource dataSource; static { try { Properties properties = new Properties (); InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties" ); properties.load(inputStream); dataSource= (DruidDataSource) DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection () { Connection conn=null ; try { conn=dataSource.getConnection(); } catch (Exception throwables) { throwables.printStackTrace(); } return conn; } public static void closeConnection (Connection conn) { if (conn!=null ){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
4.编写JdbcUtils测试类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package com.atguigu.test;import com.atguigu.utils.JdbcUtils;import org.junit.Test;import java.sql.Connection;public class JdbcUtilsTest { @Test public void jdbcUtilsTest () { for (int i = 0 ; i < 100 ; i++) { Connection connection = JdbcUtils.getConnection(); System.out.println(connection); JdbcUtils.closeConnection(connection); } } }
5.编写BaseDao
使用BaseDao主要的作用是减少冗余代码,在对Dao的操作中CRUD可以说是最普通最常见的操作了,基本上面对不同的数据表都会有类似的CRUD操作,BaseDao的思想就是把这些冗余的操作抽取出来,作为一个抽象出来的类,使用这个BaseDao可以使我们的代码更优雅
1.导入相关的包
Commons DbUtils是Apache 组织提供的一个对JDBC 进行简单封装的开源工具类库,使用它能够简化JDBC 应用程序的开发,同时也不会影响程序的性能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 package com.atguigu.dao.impl;import com.atguigu.utils.JdbcUtils;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.apache.commons.dbutils.handlers.ScalarHandler;import java.sql.Connection;import java.sql.SQLException;import java.util.List;public abstract class BaseDao { private QueryRunner queryRunner=new QueryRunner (); public int update (String sql,Object... args) { Connection connection= JdbcUtils.getConnection(); try { return queryRunner.update(connection,sql,args); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.closeConnection(connection); } return -1 ; } public <T> T queryForOne (Class<T>type,String sql,Object... args) { Connection connection=JdbcUtils.getConnection(); try { return queryRunner.query(connection,sql,new BeanHandler <T>(type),args); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.closeConnection(connection); } return null ; } public <T> List<T> queryForList (Class<T>type,String sql,Object... args) { Connection connection=JdbcUtils.getConnection(); try { return queryRunner.query(connection,sql,new BeanListHandler <T>(type),args); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.closeConnection(connection); } return null ; } public Object queryForSingleValue (String sql,Object... args) { Connection connection=JdbcUtils.getConnection(); try { return queryRunner.query(connection,sql,new ScalarHandler (),args); } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.closeConnection(connection); } return null ; } }
6.编写UserDao和测试 1.编写UserDao接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.atguigu.dao;import com.atguigu.pojo.User;public interface UserDao { User queryUerByUsername (String username) ; User queryUerByUsernameAndPassword (String username,String password) ; int saveUser (User user) ; }
2.编写UserDao实现类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package com.atguigu.dao.impl;import com.atguigu.dao.UserDao;import com.atguigu.pojo.User;public class UserDaoImpl extends BaseDao implements UserDao { @Override public User queryUerByUsername (String username) { String sql="select `id`,`username`,`password`,`email` from t_user where username=?" ; return queryForOne(User.class,sql,username); } @Override public User queryUerByUsernameAndPassword (String username, String password) { String sql="select `id`,`username`,`password`,`email` from t_user where username=? and password=?" ; return queryForOne(User.class,sql,username,password); } @Override public int saveUser (User user) { String sql="INSERT INTO t_user(`username`,`password`,`email`) VALUES(?,?,?)" ; return update(sql,user.getUsername(),user.getPassword(),user.getEmail()); } }
3.编写UserDao测试类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package com.atguigu.test;import com.atguigu.dao.UserDao;import com.atguigu.dao.impl.UserDaoImpl;import com.atguigu.pojo.User;import org.junit.Test;import static org.junit.Assert.*;public class UserDaoTest { UserDao userDao=new UserDaoImpl (); @Test public void queryUerByUsername () { if (userDao.queryUerByUsername("admin" )==null ){ System.out.println("用户名可用!" ); } else { System.out.println("用户名已存在!" ); } } @Test public void queryUerByUsernameAndPassword () { if (userDao.queryUerByUsernameAndPassword("admin" ,"admin" )==null ){ System.out.println("用户名或密码错误!" ); } else { System.out.println("登录成功!" ); } } @Test public void saveUser () { User user=new User (null ,"hello" ,"123456" ,"1245@qq.com" ); System.out.println(userDao.saveUser(user)); } }
7.编写UserService和测试 1.UserService接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.atguigu.service;import com.atguigu.pojo.User;public interface UserService { public void registerUser (User user) ; public User login (User user) ; public boolean existsUsername (String username) ; }
2.UserServiceImpl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package com.atguigu.service.impl;import com.atguigu.dao.UserDao;import com.atguigu.dao.impl.UserDaoImpl;import com.atguigu.pojo.User;import com.atguigu.service.UserService;public class UserServiceImpl implements UserService { private UserDao userDao=new UserDaoImpl (); @Override public void registerUser (User user) { userDao.saveUser(user); } @Override public User login (User user) { return userDao.queryUerByUsernameAndPassword(user.getUsername(),user.getPassword()); } @Override public boolean existsUsername (String username) { if (userDao.queryUerByUsername(username)==null ){ return false ; } return true ; } }
3.UserService测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.atguigu.test;import com.atguigu.pojo.User;import com.atguigu.service.UserService;import com.atguigu.service.impl.UserServiceImpl;import org.junit.Test;import static org.junit.Assert.*;public class UserServiceTest { UserService userService=new UserServiceImpl (); @Test public void registerUser () { userService.registerUser(new User (null ,"bbj" ,"666" ,"1265@qq.com" )); userService.registerUser(new User (null ,"asdbbj" ,"666" ,"124465@qq.com" )); } @Test public void login () { System.out.println(userService.login(new User (null ,"wzg" ,"hhh" ,"guug@qq.com" ))); } @Test public void existsUsername () { if (userService.existsUsername("bbj" )){ System.out.println("用户名已存在" ); } else { System.out.println("用户名可用" ); } } }
8.实现注册登录功能
获取请求的参数
检查验证码是否正确
检查用户名是否存在
存在则跳回注册页面
不存在则保存到数据库并跳转到注册成功
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 package com.atguigu.web;import com.atguigu.pojo.User;import com.atguigu.service.UserService;import com.atguigu.service.impl.UserServiceImpl;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class RegisterServlet extends HttpServlet { private UserService userService = new UserServiceImpl (); @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username" ); String password = req.getParameter("password" ); String email = req.getParameter("email" ); String code = req.getParameter("code" ); if ("abcde" .equalsIgnoreCase(code)) { if (userService.existsUsername(username)) { System.out.println("用户名" + username + "已经存在" ); req.getRequestDispatcher("/pages/user/regist.html" ).forward(req, resp); } else { userService.registerUser(new User (null , username, password, email)); req.getRequestDispatcher("/pages/user/regist_success.html" ).forward(req, resp); } } else { System.out.println("验证码错误" ); req.getRequestDispatcher("/pages/user/regist.html" ).forward(req, resp); } } @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } }
获取请求的参数
调用xxxService处理业务
根据login()判断是否成功
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.atguigu.web;import com.atguigu.pojo.User;import com.atguigu.service.UserService;import com.atguigu.service.impl.UserServiceImpl;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class LoginServlet extends HttpServlet { private UserService userService=new UserServiceImpl (); @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username" ); String password = req.getParameter("password" ); User loginUser = userService.login(new User (null , username, password, null )); if (loginUser==null ){ System.out.println("登录失败" ); req.getRequestDispatcher("/pages/user/login.html" ).forward(req, resp); } else { req.getRequestDispatcher("/pages/user/login_success.html" ).forward(req, resp); } } }
9.验证码功能实现
谷歌kaptcha验证码 1.导入kaptcha包
Kaptcha 是一个可高度配置的实用验证码生成工具,可自由配置的选项如:
验证码的字体
验证码字体的大小
验证码字体的字体颜色
验证码内容的范围(数字,字母,中文汉字!)
验证码图片的大小,边框,边框粗细,边框颜色
验证码的干扰线
验证码的样式(鱼眼样式、3D、普通模糊)
kapacha依赖包
Maven Repository: com.jhlabs » filters » 2.0.235 (mvnrepository.com)
2.直接配置Servlet
1 2 3 4 5 6 7 8 <servlet > <servlet-name > KaptchaServlet</servlet-name > <servlet-class > com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > KaptchaServlet</servlet-name > <url-pattern > /kaptcha.jpg</url-pattern > </servlet-mapping >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("调用了doGet方法" ); String token = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY); req.getSession().removeAttribute(KAPTCHA_SESSION_KEY); String code = req.getParameter("code" ); if (token!=null &&token.equalsIgnoreCase(code)){ System.out.println("保存到数据库" ); }else { System.out.println("请不要重复提交表单" ); } }
i18国际化 1.什么是i18n国际化
国际化(Internationalization)指的是同一个网站可以支持多种不同的语言,以方便不同国家,不同语种的用户访问。关于国际化我们想到的最简单的方案就是为不同的国家创建不同的网站.
苹果公司这种方案并不适合全部公司,而我们希望相同的一个网站,而不同人访问的时候可以根据用户所在的区域显示不同的语言文字,而网站的布局样式等不发生改变。
于是就有了我们说的国际化,国际化总的来说就是同一个网站不同国家的人来访问可以显示出不同的语言。但实际上这 种需求并不强烈,一般真的有国际化需求的公司,主流采用的依然是苹果公司的那种方案,为不同的国家创建不同的页面。
国际化的英文Internationalization,但是由于拼写过长,老外想了一个简单的写法叫做l18N,代表的是Internationalization 这个单词,以开头,以N结尾,而中间是18个字母,所以简写为18N。以后我们说18N和国际化是一个意思。
2.国际化要求