Servlet应用

Servlet应用

1、首先要配置好环境

1.打开idea,选择Create New Project

2.选择Java->Web Application

3.填写项目名,选择项目路径

4.点击右上角的Add Configuration,找到Tomcate Server下的Local,再点击Create configuration

5.填写服务的名称

6.选择Deployment选项,点击右边加号,选择Artifact…

7.点击Apply,然后Ok

8.至此Tomact服务就配置好了,接下去就是配置项目文件

9.File->Project Structure

10.Modules->LoginByServletDemo(项目名)->Sources->选中WEB-INF,右击创建两个新文件,名字为:classess , lib

 

11.切换到Path,选择Use module compile output path,并且Output path和Test out path的路径修改为前面刚创建的classes的文件路径

12.切换到Dependencies,点击右侧加号,选择Jars or directiories…

13.选择之前创建的lib文件夹

14.选择Jar Directory

15.点击右侧加号,选择Library

16.选择Tomcat 9.0.34(也可以是其他版本号)

17.点击Apply,然后OK

18.可以先看一下index.jsp文件内容,该文件是服务启动后,默认打开的文件(也可以修改成不打开,在配置服务的时候,可以把第5点所示界面的After launch 取消勾选),然后选择刚创建的服务ServletTomcat,点击绿色三角形启动。

19.可以看到左下角已经变成了Running

20.项目启动以后,如果选择自动打开就会出现该界面(jsp界面设定的内容),若取消了自动打开,则需要手动在浏览器的网址栏中输入如图所示的地址,注意项目名不同,地址也不一样,根据自己创建的情况输入

至此,一个完整的Tomcat项目就配置好了

2、加入上一次模拟的网页项目内容+后台管理平台的网页模板

  2.1 网页的内容参考 https://www.cnblogs.com/luomei/p/12873899.html ,后台管理平台的网页模板可自行下载

  2.2 现在项目文件大体分为两块,src目录下存放java代码文件,web目录下存放web项目文件,但需要注意,不能把项目文件存放到WEB-INF下,WEB-INF文件下,其中classes存放预编译文件(我们不需要管),lib文件下存放项目需要的一些架包(在第一大块中有一步就是将这个包设置为项目的架包路径,所以存到到这里就可以),web.xml文件是个配置文件,功能就类似于安卓项目中的.AndroidManfest.xml文件。

  2.然后把你需要的web项目文件复制到web目录下就可以,可以在文件资源管理器下复制到相应路径,也可以复制文件后,直接点击项目中的web目录,快捷键粘贴即可,下图所示,是我放入的一些项目文件,其中yinglang文件下的是后台管理的模板,login.html是上一次做好的登陆界面

 

3、创数据库,建立数据表,并预先填入基础信息

  3.1 我选取的是Mysql数据库,有需要的可以自行安装,或者推荐一个软件xmapp,可以避免很多配置mysql时候的各种错误

  3.2 可视化工具可以选择MySQL Workbench,界面比较简洁,能快速的完成直接对表进行增删改查的操作。

  3.3 下图所示是已经创建好的表内容:

 

