Servlet 开发一个Servlet只需要两部:
编写一个类,实现Servlet接口
把开发好的java类部署到web服务器上
把实现了Servlet的java程序叫做Sevlet
每次都要先进行web.xml修改 1 2 3 4 5 6 7 <?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_3_1.xsd" version ="3.1" > </web-app >
ServletContext web容器在启动的时候,它会为每个web程序都创建一个对应的ServletConText对象,它代表了当前的web应用;
1.共享数据 我在这个Servlet中保存的数据,可以在另一个Servlet的找到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class helloservlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); String username = "likunsong" ; context.setAttribute("username" ,username); System.out.println("hello" ); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super .doPost(req, resp); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class GetServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); String username = (String) context.getAttribute("username" ); resp.setContentType("text/html" ); resp.setCharacterEncoding("utf-8" ); resp.getWriter().print(username); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super .doPost(req, resp); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <servlet > <servlet-name > hello</servlet-name > <servlet-class > com.li.servlet.helloservlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > hello</servlet-name > <url-pattern > /hello</url-pattern > </servlet-mapping > <servlet > <servlet-name > getc</servlet-name > <servlet-class > com.li.servlet.GetServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > getc</servlet-name > <url-pattern > /getc</url-pattern > </servlet-mapping >
2.获取初始化参数 1 2 3 4 5 6 7 8 9 10 11 12 13 <context-param > <param-name > url</param-name > <param-value > jdbc:mysql://localhost:3306</param-value > </context-param > <servlet > <servlet-name > Demo03</servlet-name > <servlet-class > com.li.servlet.ServletDemo03</servlet-class > </servlet > <servlet-mapping > <servlet-name > Demo03</servlet-name > <url-pattern > /demo</url-pattern > </servlet-mapping >
1 2 3 4 5 6 protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); String url = context.getInitParameter("url" ); resp.getWriter().print(url); }
3.请求转发 1 2 3 4 5 6 7 8 9 10 11 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this .getServletContext(); context.getRequestDispatcher("/demo" ).forward(req,resp); System.out.println("进入了ServlDemo04" ); }
1 2 3 4 5 6 7 8 <servlet > <servlet-name > Demo04</servlet-name > <servlet-class > com.li.servlet.ServletDemo04</servlet-class > </servlet > <servlet-mapping > <servlet-name > Demo04</servlet-name > <url-pattern > /demo4</url-pattern > </servlet-mapping >
4.读取资源文件 Properties
在java目录下新建properties
在resources目录下新建properties
发现都被打包打了同一个路径下:classes ,我们俗称这个路径为classpath;
思路:需要一个文件流:
1 2 username = root password = 123456
1 2 3 4 5 6 7 8 9 10 11 12 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { InputStream is = this .getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties" ); Properties prop = new Properties (); prop.load(is); String username = prop.getProperty("username" ); String password = prop.getProperty("password" ); resp.getWriter().print(username+" " +password); }
访问测试即可。
HttpServletResponse web服务器接收到客户端的http请求,会针对这个请求分别创建一个代表请求的request的对象,和一个代表相应的response对象
如果要获取我们客户端请求的参数,找request
如果要给客户端响应一些东西,找response
1.常见应用
向浏览器发送消息
下载文件
获取要下载文件的路径
下载的文件名
设置想办法让浏览器能够支持我们需要的东西
获取下载文件的输入流
创建缓存区
获取OUTputStream对象
使FileOutStream流写入buffer缓冲区
使用OutputStream将缓冲区中的数据输出到客户端
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 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String realPath = "E:\\project\\demo\\javaweb-02-servlet\\response\\src\\main\\resources\\1.jpg" ; System.out.println("下载文件的路径" +realPath); String filename = realPath.substring(realPath.lastIndexOf("\\" ) + 1 ); resp.setHeader("Content-Disposition" ,"attachment;filename=" +filename); FileInputStream in = new FileInputStream (realPath); int len = 0 ; byte [] buffer = new byte [1024 ]; ServletOutputStream out = resp.getOutputStream(); while ((len = in.read(buffer))>0 ){ out.write(buffer,0 ,len); } in.close(); out.close(); }
2.验证码功能 验证码怎么来的?
前端实现
后端实现,需要用到java的图片类,生成一个图片
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 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("refresh" ,"5" ); BufferedImage image = new BufferedImage (80 ,20 ,BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) image.getGraphics(); g.setColor(Color.white); g.fillRect(0 ,0 ,80 ,20 ); g.setColor(Color.BLUE); g.setFont(new Font (null ,Font.BOLD,20 )); g.drawString(makeNum(),0 ,20 ); resp.setContentType("image/jpeg" ); resp.setDateHeader("expires" ,-1 ); resp.setHeader("Cache-Control" ,"no-cache" ); resp.setHeader("Prama" ,"no-cache" ); ImageIO.write(image,"jpg" , resp.getOutputStream()); } private String makeNum () { Random random = new Random (); String num = random.nextInt(9999999 ) + "" ; StringBuffer sb = new StringBuffer (); for (int i = 0 ;i < 7 - num.length();i ++){ sb.append("0" ); } String s = sb.toString() + num; return s; }
1 2 3 4 5 6 7 8 <servlet > <servlet-name > img</servlet-name > <servlet-class > com.li.servlet.ImageServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > img</servlet-name > <url-pattern > /img</url-pattern > </servlet-mapping >
3.实现重定向 B一个web资源收到客户端A请求后,B他会通知A客户端去访问另一个web资源C,这个过程叫重定向
常见场景
用户登录
1 void sendRedirect (String varl) throws IOException
测试:
1 2 3 4 5 resp.sendRedirect("/r/img" );
面试题:请你聊一聊转发和重定向的区别?
相同点
不同点
请求转发的时候,url不会发生变化
重定向的时候,url会发生变化
登录实现
1 2 3 4 5 6 7 8 9 10 11 12 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username" ); String password = req.getParameter("password" ); System.out.println(username+"" +password); resp.sendRedirect("/r/success.jsp" ); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <html> <body> <%@ page contentType="text/html;" pageEncoding="utf-8" %> <h2>Hello World!</h2> <form action="${pageContext.request.contextPath}/login" method="get" > 用户名:<input type="text" name="username" ><br> 密码:<input type="password" name="password" ><br> <input type="submit" > </form> </body> </html>
1 2 3 4 5 6 7 8 <servlet > <servlet-name > request</servlet-name > <servlet-class > com.li.servlet.Requestext</servlet-class > </servlet > <servlet-mapping > <servlet-name > request</servlet-name > <url-pattern > /login</url-pattern > </servlet-mapping >
HttpServletRequest 代表客户端的请求,通过http协议访问服务器,http请求中的所有信息会被封装到httpservletrequest。通过这个方法,可以获得客户端的信息。
1.获取前端传递的参数,请求转发 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setCharacterEncoding("utf-8" ); req.setCharacterEncoding("utf-8" ); String username = req.getParameter("username" ); String password = req.getParameter("password" ); String[] hobbys = req.getParameterValues("hobbys" ); System.out.println("===========================" ); System.out.println(username); System.out.println(password); System.out.println(Arrays.toString(hobbys)); System.out.println("===========================" ); req.getRequestDispatcher("/loginsuccess.jsp" ).forward(req,resp); }
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 # index.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录</title> </head> <body> <h1>登录</h1> <div> <%--表单表示的意思,以post的方式提交表单,提交到我们的login请求--%> <form action="${pageContext.request.contextPath}/login" method="post" > 用户名:<input type="text" name="username" > <br> 密码:<input type="password" name="password" > <br> 爱好: <input type="checkbox" name="hobbys" value="代码" > 代码 <input type="checkbox" name="hobbys" value="唱歌" > 唱歌 <input type="checkbox" name="hobbys" value="电影" > 电影 <input type="checkbox" name="hobbys" value="游戏" > 游戏 <br> <input type="submit" > </form> </div> </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 13 # loginsuccess.jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>登录成功</h1> </body> </html>
面试题:请你聊一聊转发和重定向的区别?
相同点
不同点
请求转发的时候,url不会发生变化 ; 307
重定向的时候,url会发生变化; 302
cookie session 1.会话 用户打开一个浏览器,点击了超链接,访问多个web资源,关闭浏览器,这个过程可以称为会话。
有状态会话
一个网站怎么证明你来过
客户端 服务端
服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie
服务器登记你来过了,下次你来的时候,我来匹配你
2.保存会话的两种技术 cookie
session
服务器技术,利用这个技术,可以保存用户的会话信息?我们可以把信息或者数据放在session中
常见例子:网站登录之后,第二次访问不用登录,直接就登上去
3.cookie
从请求中拿到cookie信息
服务器响应给客户端cookie
1 2 3 4 5 6 Cookie[] cookies = req.getCookies(); cookie.getName() cookie.getValue() new Cookie ("Lasttime" , System.currentTimeMillis()+"" ); cookie.setMaxAge(24 *60 *60 ); resp.addCookie(cookie);
cookie:一般会保存在本地的 用户目录下 appdata
一个网站cookie是否存在上限
细节问题
一个cookie只能保存一个信息
一个web站点可以给浏览器发送多个cookie,最多20个
cookie大小有限制4kb
浏览器cookie上限300个
删除cookie:
不设置有效期,关闭浏览器,自动失效
把有效期设置为0
4.session(重点) 什么是session
服务器会给每一个用户(浏览器)创建一个session对象
一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在
用户登录之后,整个网站他都能访问 —-》保存用户的信息,保存购物车的信息….
Session和cookie的区别
cookie是吧用户的数据放在浏览器保存
session把用户的数据写到用户独占session中,服务端包保存(保存重要的信息,较少服务器自愿的浪费)
session对象由服务创建
使用场景
保存一个登录用户的信息
购物车信息
在整个网站中经常会使用到的数据,保存在session中
使用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 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8" ); req.setCharacterEncoding("utf-8" ); resp.setCharacterEncoding("utf-8" ); HttpSession session = req.getSession();session.setAttribute("name" ,"李坤松" ); String id = session.getId();if (session.isNew()){resp.getWriter().write("session已经创建成功,ID" +id); }else { resp.getWriter().write("session以及在服务器中存在了,ID" +id); } } session.invalidate();
会话自动过期:web.xml部署
1 2 3 4 <session-config > <session-timeout > 15</session-timeout > </session-config >
JSP 1.什么是jsp 最大的特点:
写jsp就像写html
区别
html只提供动态界面
Jsp中可以嵌入java代码,为用户提供动态数据
2.Jsp原理 思路:jsp怎么执行
JSP本质还是一个Servlet
JSP表达式
1 2 3 4 <% 作用: 用来将程序输出,输出到客户端 <%=b%> %>
3.jsp标签,JSTL标签,EL表达式 使用JSTL
导入依赖(pom.xml)
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 <dependencies > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.1.0</version > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <version > 2.1</version > </dependency > <dependency > <groupId > jstl</groupId > <artifactId > jstl</artifactId > <version > 1.2</version > </dependency > <dependency > <groupId > taglibs</groupId > <artifactId > standard</artifactId > <version > 1.1.2</version > </dependency > </dependencies >
在jsp界面上引入JSTL标签
1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JSTL使用的语法 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 <% ArrayList<String > people = new ArrayList <>(); people.add(0 ,"张三" ); people.add(1 ,"田七" ); people.add(2 ,"赵六" ); people.add(3 ,"王五" ); people.add(4 ,"里斯" ); request.setAttribute("list" ,people); %> <form action="hello.jsp" method="get" > <input type="text" name="username" value="${param.username}" > <input type="submit" value="登录" > </form> <c:forEach var ="people" items="${list}" > <c:out value="${people}" /> <br> </c:forEach> <c:if test="${param.username == 'admin'}" var ="admincheck" > <c:out value="管理员欢迎你" /> </c:if > <c:set value="111" var ="scope" /> <c:choose> <c:when test="${scope > 90}" > <c:out value="你的成绩为优秀" /> </c:when> <c:when test="${scope > 80}" > <c:out value="你的成绩为良好" /> </c:when> <c:when test="${scope > 70}" > <c:out value="你的成绩为一般" /> </c:when> <c:when test="${scope > 60}" > <c:out value="你的成绩为及格" /> </c:when> </c:choose>
JavaBean 实体类
JavaBean有特定的写法
必须有一个无参构造
属性必须私有化
必须有对应的set/get方法
一般用来和数据库的字段做映射 ORM;
ORM :对象关系映射
表 –> 类
字段 –> 类的属性
行记录 –> 类的对象
people表
id
name
age
address
1
1号
3
郑州
2
2号
18
郑州
1 2 3 4 5 6 7 8 9 10 class people { private int id; private String name; private int age; private String address; } class A { new people (1 ,"1号" ,3 ,"" ) }
MVC三层架构 model
业务处理:业务逻辑(Service)
数据持久层: CURD(Dao)
View
展示数据
提供链接发起的Servlet请求 (a , form , img )
Controller (servlet)
接收用户的请求:(req:请求参数,Session 信息 。。)
交给业务层对应的代码
控制试图的跳转
1 登录 --> 接收用户的登录请求 -->处理用户的请求(获取用户登陆的参数,username,password) --> 交给业务层处理业务(判断用户名密码是否正确:事务) --> Dao层查询用户名和密码是否正确 --> 数据库
Filter(过滤器)重点 Filter:过滤器,用来过滤网站的数据
Filter开发步骤 导包 要导入Filter(javax.servlet)的包
编写过滤器 实现Filter接口,重写对应的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class CharacterEncodingFilter implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { System.out.println("初始化" ); } @Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8" ); servletResponse.setCharacterEncoding("utf-8" ); servletResponse.setContentType("text/html;charset = utf-8" ); filterChain.doFilter(servletRequest,servletResponse) ; } @Override public void destroy () { System.out.println("销毁" ); } }
在web.xml中配置Filter
1 2 3 4 5 6 7 8 9 <filter > <filter-name > filter</filter-name > <filter-class > com.li.filter.CharacterEncodingFilter</filter-class > </filter > <filter-mapping > <filter-name > filter</filter-name > <url-pattern > /show/*</url-pattern > </filter-mapping >
监听器 监听器的接口
编写一个监听器
实现监听器的接口
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 public class OnlineCountlisterner implements HttpSessionListener { @Override public void sessionCreated (HttpSessionEvent httpSessionEvent) { ServletContext sct = httpSessionEvent.getSession().getServletContext(); Integer oct = (Integer) sct.getAttribute("OnlineCount" ); if (oct == null ) { oct = new Integer (1 ); } else { int count = oct.intValue(); oct = new Integer (count + 1 ); } sct.setAttribute("OnlineCount" ,oct); } @Override public void sessionDestroyed (HttpSessionEvent httpSessionEvent) { ServletContext sct = httpSessionEvent.getSession().getServletContext(); Integer oct = (Integer) sct.getAttribute("OnlineCount" ); if (oct == null ) { oct = new Integer (0 ); } else { int count = oct.intValue(); oct = new Integer (count - 1 ); } sct.setAttribute("OnlineCount" ,oct); } }
web.xml注册监听器
1 2 3 <listener > <listener-class > com.li.listenter.OnlineCountlisterner</listener-class > </listener >
看情况是否使用!(几乎不用)
过滤器,监听器的常见应用 监听器:GUI编程中经常使用:
用户登录后,向session中放数据
进入主页要判断用户是否登录;要求,在过滤器中实现
1 2 3 4 5 6 7 8 9 10 11 12 @Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; if (request.getSession().getAttribute("USER_SESSION" ) == null ){ response.sendRedirect("/j/login.jsp" ); } filterChain.doFilter(servletRequest,servletResponse); }
JDBC 就是java连接数据库
导入jdbc的jar包 1 2 3 4 5 6 7 <dependencies > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.48</version > </dependency > </dependencies >
JDBC固定步骤:
加载驱动
连接数据库
向数据库发送对象Statement:CRUD
编写SQL(根据业务,不同的SQL)
执行SQL
关闭连接
未预编译 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 public class testjdbc { public static void main (String[] args) throws ClassNotFoundException, SQLException { String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8" ; String username = "root" ; String password = "123456" ; Class.forName("com.mysql.jdbc.Driver" ); Connection connection = DriverManager.getConnection(url, username, password); Statement statement = connection.createStatement(); String sql = "delete from jdbc.users where id=3" ; ResultSet rs = statement.executeQuery(sql); while (rs.next()){ System.out.println("id=" +rs.getObject("id" )); System.out.println("name=" +rs.getObject("name" )); System.out.println("password=" +rs.getObject("password" )); System.out.println("email=" +rs.getObject("email" )); System.out.println("birthday=" +rs.getObject("birthday" )); } rs.close(); statement.close(); connection.close(); } }
预编译SQL 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 public class test2 { public static void main (String[] args) throws ClassNotFoundException, SQLException { String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8" ; String username = "root" ; String password = "123456" ; Class.forName("com.mysql.jdbc.Driver" ); Connection connection = DriverManager.getConnection(url, username, password); String sql = "insert into jdbc.users(id, name, password, email, birthday) values (?,?,?,?,?)" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1 ,4 ); preparedStatement.setString(2 ,"lks" ); preparedStatement.setString(3 ,"123456" ); preparedStatement.setString(4 ,"1537628435@qq.com" ); preparedStatement.setDate(5 ,new Date (new java .util.Date().getTime())); int i = preparedStatement.executeUpdate(); if (i > 0 ){ System.out.println("插入成功" ); } preparedStatement.close(); connection.close(); } }
事务 要么都成功,要么都失败
ACID原则:保证数据的安全
1 2 3 4 5 6 7 8 9 10 开启事务 事务提交 commit () 事务回滚 rollback () 关闭事务 转账 A :1000 B :1000 A (900 ) --100 --> B (1100 )
Junit(单元测试)
1 2 3 4 5 <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.12</version > </dependency >
@Test 只有在方法上有效,只要加了这个注解的方法,就能直接运行
1 2 3 4 @Test public void test () { System.out.println("nimenhao" ); }
搭建一个环境 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 public class test3 { @Test public void test () { String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8" ; String username = "root" ; String password = "123456" ; Connection connection = null ; try { Class.forName("com.mysql.jdbc.Driver" ); connection = DriverManager.getConnection(url, username, password); connection.setAutoCommit(false ); String sql1 = "update jdbc.account set money = money - 100 where name='A'" ; connection.prepareStatement(sql1).executeUpdate(); String sql2 = "update jdbc.account set money = money + 100 where name='B'" ; connection.prepareStatement(sql2).executeUpdate(); connection.commit(); System.out.println("success" ); } catch (Exception e) { try { connection.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } e.printStackTrace(); }finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
项目实战SMBMS 项目搭建准备工作
使用maven搭建
配置tomcat创建服务器
测试项目能不能跑
Dao层是进行数据库的操作类的封装。Service层是业务层,调用Dao层的操作类。Servlet是表示层,处理页面的传过来的数据,然后调用service 来实现功能
导入项目遇到的jar包 jar 包jsp,servlet,jstl,mysql驱动,stand
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 <dependencies > <dependency > <groupId > junit</groupId > <artifactId > junit</artifactId > <version > 4.11</version > <scope > test</scope > </dependency > <dependency > <groupId > javax.servlet</groupId > <artifactId > javax.servlet-api</artifactId > <version > 3.1.0</version > </dependency > <dependency > <groupId > javax.servlet.jsp</groupId > <artifactId > jsp-api</artifactId > <version > 2.1</version > </dependency > <dependency > <groupId > jstl</groupId > <artifactId > jstl</artifactId > <version > 1.2</version > </dependency > <dependency > <groupId > taglibs</groupId > <artifactId > standard</artifactId > <version > 1.1.2</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.48</version > </dependency > </dependencies >
创建项目包结构
编写实体类
表映射
编写基础公共类
数据库配置文件 1 2 3 4 driver = com.mysql.jdbc.Driver usl = jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8 username = root password = 123456
编写数据库的公共类 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 package com.li.dao;import javax.xml.transform.Result;import java.io.IOException;import java.io.InputStream;import java.sql.*;import java.util.Properties;public class BaseDao { private static String driver; private static String url; private static String username; private static String password; static { Properties properties = new Properties (); InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties" ); try { properties.load(is); } catch (IOException e) { e.printStackTrace(); } driver = properties.getProperty("driver" ); url = properties.getProperty("url" ); username = properties.getProperty("username" ); password = properties.getProperty("password" ); } public static Connection getConnection () { Connection connection = null ; try { Class.forName(driver); connection = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); } return connection; } public static ResultSet execute (Connection connection,String sql,Object[] params,ResultSet resultSet,PreparedStatement preparedStatement) throws SQLException { preparedStatement = connection.prepareStatement(sql); for (int i = 0 ;i < params.length;i ++){ preparedStatement.setObject(i + 1 ,params[i]); } resultSet = preparedStatement.executeQuery(); return resultSet; } public static int execute (Connection connection,String sql,Object[] params,PreparedStatement preparedStatement) throws SQLException { preparedStatement = connection.prepareStatement(sql); for (int i = 0 ;i < params.length;i ++){ preparedStatement.setObject(i + 1 ,params[i]); } int updateRows = preparedStatement.executeUpdate(sql); return updateRows; } public static boolean closeResource (Connection connection,ResultSet resultSet,PreparedStatement preparedStatement) { boolean flag = true ; if (resultSet != null ) { try { resultSet.close(); resultSet = null ; } catch (SQLException e) { e.printStackTrace(); flag = false ; } } if (connection != null ) { try { connection.close(); connection = null ; } catch (SQLException e) { e.printStackTrace(); flag = false ; } } if (preparedStatement != null ) { try { preparedStatement.close(); preparedStatement = null ; } catch (SQLException e) { e.printStackTrace(); flag = false ; } } return flag; } }
编写字符编码过滤器 1 2 3 4 5 6 7 8 @Override public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8" ); servletResponse.setCharacterEncoding("utf-8" ); servletResponse.setContentType("text/html" ); filterChain.doFilter(servletRequest,servletResponse); }
导入静态资源
https://github.com/five517/SMBMS
登录功能实现 1.编写前端界面
2.设置欢迎界面
1 2 3 4 <welcome-file-list > <welcome-file > login.jsp</welcome-file > </welcome-file-list >
3.编写dao层登录用户的接口
1 2 public User getLoginUser (Connection connection,String usercode) throws SQLException;
4.编写dao接口的实现类
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 public class UserDaoIm1 implements UserDao { @Override public User getLoginUser (Connection connection, String userCode) throws SQLException { PreparedStatement pstm = null ; ResultSet rs = null ; User user = null ; if (connection != null ) { String sql = "select * from smbms_user where userCode=?" ; Object[] params = {userCode}; rs = BaseDao.execute(connection, sql, params, rs, pstm); if (rs.next()){ user = new User (); user.setId(rs.getInt("id" )); user.setUserCode(rs.getString("userCode" )); user.setUserName(rs.getString("username" )); user.setGender(rs.getInt("gender" )); user.setBirthday(rs.getDate("birthday" )); user.setPhone(rs.getString("phone" )); user.setAddress(rs.getString("address" )); user.setUserRole(rs.getInt("userRole" )); user.setCreatedBy(rs.getInt("createBy" )); user.setCreationDate(rs.getTimestamp("creationDate" )); user.setModifyBy(rs.getInt("modifyBy" )); user.setModifyDate(rs.getTimestamp("modifyDate" )); } } return user; } }
5.业务层实现类的接口
1 2 3 4 5 6 public interface UserService { public User login (String userCode , String password) ; }
6.编写业务实现类的实现类
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 public class UserServiceImp1 implements UserService { private UserDao userDao; public UserServiceImp1 () { userDao = new UserDaoIm1 (); } @Override public User login (String userCode, String password) { Connection connection = null ; User user = null ; try { connection = BaseDao.getConnection(); user = userDao.getLoginUser(connection, userCode); } catch (SQLException e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection,null ,null ); } return user; } }
7.编写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 public class loginServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("LoginServlet--start...." ); String usercode = req.getParameter("userCode" ); String userPassword = req.getParameter("userPassword" ); UserServiceImp1 userServiceImp1 = new UserServiceImp1 (); User user = userServiceImp1.login(usercode, userPassword); if (user != null ) { req.getSession().setAttribute(Constant.USER_SESSION,user); resp.sendRedirect("jsp/frame.jsp" ); }else { req.setAttribute("error" ,"用户名或密码不正确" ); req.getRequestDispatcher("login.jsp" ).forward(req,resp); } } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
8.注册Servlet
1 2 3 4 5 6 7 8 9 <servlet > <servlet-name > LoginServlet</servlet-name > <servlet-class > com.li.servlet.user.loginServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > LoginServlet</servlet-name > <url-pattern > /login.do</url-pattern > </servlet-mapping >
登录功能优化 注销功能: 思路: 移除session,返回登录界面
LoginoutServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 public class loginoutServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.getSession().removeAttribute(Constant.USER_SESSION); resp.sendRedirect(req.getContextPath()+"/login.jsp" ); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
xml
1 2 3 4 5 6 7 8 9 <servlet > <servlet-name > LogintoutServlet</servlet-name > <servlet-class > com.li.servlet.user.loginoutServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > LogintoutServlet</servlet-name > <url-pattern > /jsp/logout.do</url-pattern > </servlet-mapping >
登录拦截优化 SysFilter.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Override public void doFilter (ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req1 = (HttpServletRequest) req; HttpServletResponse resp1 = (HttpServletResponse) resp; User attribute = (User) req1.getSession().getAttribute(Constant.USER_SESSION); if (attribute == null ){ resp1.sendRedirect("/smbms/error.jsp" ); } filterChain.doFilter(req1,resp1); }
xml
1 2 3 4 5 6 7 8 9 <filter > <filter-name > sysfilter</filter-name > <filter-class > com.li.filter.SysFilter</filter-class > </filter > <filter-mapping > <filter-name > sysfilter</filter-name > <url-pattern > /jsp/*</url-pattern > </filter-mapping >
密码修改 UserDao接口 1 2 public int updatePwd (Connection connection,int id , int password) throws SQLException;
UserDao接口实现类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Override public int updatePwd (Connection connection, int id, int password) throws SQLException { PreparedStatement pstm = null ; int execute = 0 ; if (connection != null ) { String sql = "update smbms.smbms_user set userPassword = ? where id = ?" ; Object params[] = {password,id}; execute = BaseDao.execute(connection, sql, params, pstm); BaseDao.closeResource(null ,null ,pstm); } return execute; }
UserService层接口 1 2 public boolean updatePwd ( int id , int pwd) ;
UserService实现类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Override public boolean updatePwd (int id, int pwd) { Connection connection = null ; boolean flag = false ; connection = BaseDao.getConnection(); try { if (userDao.updatePwd(connection,id,pwd)>0 ){ flag = true ; } } catch (SQLException e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection,null ,null ); } return flag; }
UserServlet编写 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 @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getParameter("method" ); if (method != null && method.equals("savepwd" )){ this .upadtePwd(req,resp); }else if (method != null && method.equals("pwdmodify" )){ this .pwdModeify(req,resp); } } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } public void upadtePwd (HttpServletRequest req, HttpServletResponse resp) { Object attribute = req.getSession().getAttribute(Constant.USER_SESSION); String newpassword = req.getParameter("newpassword" ); boolean flag = false ; if (attribute != null && newpassword != null ){ UserService userService = new UserServiceImp1 (); flag = userService.updatePwd(((User) attribute).getId(), newpassword); if (flag) { req.setAttribute("message" ,"修改密码成功,请退出使用新密码登录" ); req.getSession().removeAttribute(Constant.USER_SESSION); } else { req.setAttribute("message" ,"密码修改失败" ); } }else { req.setAttribute("message" ,"密码修改失败" ); } try { req.getRequestDispatcher("pwdmodify.jsp" ).forward(req,resp); } catch (ServletException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
优化密码使用Ajax 阿里巴巴的fastJaon 1 2 3 4 5 6 <dependency > <groupId > com.alibaba</groupId > <artifactId > fastjson</artifactId > <version > 2.0.2</version > </dependency >
修改userServlet内容 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 public void pwdModeify (HttpServletRequest req, HttpServletResponse resp) { Object attribute = req.getSession().getAttribute(Constant.USER_SESSION); String oldpassword = req.getParameter("oldpassword" ); Map<String, String> resultMap = new HashMap <String, String>(); if (attribute == null ){ resultMap.put("result" ,"sessionerror" ); }else if (StringUtils.isNullOrEmpty(oldpassword)){ resultMap.put("result" ,"error" ); }else { String userPassword = ((User) attribute).getUserPassword(); if (oldpassword.equals(userPassword)){ resultMap.put("result" ,"true" ); }else { resultMap.put("result" ,"false" ); } } try { resp.setContentType("application/jsion" ); PrintWriter writer = resp.getWriter(); writer.write(JSONArray.toJSONString(resultMap)); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } }
用户管理实现 导入分页的工具类
用户列表页面导入
获取用户数量 UserDao,UserDaoImpl,UserService,UserServiceImpl
UserDao 1 2 public int getUserCount (Connection connection,String username , int userrole) throws SQLException;
UserDaoImpl 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 @Override public int getUserCount (Connection connection, String username, int userrole) throws SQLException { PreparedStatement pstm = null ; ResultSet rs = null ; int count = 0 ; if (connection != null ){ StringBuffer sql = new StringBuffer (); sql.append("select count(1) as count from smbms.smbms_user u,smbms.smbms_role r where u.userRole = r.id" ); ArrayList<Object> list = new ArrayList <Object>(); if (!StringUtils.isNullOrEmpty(username)){ sql.append(" and u.userName like ?" ); list.add("%" +username+"%" ); } if (userrole > 0 ){ sql.append(" and u.userRole = ?" ); list.add(userrole); } Object[] params = list.toArray(); System.out.println("text:" +sql.toString()); rs = BaseDao.execute(connection, sql.toString(), params, rs, pstm); if (rs.next()){ count = rs.getInt("count" ); } BaseDao.closeResource(null ,rs,pstm); } return count ; }
UserService 1 2 public int getUserCount (String username,int userrole) ;
UserServiceImpl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Override public int getUserCount (String username, int userrole) { Connection connection = null ; int count = 0 ; try { connection = BaseDao.getConnection(); count = userDao.getUserCount(connection,username,userrole); } catch (SQLException e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection,null ,null ); } return count; }
获取用户列表 UserDao,UserDaoImpl,UserService,UserServiceImpl
UserDao 1 2 public List<User> getUserList (Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws Exception;
UserDaoImpl 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 @Override public List<User> getUserList (Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws Exception { List<User> userList = new ArrayList <User>(); PreparedStatement pstm=null ; ResultSet rs=null ; if (connection!=null ){ StringBuffer sql = new StringBuffer (); sql.append("select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.userRole = r.id" ); List<Object> list = new ArrayList <Object>(); if (!StringUtils.isNullOrEmpty(userName)){ sql.append(" and u.userName like ?" ); list.add("%" +userName+"%" ); } if (userRole > 0 ){ sql.append(" and u.userRole = ?" ); list.add(userRole); } sql.append(" order by creationDate DESC limit ?,?" ); currentPageNo = (currentPageNo-1 )*pageSize; list.add(currentPageNo); list.add(pageSize); Object[] params = list.toArray(); System.out.println("sql ----> " + sql.toString()); rs = BaseDao.execute(connection,sql.toString(),params,rs,pstm); while (rs.next()){ User _user = new User (); _user.setId(rs.getInt("id" )); _user.setUserCode(rs.getString("userCode" )); _user.setUserName(rs.getString("userName" )); _user.setGender(rs.getInt("gender" )); _user.setBirthday(rs.getDate("birthday" )); _user.setPhone(rs.getString("phone" )); _user.setUserRole(rs.getInt("userRole" )); _user.setUserRoleName(rs.getString("userRoleName" )); userList.add(_user); } BaseDao.closeResource( null , rs, pstm); } return userList; }
UserService 1 2 public List<User> getUserList (String queryUserName, int queryUserRole, int currentPageNo, int pageSize) ;
UserServiceImpl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Override public List<User> getUserList (String queryUserName, int queryUserRole, int currentPageNo, int pageSize) { Connection connection = null ; List<User> userList = null ; System.out.println("queryUserName ---- > " + queryUserName); System.out.println("queryUserRole ---- > " + queryUserRole); System.out.println("currentPageNo ---- > " + currentPageNo); System.out.println("pageSize ---- > " + pageSize); try { connection = BaseDao.getConnection(); userList = userDao.getUserList(connection, queryUserName,queryUserRole,currentPageNo,pageSize); } catch (Exception e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection, null , null ); } return userList; }
出现错误总结: web.xml中添加servlet 注释报错 出现错误信息: Element 'web-app' cannot have character [children], because the type's content type is element-only
原因:web.xml中注释写的有问题,不能直接使用 // ,要使用;
java文件中添加HttpServlet报错 解决办法:
找到自己的tomcat目录下lib目录下的 servlet-api.jar
由于我的已经处理好,下面附上别的博主的照片
最后在java文件中import即可解决。
引用博客链接
运行后java显示的有乱码 在java文件中添加
1 2 3 resp.setContentType("text/html;charset=utf-8" ); req.setCharacterEncoding("utf-8" ); resp.setCharacterEncoding("utf-8" );
Establishing SSL connection without server’s identity verification is not recommended 添加 useSSL=false