博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Servlet
阅读量:5436 次
发布时间:2019-06-15

本文共 12753 字,大约阅读时间需要 42 分钟。

现在我们写代码,基本都是各种框架用的飞起,提起Servlet,感觉是很久远的事情了...

但无论怎样,Servlet都是基础,各种框架都是在Servlet的基础上封装的。这篇,我们来复习下Servlet。

首先,我们先了解几个硬性概念。

1、什么是Servlet?

--简单来说Servlet就是用java编写的服务器端代码。

2、Servlet的生命周期?

1)、Web服务器首先检查是否已经装载并创建了该Servlet的实例对象;

2)、装载并创建该Servlet的一个实例对象;

3)、调用Servlet的init()方法;

4)、创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个响应Http的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去;

5)、Web应用程序被停止或重新启动之前 ,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。

3、Servlet接口实现类?

--GenericServlet、HttpServlet(常用)

4、关于web.xml配置?

--由于客户端是通过url地址访问web容器中的资源,所以Servlet程序若想被外界访问,必须把Servlet程序映射到一个url地址上,这个工作由web.xml中<servlet>元素和<servlet-mapping>元素完成。

如:

UserServlet
com.rain.controller.UserServlet
UserServlet
/UserServlet

<servlet>元素用于注册Servlet,它包含两个元素:<servlet-name>和<servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。

<servlet-mapping>元素用于映射一个已注册的Servlet的对外访问路径,它包含两个元素:<servlet-name>和<url-pattern>,分别用于指定Servlet的注册名称和Servlet的对外访问路径。

需要注意的是:

1)、一个<servlet>可以对应多个<servlet-mapping>,即Servlet可以有多个对外访问路径;