4、编写一个servlet进行用户名和密码校验,获取登录页面的用户名密码,并显示出来(代码和截图的包路径可能有些出入,因为代码是项目整体完成后添加的,根据实际情况修改即可)

  4.1 在正式进行代码的编写前,我发现我的idea无法使用new快速创建servlet的相关文件,在查询了相关资料以后,发现,需要在.iml文件中加上红框中的内容

  4.2 创建一个Servlet文件

  4.3 在web.xml文件中配置Servlet

 

  4.3 因为要连接数据库,所以还要下载mysql对应的架包,并存放到WEB-INF下的lib文件中

  4.4 编写服务器端代码

   4.4.1 数据库连接

 1 package JDBCHelper;
 2 import com.mysql.jdbc.StatementImpl;
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.SQLException;
 6 /*
 7  * 数据库连接
 8  */
 9 public class MySqlDBUtil {
10     public static Connection getConnection() {
11         Connection connection = null;
12         try {
13             Class.forName("com.mysql.jdbc.Driver");
14             connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/servletdata?useSSL=true&characterEncoding=utf-8&user=root&password=");
15             System.out.println("数据库连接成功!");
16             System.out.println("-------------------------------");
17             return connection;
18         } catch (Exception e) {
19             e.printStackTrace();
20         }
21         System.out.println("创建连接失败!");
22         System.out.println("-------------------------------");
23         return null;
24     }
25     public static void ShutDown(StatementImpl statement, Connection connection) {
26         if (statement != null) {
27             try {
28                 statement.close();
29             } catch (SQLException e) {
30                 e.printStackTrace();
31             }
32         }
33         if (connection != null) {
34             try {
35                 connection.close();
36             } catch (SQLException e) {
37                 e.printStackTrace();
38             }
39 
40         }
41     }
42 }

   4.4.2 数据表查询

 

 1 package JDBCHelper;
 2 
 3 import TableObject.Users;
 4 import com.mysql.jdbc.PreparedStatement;
 5 import java.sql.Connection;
 6 import java.sql.ResultSet;
 7 import java.sql.SQLException;
 8 
 9 public class UsersTableUtil {
10     //登陆校验
11     public boolean IsUsersExist(Connection con, Users user) {
12         try {
13             //验证用户名存在性
14             PreparedStatement pstmt;
15             String sql = "select * from  users where username=? and password=?";
16             pstmt= (PreparedStatement) con.prepareStatement(sql);
17             pstmt.setString(1,user.getName());
18             pstmt.setString(2,user.getPassword());
19             ResultSet rs=pstmt.executeQuery();
20             if (rs.next()) {
21                 //关闭数据库
22                 MySqlDBUtil.ShutDown(pstmt,null);
23                     return true;
24             }
25             MySqlDBUtil.ShutDown(pstmt,null);
26             return false;
27         } catch (SQLException e) {
28             // TODO Auto-generated catch block
29             e.printStackTrace();
30             return false;
31         }
32     }
33 }

   4.4.3  用户表所对应的用户类

 1 package TableObject;
 2 
 3 public class Users {
 4     String name="";//用户名
 5     String password="";//用户密码
 6 
 7     public String getName() {
 8         return name;
 9     }
10 
11     public void setName(String name) {
12         this.name = name;
13     }
14 
15     public String getPassword() {
16         return password;
17     }
18 
19     public void setPassword(String password) {
20         this.password = password;
21     }
22 }

   4.4.4 刚创建的LoginServlet的代码

 1 package Servlet;
 2 
 3 import JDBCHelper.MySqlDBUtil;
 4 import JDBCHelper.UsersTableUtil;
 5 import TableObject.Users;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.annotation.WebServlet;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 import java.io.IOException;
12 import java.sql.Connection;
13 
14 @WebServlet(name = "Servlet.LoginServlet")
15 public class LoginServlet extends HttpServlet {
16     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
17         //设置成与浏览器不同的编码方式,测试过滤器
18         //response.setContentType("text/html;charset=GB2312");
19         //request.setCharacterEncoding("GB2312");
20         //与浏览器相同的编码方式
21         response.setContentType("text/html;charset=utf-8");
22         request.setCharacterEncoding("utf-8");
23         //连接数据库
24         Connection connection= MySqlDBUtil.getConnection();
25         //Login的处理
26         Login(request,response,connection);
27         //关闭数据库
28         MySqlDBUtil.ShutDown(null,connection);
29     }
30     void Login(HttpServletRequest request, HttpServletResponse response,Connection connection) throws IOException {
31         //获取表单中的数据的值
32         Users user=new Users();
33         user.setName(request.getParameter("username"));
34         user.setPassword(request.getParameter("password"));
35         System.out.println("登入用户名:"+user.getName());
36         System.out.println("登入用户密码:"+user.getPassword());
37         //验证用户名密码
38         UsersTableUtil ur = new UsersTableUtil();
39         boolean b = ur.IsUsersExist(connection, user);
40         System.out.println("是否存在该用户:"+b);
41         System.out.println("-------------------------------");
42         if(b){
43             //成功登录,进入主界面
44             response.sendRedirect("yinglang/index.html");
45         }else
46         {
47             response.getWriter().println("登陆失败");
48             //登录失败,返回登陆界面
49             response.sendRedirect("login.html");
50             System.out.println("Login Failed!");
51         }
52     }
53     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
54 
55     }
56 }

   4.4.5 还需要修改login.html文件,红框中的注意修改即可

 

