一、简单的 Servlet demo(项目名 Servlet)
项目目录如下
1、maven 添加依赖包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
2、编写服务端 Servlet
public class LoginServlet extends HttpServlet {
private String message;
public void init() throws ServletException
{
message = "Hello World";
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String username=request.getParameter("username");
String password=request.getParameter("password");
System.out.println(username);
System.out.println(password);
HttpSession session = request.getSession();
session.setAttribute("username",username);
session.setAttribute("password",password);
response.sendRedirect(request.getContextPath()+"/success.html");
System.out.println(request.getContextPath());
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h1>" + message + "</h1>");
}
public void destroy()
{
}
}
开发 Servlet 时,首先要导入Servlet 所需要的包,自定义的 Serlvet 类继承自 HttpServlet 类,实现 doGet() 或者 doPost() 方法。
技巧:HTTP 请求通常使用 GET 或 POST 方法提交,相应地在 Servlet 中也提供了 doGet() 和 doPost() 两种分别处理请求的方法,但实际的处理过程很多时候却几乎是相同的,所以通常的处理方法是:分别编写 doGet() 和 doPost() 方法对应不同的提交方式,同时通过相互调用避免重复编码 。例如,把处理代码都放在 doGet() 方法中,然后在 doPost() 方法中调用 doGet() 方法。这样就可以保证技能进行差异化处理,又能避免代码冗余。
3、编写登陆和登录成功页面
login.html 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<form action="01/login" method="post">
请输入账号<input type="text" name="username"><br>
请输入密码<input type="text" name="password"><br>
<input type="submit">
</form>
</body>
</html>
success.html 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆成功</title>
</head>
<body>
登陆成功!
</body>
</html>
html 页面与 jsp 页面的存放位置与访问注意事项
(1)html 和 jsp 页面一般放在 web 目录下与 WEB-INF 同级目录下的文件夹中。 web 目录下面有 WEB-INF 文件夹,服务器把它指为禁访目录,其安全级别很高,浏览器不能直接访问 ,用来存放 web.xml、class文件、jar 包以及当前项目的核心配置文件等。因此 html 和 jsp 页面不要放在这下面,可以放在和 WEB-INF 同级目录下的文件夹中,这样浏览器可以直接访问 。 访问上述 html 页面的路径为 http://localhost:8080/01/static/login.html 和 http://localhost:8080/01/static/success.html。 (2)如果 html 和 jsp 文件放在 WEB-INF 目录下,可以通过重定向 进行访问:
request.getRequestDispatcher("/WEB-INF/a.jsp").forward(request,response);
或
request.getRequestDispatcher("/WEB-INF/a.htm").forward(request,response);
4、配置访问路径映射
(1)方式一:web.xml 配置
<?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>LoginServlet</servlet-name>
<servlet-class>servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
在 web.xml 中配置 Servlet 的目的其实只有一个,就是把访问路径与一个 Servlet 绑定到一起 ,上面配置是把访问路径:“/login”与“servlet.LoginServlet”绑定到一起。 通过 <servlet> 标签指明 Servlet 信息:
● <servlet>标签:\<servlet-name> 指定 hello 这个 Servlet 的名称为 hello;<servlet-class> 指定 hello 这个 Servlet 的路径,如果 Servlet 部署在包下,则一定要将完整的包名加上去 ,如 servlet.LoginServlet。
通过 <servlet-mapping> 标签指明请求与 Servlet 的映射关系:
● <servlet-mapping>标签:指定 /hello 访问路径所以访问的 Servlet 名为 hello,/hello 中的斜线,一定不能掉 。 ● <servlet> 和 <servlet-mapping> 通过 <servlet-name> 这个元素关联在一起了 。 ● <servlet…/> 元素和 <servlet-map…/> 元素中的 <servlet-name.../> 子元素的值一定要相同 ,允许一个 <servlet> 对应一个或多个 <servlet-mapping>,但是 <servlet-mapping>必须有一个且只能有一个 <servlet>
在 web.xml 中可以配置多个 Servlet ,每个 Servlet 的访问路径可以通过 <servlet>和 <servlet-mapping>进行指定。
(2)利用注解进行配置
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private String message;
public void init() throws ServletException
{
message = "Hello World,lhj";
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("执行到了");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String username=request.getParameter("username");
String password=request.getParameter("password");
System.out.println(username);
System.out.println(password);
HttpSession session = request.getSession();
session.setAttribute("username",username);
session.setAttribute("password",password);
response.sendRedirect(request.getContextPath()+"/success.html");
System.out.println(request.getContextPath());
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h1>" + message + "</h1>");
}
public void destroy()
{
}
}
使用注解 @WebServlet("/login") 即可指定该 Servlet 的访问路径,同 web.xml 的 < servlet>和< servlet-mapping> 标签所起的作用相同。
注意:web.xml 和注解的两种方式配一个就好了,不然路径重名的话反而会让tomcat启动不了 。
5、配置项目
(1)建包存放字节码文件和项目引用的包
在 web/WEB-INF目录下新建两个文件夹,classes 用于存放 Java 字节码文件(.class),lib 用于存放项目引用的包。
1)进入Project Structure,进入 Modules(IDEA的工程)选项卡,将 Paths 的两个输出路径均改成上一步新建的 classes 包,
2)然后点击 Dependencies,选择右边+号,新建 JARS 路径,选择第 1 步创建的 lib 文件夹。
(2)相关配置
6、配置 tomcat 部署服务
Run —> Edit Configurations 进行配置 Tomcat:
(1)添加 Tomcat Server
编辑配置—> "+"号 —> tomcat Server —> Local
(2)配置 server (3)部署配置
在服务部署中指定应用上下文名称后,该上下文名称会需要添加到 server 配置页面的 open browser 的 URL 中。
7、访问服务
输入账号和用户名后,跳转到登陆成功页面(服务端重定向)
二、使用 Filter 和 Session 防止恶意登录
当没用使用过滤器的时候,用户在客户端填写了用户名和密码点击了登录按钮之后,客户端会发送请求直接给系统后端,后端再调用 SQL 语句来判断用户名和密码是否有问题。用户名和密码都没有问题,则让他登录系统主页。这是一个正常情况。然而现实生活中并不全是正常的情况,偶尔也会出现一些意外,一些聪明的程序员可以绕过你的登录界面,直接访问你的系统主页。而我们的 Filter 过滤器就可以应对这样的情况。
同样的场景,当我们使用了 Filter 过滤器的时候,用户每一次发送请求的时候都要经过 Filter 过滤器,那么我们可以在过滤器里面通过 Session 进行判断当前用户有没有登录,如果已经登录则可以放行进行访问系统资源,否则我们就让他跳转到提示错误的页面或者登录页面!
@WebFilter(filterName = "Loginfilter", urlPatterns = {"/*"})
public class loginfilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest reqs = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 获取当前请求的资源路径url
String requestURI = reqs.getRequestURI();
System.out.println(" req.getRequestURI() 是" + reqs.getRequestURL());
// 如果当前请求是进行登录则放行
if (requestURI.indexOf("login") !=-1) {
System.out.println("放行");
chain.doFilter(reqs, res);
return; // 过滤器结束此次处理行为
// 如果请求不是进行登录则不放行,交由过滤器处理
} else {
System.out.println("不放行");
// 查看当前请求的 session 是否为 null
HttpSession session = reqs.getSession(false);
// 如果 session 为 null,则说明没有进行登录,重新回到登陆页面
if (session == null || session.getAttribute("username") == null) {
System.out.println(session);
// 请求重定向到登录页面
res.sendRedirect(reqs.getContextPath() + "/static/login.html");
return;
} else {
System.out.println(session);
chain.doFilter(reqs, res);
}
}
}
public void init(FilterConfig config) throws ServletException {
}
}
1、处理策略:
对每次请求都进行判断,如果请求是登陆请求,则放行,交由下一个 Filter 或者Servlet 进行处理;如果不是登录请求,则拦截该请求并查看该请求的 Session,如果 Session 不为 null 则表明已经登陆过,否则为未登录的非法访问,需要重定向到错误页面或登录页面 。
2、在查看 Session 的时候,使用 getSession(false) 而不是 getSession(),为了避免 Session 为 null 再新建 。
public HttpSessiongetSession(boolean create)
getSession(boolean create) 是返回当前请求中的 Session ,如果当前请求中的Session 为null,当 create 为 true 时就创建一个新的 Session,否则返回 null。 HttpServletRequest.getSession(ture) 等同于 HttpServletRequest.getSession()。
当向 Session 中存取登录信息时,一般建议:HttpSession session =request.getSession(); 当从 Session 中查看登录信息时,一般建议:HttpSession session =request.getSession(false);
3、过滤器除了注解方式配置,也可以使用 web.xml 进行配置。
|