2)、url-pattern中的路径也可以使用*通配符,但只有两种格式:一种是*.扩展名,另一种是以 /开头,/*结尾。

优先级判断如下:

1)、哪个精确找哪个;

2)、*.后缀的格式匹配度最低。 

 

5、Servlet中的线程安全问题?

当多个客户端并发访问同一个Servlet的时候,web服务器会为每个客户端的请求创建一个线程,并在这个线程上调用Servlet的service()方法,但是Servlet在内存中只有一个对象,因此service方法内部如果访问了同一个资源的话,就有可能引发线程安全问题。

解决方案:

1)、使用SingleThreadModel接口:不能真的防止线程安全问题(已过时);

2)、使用同步代码块(效率低下)。

需要考虑线程安全的情况:

1)、访问类变量(成员变量);

2)、访问共享资源。

最终解决方案:在Servlet中尽量减少使用类变量(成员变量),如果一定要使用类变量则用锁来防止线程安全问题。但是要注意,锁住的内容应该是造成线程安全问题的核心代码,尽量的少锁主内容,减少等待时间提高Servlet的响应速度。

OK,理论上的内容讲完了,闲话少说,贴代码,自己写的一个登录注册的例子,代码可以直接拿去用,但没有cs之类的。

 

 

环境:JDK7+Tomcat8+MySQL8

项目架构:

 

Entity:

package com.rain.entity;/**  * @author 047493  * @version 2019年5月21日  * entity:实体模型层 * User:实体类 */public class User {	private int id;	private String userName;	private String password;	private String email;		public int getId(){		return id;	}	public void setId(int 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 setEmain(String email){		this.email = email;	}		@Override	public String toString(){		return "User [id=" +id+ ",userName=" +userName+ ",password=" +password+ ",email=" +email+"]";	}}

 

 

Controller:

package com.rain.controller;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.rain.entity.User;import com.rain.service.UserService;import com.rain.service.impl.UserServiceImpl;/*@WebServlet("/UserServlet")*/public class UserServlet extends HttpServlet {	private static final long serialVersionUID = 1L;	UserService userService = new UserServiceImpl();       public UserServlet() {        super();    }	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		doPost(request,response);	}		protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		String method = request.getParameter("method");				//如果传入的参数是login		if("login".equals(method)){			login(request,response);		}else if("regist".equals(method)){			regist(request,response);		}else if("toLogin".equals(method)){			toLogin(request,response);		}else if("logout".equals(method)){			logout(request,response);		}else if("toRegist".equals(method)){			toRegist(request,response);		}else {			request.setAttribute("msg", "该功能正在开发。。。");			request.getRequestDispatcher("/message.jsp").forward(request, response);		}	}				//注册	private void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {		User user = new User();				//获取前台jsp页面参数		String userName = request.getParameter("userName");		String password = request.getParameter("password");		String email = request.getParameter("email");				//将接收到的参数封装到user对象中去		user.setUserName(userName);		user.setPassword(password);		user.setEmain(email);				//判断用户名密码是否为空		//if(StringUtils.isNotBlank(user.getUserName()) && StringUtils.isNotBlank(user.getPassword())){		if((userName != null && userName.length() != 0)&&(password != null && password.length() != 0)){			int rows = userService.userRegister(user);			if(rows > 0){				response.setHeader("refresh", "1;url=UserServlet?method=toLogin");			} else {				response.setHeader("msg", "注册失败!");				request.getRequestDispatcher("/message").forward(request, response);			}		} else {			request.setAttribute("msg", "用户名密码不允许为空!");			request.getRequestDispatcher("/message").forward(request, response);		}	}		//登录	public void login(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException{				//获取前台jsp表单传递的参数		String userName = request.getParameter("userName");		String password = request.getParameter("password");						//根据参数进行判断		//1、用户名密码均不为空		//if(StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(password)){		if((userName != null && userName.length() != 0)&&(password != null && password.length() != 0)){			//2、传递到service层登录方法			User user = userService.userLogin(userName, password);			//3、判断用户信息是否查询得到			if(user != null){				//查询到,存入session				request.getSession().setAttribute("USER_SESSION", user);				//登录成功,跳转至主页				request.getRequestDispatcher("/WEB-INF/jsp/main.jsp").forward(request, response);			}else{				//未查询到或者用户名密码不匹配,会将失败的信息存储到msg中				request.setAttribute("msg", "用户名或密码错误!");				//登录失败,转向错误信息提示页,根据存入的msg取出相对应的内容				request.getRequestDispatcher("/message.jsp").forward(request, response);			}		}else{			//如果用户名或密码为空			request.setAttribute("msg", "用户名密码不允许为空!");			request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);		}	}		//转向注册		private void toRegist(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {			request.getRequestDispatcher("/WEB-INF/jsp/regist.jsp").forward(request, response);		}				//注销		private void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {			request.getSession().invalidate();			request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);		}		//转向到登录页面		private void toLogin(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {			request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);		}}

 

Service:接口+实现类

package com.rain.service;import com.rain.entity.User;/**  * @author 047493  * @version 2019年5月22日  * 业务逻辑层接口 */public interface UserService {		//用户登录	User userLogin(String userName,String password);		//用户注册	int userRegister(User user);}package com.rain.service.impl;import com.rain.dao.impl.UserDaoImpl;import com.rain.entity.User;import com.rain.service.UserService;/**  * @author 047493  * @version 2019年5月22日  * 业务逻辑层实现类 */public class UserServiceImpl implements UserService{	private UserDaoImpl userDao = new UserDaoImpl();	@Override	public User userLogin(String userName, String password) {		User user = userDao.login(userName, password);		return user;	}	@Override	public int userRegister(User user) {				return userDao.regist(user);	}		}

 DAO:接口+实现类

package com.rain.dao;import com.rain.entity.User;/**  * @author 047493  * @version 2019年5月21日  * Dao:数据持久层接口 */public interface UserDao {		//登录	User login(String userName,String password);		//注册	int regist(User user);}package com.rain.dao.impl;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import com.rain.dao.UserDao;import com.rain.entity.User;import com.rain.util.DBUtil;/**  * @author 047493  * @version 2019年5月21日  * Impl:数据持久层实现 */public class UserDaoImpl implements UserDao{	public static Connection conn;	public static PreparedStatement ps;	public static ResultSet rs;		@Override	public User login(String userName, String password) {		String sql = "select * from t_user where userName=? and password=?";		conn = DBUtil.getConnect();		User user = null;		try {			ps = conn.prepareStatement(sql);			ps.setString(1, userName);			ps.setString(2, password);			rs = ps.executeQuery();			while(rs.next()){				user = new User();				user.setId(rs.getInt("id"));				user.setUserName(rs.getString("userName"));				user.setPassword(rs.getString("password"));				user.setEmain(rs.getString("email"));			}			rs.close();			ps.close();					} catch (SQLException e) {			e.printStackTrace();		} finally {			try {				conn.close();			} catch (SQLException e) {				e.printStackTrace();			}		}		return user;	}	@Override	public int regist(User user) {		String sql="insert into t_user(userName,password,email) values(?,?,?)";		conn = DBUtil.getConnect();		int i = 0;		try {			ps = conn.prepareStatement(sql);			ps.setString(1, user.getUserName());			ps.setString(2, user.getPassword());			ps.setString(3, user.getEmail());			ps.executeUpdate();			i = 1;		} catch (SQLException e) {			e.printStackTrace();		} finally {			try {				conn.close();			} catch (SQLException e) {				e.printStackTrace();			}		}		return i;	}			}

 Util:数据库连接类

package com.rain.util;import java.io.IOException;import java.io.InputStream;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Properties;/**  * @author 047493  * @version 2019年5月21日  * 数据库连接工具类 */public class DBUtil {	public static Connection conn;	public static PreparedStatement ps;	public static ResultSet rs;		static{		try {			Class.forName("com.mysql.cj.jdbc.Driver");			System.out.println("加载数据库驱动成功!");		} catch (ClassNotFoundException e) {			e.printStackTrace();		}	}		public static Connection getConnect(){		Properties p = new Properties();		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();		InputStream in = classLoader.getResourceAsStream("db.properties");		String username = null;		String password = null;		String url = null;				try {			p.load(in);			username = p.getProperty("username");			password = p.getProperty("password");			url = p.getProperty("url");		} catch (IOException e) {			e.printStackTrace();		}				if(conn == null){			try {				conn = DriverManager.getConnection(url,username,password);				System.out.println("数据库连接成功!");			} catch (SQLException e) {				// TODO Auto-generated catch block				e.printStackTrace();			}		}				return conn;	}		public static void CloseConnection(){		try {			if(rs != null){				rs.close();			}			if(ps != null){				ps.close();			}			if(conn != null){				conn.close();			}		}catch (SQLException e) {			e.printStackTrace();		}	}}

 

db.properties:

username=rootpassword=123456url=jdbc:mysql://127.0.0.1:3306/login?serverTimezone=GMT

 web.xml:

ServletProject
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
UserServlet
com.rain.controller.UserServlet
UserServlet
/UserServlet

 index.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>			
首页

 message.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
错误信息提示页 ${msg}

 login.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>			
登录页面
没有账号,去注册?

 

main.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>			
登录成功页面

${sessionScope.USER_SESSION.userName},登录成功


退出系统

 

regist.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>			
注册页面
请填写表单
已有账号,直接登录

 

OK,访问路径:http://localhost:8080/项目名称/index.jsp 即可。

  

转载于:https://www.cnblogs.com/Rain1203/p/10919557.html

你可能感兴趣的文章
1+2+3+...+100 不允许使用乘法和除法,条件分支循环等
查看>>
Boost 读写锁
查看>>
日语的学习
查看>>
smarty 3 + codeigniter 2 + hmvc
查看>>
Lake Counting
查看>>
Oracle安装
查看>>
iOS 取后两位并且四舍五入
查看>>
bfs题目集锦
查看>>
postgresql 物理备份 pg_basebackup
查看>>
java 集合类Collection和Map
查看>>
【js编程艺术】小制作六
查看>>
WebSphere优化技巧集中营
查看>>
慢性咽炎注意事项
查看>>
hexdump:查看MBR前512个字节
查看>>
win7 SaveFileDialog 不能弹出保存窗体
查看>>
Nginx-解读内置非默认模块 ngx_http_stub_status_module
查看>>
View和ViewGroup的区别 -- Touch事件处理
查看>>
面向对象---内部类浅谈
查看>>
truncate
查看>>
LINQ--联合查询表,按记录数分页读取数据
查看>>