结果展示:

 

5、使用cookie,保存登录信息,30天内,用户无需登录

  5.1 一个工具类来专门保存cookie

 1 package Util;
 2 
 3 import javax.servlet.http.Cookie;
 4 import javax.servlet.http.HttpServletResponse;
 5 
 6 public class CookieSave {
 7     public void Save(HttpServletResponse response,String name,String value,int last_time)
 8     {
 9         //创建Cookie,将用户名存到叫cookieUserName的cookie中
10         //Cookie 对象携带需要保存的数据,user.getName()=value,都是字符串类型
11         //每个cookie保存一个数据,如果需要多个,创建多个cookie对象
12         Cookie cookieUserName = new Cookie(name, value);
13         //设置cookie存在时间   单位:秒
14         //cookie保存的时间,不管中途是否使用,访问cookie,到时就过期
15         //如果不设置,那么cookie在浏览器关闭的时候失效
16         cookieUserName.setMaxAge(last_time);
17         //将cookie发给浏览器(如果没有这句,cookie就不会发送给客户端)
18         response.addCookie(cookieUserName);
19     }
20 }

  5.2 将loginservlet中成功验证的代码修改为:

1 if(b){
2             CookieSave cookieSave=new CookieSave();
3             //存储用户名
4             cookieSave.Save(response,"username",user.getName(),60*60*24*30);
5             //存储密码
6             cookieSave.Save(response,"password",user.getPassword(),60*60*24*30);
7             //成功登录,进入主界面
8             response.sendRedirect("yinglang/index.html");
9         }

  5.3 完成上面两步只是完成了cookie的存储,还需要实现当页面打开后自动填充已保存的cookie,所以还需要在login.html的js代码中添加如下关于cookie操作的代码:

 1  function getCookie(cname){
 2             var name = cname + "=";
 3             var ca = document.cookie.split(';');
 4             for(var i=0; i<ca.length; i++) {
 5                 var c = ca[i].trim();
 6                 if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }
 7             }
 8             return "";
 9         }
10         function checkCookie(){
11             var user=getCookie("username");
12             var uname=document.getElementById("username");
13             var pwd=getCookie("password");
14             var upwd=document.getElementById("password");
15 
16             if (user!=""&&pwd!=""){
17                 uname.value=user;
18                 upwd.value=pwd;
19             }
20         }
21         window.onload=function()//用window的onload事件,窗体加载完毕的时候
22         {
23             checkCookie();
24         }

结果展示,可以看到时间设置是正确的30天:

6、使用session,显示网站当前在线人数

  6.1 建立一个HttpSessionListener类,并也在web.xml中添加配置

 1 package Servlet;
 2 
 3 import javax.servlet.annotation.WebListener;
 4 import javax.servlet.http.HttpSession;
 5 import javax.servlet.http.HttpSessionEvent;
 6 import javax.servlet.http.HttpSessionListener;
 7 import java.text.SimpleDateFormat;
 8 import java.util.Date;
 9 
10 @WebListener()
11 public class OnlineCounterListener implements HttpSessionListener {
12     //number of online
13     public static int activeSessions = 0;
14 
15     /* Session创建事件 */
16     public void sessionCreated(HttpSessionEvent se) {
17         activeSessions++;
18         System.out.println("newSession.id=" + se.getSession().getId() + "-->The number of online is " + Integer.toString(activeSessions));
19         HttpSession session = se.getSession();
20         // 获取 session 创建时间
21         Date createTime = new Date(session.getCreationTime());
22         //设置日期输出的格式
23         SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
24         System.out.println("createtime=" + df.format(createTime));
25         System.out.println("-------------------------------");
26 
27     }
28 
29     /* Session失效事件 */
30     public void sessionDestroyed(HttpSessionEvent se) {
31         activeSessions--;
32         System.out.println("outSession.id=" + se.getSession().getId() + "-->The number of online is " + Integer.toString(activeSessions));
33         HttpSession session = se.getSession();
34         // 获取该网页的最后一次访问时间
35         Date lastAccessTime = new Date(session.getLastAccessedTime());
36         //设置日期输出的格式
37         SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
38         System.out.println("The lastAccessTime " + df.format(lastAccessTime));
39         System.out.println("-------------------------------");
40     }
41 }

  web.xml

<!--    配置监听-->
    <listener>
        <listener-class>Servlet.OnlineCounterListener</listener-class>
    </listener>

  6.2 再添加一个session的servlet,用来获取当前的在线人数,当然,也要在web.xml中添加配置

 1 package Servlet;
 2 
 3 import javax.servlet.ServletException;
 4 import javax.servlet.annotation.WebServlet;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 import java.io.IOException;
 9 
10 import static Servlet.OnlineCounterListener.activeSessions;
11 
12 @WebServlet(name = "GetSession")
13 public class GetSession extends HttpServlet {
14     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
15     }
16     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
17         response.getWriter().println("The number of online : "+Integer.toString(activeSessions));
18     }
19 }

       web.xml

    <servlet>
        <servlet-name>GetSession</servlet-name>
        <servlet-class>Servlet.GetSession</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetSession</servlet-name>
        <url-pattern>/GetSession</url-pattern>
    </servlet-mapping>

  6.3 在loginservlet的代码中,成功登陆后加上一句代码就可以了,可以利用session完成一些操作,因为该功能只需要计数,利用监听部分的代码就可以完成了,在这里添加这一句是为了让监听响应到session的创建。

HttpSession session =request.getSession(true);

  6.4 在长时间未响应后,需要断开session,这里采用在web.xml中添加配置的方式

    <session-config>
        <session-timeout>3</session-timeout>
    </session-config>

结果展示(这里需要把自动打开浏览器的那个after launch取消勾选,不然会不知道从哪儿冒出来两个session,其次,一个浏览器一个session,可以用查看cookie的方式看到对应的session值):

7、使用过滤器解决乱码问题,登录时用户名为中文可能不能正常识别,解决该问题

  7.1 建立一个Filter,同样也需要在web.xml中配置

 1 package Servlet;
 2 
 3 import javax.servlet.*;
 4 import javax.servlet.annotation.WebFilter;
 5 import java.io.IOException;
 6 
 7 @WebFilter(filterName = "GBFilter")
 8 public class GBFilter implements Filter {
 9     public void destroy() {
10     }
11 
12     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
13         String encoding =req.getCharacterEncoding();
14         System.out.println("Before encoding "+encoding+" filter!");
15         encoding="utf-8";//新编码
16         req.setCharacterEncoding(encoding);
17         resp.setContentType("text/html;charset="+encoding);
18         System.out.println("after encoding "+encoding+" filter!");
19         System.out.println("-------------------------------------");
20         chain.doFilter(req, resp);
21     }
22 
23     public void init(FilterConfig config) throws ServletException {
24     }
25 }

  web.xml

    <!--配置filter-->
    <filter>
        <filter-name>GBFilter</filter-name>
        <filter-class>Servlet.GBFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>GBFilter</filter-name>
        <!--拦截规则-->
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

  7.2 模拟服务端和客户端编码方式不同的情况,这里我们先注释掉web.xml中的filter,然后将loginservlet中编码部分修改成与login.html不同的编码方式,我的项目文件中login.html编码为utf-8


  7.3 未使用过滤器,且服务端与客户端编码方式不同的模拟结果,可以看到小明这两个中文字已经变成了乱码

 

 

   7.4 取消过滤器在web.xml中的注释,且注释loginservlet中设定编码的两句代码后再次查看结果,发现乱码问题已经被解决了

 

8.码云地址

  https://gitee.com/MavisLuo/servlet

 PS.添加了过滤器一段时间后,可能会出现打开的界面出现文字乱码或者css样式丢失的情况,可以先把项目中的filter的配置注释一下,然后删除项目中的out文件,并将乱码的浏览器的缓存文件清除,建议清楚24小时以内,因为1小时以内可能也没有清除干净,再重启浏览器,大概率能解决掉这个问题。造成这个问题的具体原因还不清楚。(我这里用的是谷歌浏览器)

 

posted @ 2020-06-03 00:24  Luomei  阅读(398)  评论(1编辑  收藏  举报