书城项目-第三阶段、第四阶段,代码优化

书城项目-第三阶段:修改所有html页面为jsp页面、书城项目-第三阶段:抽取所有jsp页面中公共内容、书城项目-动态的base标签值、书城项目-表单提交失败的错误回显、书城项目-代码优化:合并LoginServlet和RegistServlet程序为UserServlet程序、书城项目-代码优化二:使用反射优化大量else if代码、书城项目-BeanUtils工具类的使用、书城项目-书城项目第四阶段,使用EL表达式

1.第三阶段:

a)页面 jsp 动态化

1、在 html 页面顶行添加 page 指令。
2、修改文件后缀名为:.jsp
3、使用 IDEA 搜索替换.html 为.jsp(快捷键:Ctrl+Shift+R)

b)抽取页面中相同的内容

i. head 中 css、jquery、base 标签

<%--
  Created by IntelliJ IDEA.
  User: ZRich
  Date: 2022/12/9
  Time: 下午 5:17
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%
    String basePath = request.getScheme()
            + "://"
            + request.getServerName()
            + ":"
            + request.getServerPort()
            + request.getContextPath()
            + "/";
%>
<%--<%=basePath%>--%>

<!-- 写base便签,永远固定相对路径跳转的结果 -->
<base href="<%=basePath%>">
<link type="text/css" rel="stylesheet" href="static/css/style.css" >
<script type="text/javascript" src="static/script/jquery-3.6.1.js"></script>

ii. 每个页面的页脚

<%--
  Created by IntelliJ IDEA.
  User: ZRich
  Date: 2022/12/9
  Time: 下午 5:28
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<div id="bottom">
		<span>
			尚硅谷书城.Copyright &copy;2015
		</span>
</div>

iii. 登录成功后的菜单

<%--
  Created by IntelliJ IDEA.
  User: ZRich
  Date: 2022/12/9
  Time: 下午 5:11
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<div>
    <span>欢迎<span class="um_span">韩总</span>光临尚硅谷书城</span>
    <a href="pages/order/order.jsp">我的订单</a>
    <a href="index.jsp">注销</a>&nbsp;&nbsp;
    <a href="index.jsp">返回</a>
</div>

iv. manager 模块的菜单

<%--
  Created by IntelliJ IDEA.
  User: ZRich
  Date: 2022/12/9
  Time: 下午 5:33
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<div>
    <a href="book_manager.jsp">图书管理</a>
    <a href="order_manager.jsp">订单管理</a>
    <a href="index.jsp">返回商城</a>
</div>

c)登录,注册错误提示,及表单回显

以登录回显为示例:
Servlet 程序端需要添加回显信息到 Request 域中

package top.qaqaq.web;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.qaqaq.pojo.User;
import top.qaqaq.service.UserService;
import top.qaqaq.service.impl.UserServiceImpl;

import java.io.IOException;

/**
 * @author RichieZhang
 * @create 2022-12-07 上午 11:51
 */
public class LoginServlet extends HttpServlet {

    private UserService userService = new UserServiceImpl();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        super.doPost(req, resp);

        //1. 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 调用 userService.login() 登录处理业务
        User loginUser = userService.login(new User(null, username, password, null));
        // 如果等于null,说明登录 失败!
        if (loginUser == null){
            // 把错误信息,和回显的表单项信息,保存在Request域中
            req.setAttribute("msg","用户名或密码错误!");
            req.setAttribute("username", username);

            // 跳回登录页面
            req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);
        } else {
            // 登录 成功
            // 跳到成功页面Login_success.html
            req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp);
        }


    }
}

jsp 页面,需要输出回显信息

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员登录页面</title>

	<%-- 静态包含 base标签,css样式,jQuery文件 --%>
	<%@ include file="/pages/common/head.jsp"%>

</head>
<body>
		<div id="login_header">
			<img class="logo_img" alt="" src="static/img/logo.gif" >
		</div>
		
			<div class="login_banner">

				<div id="l_content">
					<span class="login_word">欢迎登录</span>
				</div>
				
				<div id="content">
					<div class="login_form">
						<div class="login_box">
							<div class="tit">
								<h1>尚硅谷会员</h1>
								<a href="pages/user/regist.jsp">立即注册</a>
							</div>
							<div class="msg_cont">
								<b></b>
								<span class="errorMsg">
									<%=request.getAttribute("msg")==null?"请输入用户名和密码":request.getAttribute("msg")%>
								</span>
							</div>
							<div class="form">
								<form action="userServlet" method="post">
									<input type="hidden" name="action" value="login" />
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名"
										   autocomplete="off" tabindex="1" name="username"
										   value="<%=request.getAttribute("username")==null?"":request.getAttribute("username")%>"/>
									<br />
									<br />
									<label>用户密码:</label>
									<input class="itxt" type="password" placeholder="请输入密码" autocomplete="off" tabindex="1" name="password" />
									<br />
									<br />
									<input type="submit" value="登录" id="sub_btn" />
								</form>
							</div>
							
						</div>
					</div>
				</div>
			</div>

		<%-- 静态包含页脚内容 --%>
		<%@include file="/pages/common/footer.jsp"%>

</body>
</html>

d)BaseServlet 的抽取

在实际的项目开发中,一个模块,一般只使用一个 Servlet 程序。

代码优化一:代码优化:合并 LoginServlet 和 RegistServlet 程序为 UserServlet 程序

UserServlet 程序:

package top.qaqaq.web;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import top.qaqaq.pojo.User;
import top.qaqaq.service.UserService;
import top.qaqaq.service.impl.UserServiceImpl;
import top.qaqaq.utils.WebUtils;

import java.io.IOException;

/**
 * @author RichieZhang
 * @create 2022-12-10 上午 11:26
 */
public class UserServlet extends BaseServlet {

    private UserService userService = new UserServiceImpl();

    /**
     * 处理登录的功能
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void login(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        // 调用 userService.login() 登录处理业务
        User loginUser = userService.login(new User(null, username, password, null));
        // 如果等于null,说明登录 失败!
        if (loginUser == null){
            // 把错误信息,和回显的表单项信息,保存在Request域中
            req.setAttribute("msg","用户名或密码错误!");
            req.setAttribute("username", username);

            // 跳回登录页面
            req.getRequestDispatcher("/pages/user/login.jsp").forward(req,resp);
        } else {
            // 登录 成功
            // 跳到成功页面Login_success.html
            req.getRequestDispatcher("/pages/user/login_success.jsp").forward(req,resp);
        }
    }

    /**
     * 处理注册的功能
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void regist(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1、获取请求的参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
        String code = req.getParameter("code");

//        User user = new User();

        //测试代码
//        Map<String, String[]> parameterMap = req.getParameterMap();
//        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
//            System.out.println(entry.getKey() + "=" + Arrays.asList(entry.getValue()));
//        }

//        WebUtils.copyParamToBean(req.getParameterMap(),user);

        User user = WebUtils.copyParamToBean(req.getParameterMap(), new User());


        // 2、检查 验证码是否正确   === 写死,要求验证码为:abcde
        if ("abcde".equalsIgnoreCase(code)) {
            // 3、检查 用户名是否可用
            if (userService.existsUsername(username)) {
                System.out.println("用户名[" + username + "]已存在");

                // 把回显信息,保存到Request域中
                req.setAttribute("msg","用户名已存在!!");
                req.setAttribute("username", username);
                req.setAttribute("email", email);

                // 跳回注册页面
                req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp);
            } else {
                // 可用
                // 调用 Sservice 保存到数据库
                userService.registUser(new User(null,username,password,email));

                // 跳到注册成功页面 regist_success.jsp
                req.getRequestDispatcher("/pages/user/regist_success.jsp").forward(req, resp);
            }
        } else {
            // 把回显信息,保存到Request域中
            req.setAttribute("msg","验证码错误!!");
            req.setAttribute("username", username);
            req.setAttribute("email", email);

            System.out.println("验证码[" + code + "]错误");
            req.getRequestDispatcher("/pages/user/regist.jsp").forward(req, resp);
        }
    }
}

还要给 login.jsp 添加隐藏域和修改请求地址

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员登录页面</title>

	<%-- 静态包含 base标签,css样式,jQuery文件 --%>
	<%@ include file="/pages/common/head.jsp"%>

</head>
<body>
		<div id="login_header">
			<img class="logo_img" alt="" src="static/img/logo.gif" >
		</div>
		
			<div class="login_banner">

				<div id="l_content">
					<span class="login_word">欢迎登录</span>
				</div>
				
				<div id="content">
					<div class="login_form">
						<div class="login_box">
							<div class="tit">
								<h1>尚硅谷会员</h1>
								<a href="pages/user/regist.jsp">立即注册</a>
							</div>
							<div class="msg_cont">
								<b></b>
								<span class="errorMsg">
									<%=request.getAttribute("msg")==null?"请输入用户名和密码":request.getAttribute("msg")%>
								</span>
							</div>
							<div class="form">
								<form action="userServlet" method="post">
									<input type="hidden" name="action" value="login" />
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名"
										   autocomplete="off" tabindex="1" name="username"
										   value="<%=request.getAttribute("username")==null?"":request.getAttribute("username")%>"/>
									<br />
									<br />
									<label>用户密码:</label>
									<input class="itxt" type="password" placeholder="请输入密码" autocomplete="off" tabindex="1" name="password" />
									<br />
									<br />
									<input type="submit" value="登录" id="sub_btn" />
								</form>
							</div>
							
						</div>
					</div>
				</div>
			</div>

		<%-- 静态包含页脚内容 --%>
		<%@include file="/pages/common/footer.jsp"%>

</body>
</html>

给 regist.jsp 页面添加隐藏域 action,和修改请求地址

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员注册页面</title>

	<%-- 静态包含 base标签,css样式,jQuery文件 --%>
	<%@ include file="/pages/common/head.jsp"%>

	<script type="text/javascript">
		// 页面加载完成之后
		$(function () {
			// 给注册绑定单击事件
			$("#sub_btn").click(function () {
				// 验证用户名:必须由字母,数字下划线组成,并且长度为 5 到 12 位
				//1 获取用户名输入框里的内容
				var usernameText = $("#username").val();
				//2 创建正则表达式对象
				var usernamePatt = /^\w{5,12}$/;
				//3 使用test方法验证
				if (!usernamePatt.test(usernameText)){
					//4 提示用户结果
					$("span.errorMsg").text("用户名不合法!");

					return false;
				}

				// 验证密码:必须由字母,数字下划线组成,并且长度为 5 到 12 位
				//1 获取用户名输入框里的内容
				var passwordText = $("#password").val();
				//2 创建正则表达式对象
				var passwordPatt = /^\w{5,12}$/;
				//3 使用test方法验证
				if (!passwordPatt.test(passwordText)){
					//4 提示用户结果
					$("span.errorMsg").text("密码不合法!");

					return false;
				}

				// 验证确认密码:和密码相同
				//1 获取确认密码内容
				var repwdText = $("#repwd").val();
				//2 和密码相比较
				if (repwdText != passwordText){
					//3 提示用户
					$("span.errorMsg").text("确认密码和密码不一致!");

					return false;
				}

				// 邮箱验证:xxxxx@xxx.com
				//1 获取邮箱里的内同
				var emailText = $("#email").val();
				//2 创建正则表达式对象
				var emailPatt = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
				//3 使用test方法验证是否合法
				if (!emailPatt.test(emailText)){
					//4 提示用户
					$("span.errorMsg").text("邮箱格式不合法!");

					return false;
				}

				// 验证码:现在只需要验证用户已输入。因为还没讲到服务器。验证码生成。
				var codeText = $("#code").val();

				// 去掉验证码前后空格
				// alert("去空格前:[" + codeText + "]");
				codeText = $.trim(codeText);
				// alert("去空格前:[" + codeText + "]");

				if (codeText == null || codeText == ""){
					//4 提示用户
					$("span.errorMsg").text("验证码不能为空!");

					return false;
				}

				$("span.errorMsg").text("");
			});
		});
	</script>
<style type="text/css">
	.login_form{
		height:420px;
		margin-top: 25px;
	}
	
</style>
</head>
<body>
		<div id="login_header">
			<img class="logo_img" alt="" src="static/img/logo.gif" >
		</div>
		
			<div class="login_banner">
			
				<div id="l_content">
					<span class="login_word">欢迎注册</span>
				</div>
				
				<div id="content">
					<div class="login_form">
						<div class="login_box">
							<div class="tit">
								<h1>注册尚硅谷会员</h1>
								<span class="errorMsg">
									<%=request.getAttribute("msg")==null?"":request.getAttribute("msg")%>
								</span>
							</div>
							<div class="form">
								<form action="userServlet" method="post">
									<input type="hidden" name="action" value="regist">
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名"
										   value="<%=request.getAttribute("username")==null?"":request.getAttribute("username")%>"
										   autocomplete="off" tabindex="1" name="username" id="username" />
									<br />
									<br />
									<label>用户密码:</label>
									<input class="itxt" type="password" placeholder="请输入密码"
										   autocomplete="off" tabindex="1" name="password" id="password" />
									<br />
									<br />
									<label>确认密码:</label>
									<input class="itxt" type="password" placeholder="确认密码"
										   autocomplete="off" tabindex="1" name="repwd" id="repwd" />
									<br />
									<br />
									<label>电子邮件:</label>
									<input class="itxt" type="text" placeholder="请输入邮箱地址"
										   value="<%=request.getAttribute("email")==null?"":request.getAttribute("email")%>"
										   autocomplete="off" tabindex="1" name="email" id="email" />
									<br />
									<br />
									<label>验证码:</label>
									<input class="itxt" type="text" name="code" style="width: 150px;" id="code"/>
									<img alt="" src="static/img/code.bmp" style="float: right; margin-right: 40px">
									<br />
									<br />
									<input type="submit" value="注册" id="sub_btn" />
									
								</form>
							</div>
							
						</div>
					</div>
				</div>
			</div>

		<%-- 静态包含页脚内容 --%>
		<%@include file="/pages/common/footer.jsp"%>

</body>
</html>

优化代码二:使用反射优化大量 else if 代码:

package top.qaqaq.web;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author RichieZhang
 * @create 2022-12-10 下午 12:28
 */
public abstract class BaseServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        super.doPost(req, resp);

        String action = req.getParameter("action");

//        System.out.println(acction);

        //方法一:写一个方法判断一次
//        if ("login".equals(action)) {
//            //System.out.println("处理登录的需求");
//            login(req,resp);
//        } else if ("regist".equals(action)) {
//            //System.out.println("处理注册的需求");
//            regist(req,resp);
//        }

        //方法二:通过反射动态获取
        try {
            // 通过action业务鉴别字符串,获取相应的业务 方法反射对象
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);

//            System.out.println(method);

            // 调用目标业务 方法
            method.invoke(this,req,resp);
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

代码优化三:抽取 BaseServlet 程序。

BaseServlet 程序代码:

package top.qaqaq.web;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author RichieZhang
 * @create 2022-12-10 下午 12:28
 */
public abstract class BaseServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        super.doPost(req, resp);

        String action = req.getParameter("action");

//        System.out.println(acction);

        //方法一:写一个方法判断一次
//        if ("login".equals(action)) {
//            //System.out.println("处理登录的需求");
//            login(req,resp);
//        } else if ("regist".equals(action)) {
//            //System.out.println("处理注册的需求");
//            regist(req,resp);
//        }

        //方法二:通过反射动态获取
        try {
            // 通过action业务鉴别字符串,获取相应的业务 方法反射对象
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);

//            System.out.println(method);

            // 调用目标业务 方法
            method.invoke(this,req,resp);
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

修改 UserServlet 程序继承 BaseServlet 程序。

public class UserServlet extends BaseServlet {

    private UserService userService = new UserServiceImpl();

e)数据的封装和抽取 BeanUtils 的使用

BeanUtils 工具类,它可以一次性的把所有请求的参数注入到 JavaBean 中。
BeanUtils 工具类,经常用于把 Map 中的值注入到 JavaBean 中,或者是对象属性值的拷贝操作。

BeanUtils 它不是 Jdk 的类。而是第三方的工具类。所以需要导包。

1、导入需要的 jar 包:
commons-beanutils-1.9.4.jar
commons-logging-1.2.jar

commons-collections-3.2.2.jar

2、编写 WebUtils 工具类使用:

WebUtils 工具类:

package top.qaqaq.utils;

import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.Map;

/**
 * @author RichieZhang
 * @create 2022-12-10 下午 2:11
 */
public class WebUtils {

    /**
     * 把Map中的值注入到对应的JavaBean属性中。
     * @param value
     * @param bean
     * 如果形参写成HttpServletRequest DAO层和Service层没有这个API 且web层耦合度高,代码不优雅
     * DAO层
     * Service层
     * Web层
     */
    public static <T> T copyParamToBean(Map value, T bean) {
        try {
            System.out.println("注入之前:" + bean);
            BeanUtils.populate(bean,value);
            System.out.println("注入之后:" + bean);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return bean;
    }
}

书城-第四阶段。使用 EL 表达式修改表单回显

以登录为示例:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>尚硅谷会员登录页面</title>

	<%-- 静态包含 base标签,css样式,jQuery文件 --%>
	<%@ include file="/pages/common/head.jsp"%>

</head>
<body>
		<div id="login_header">
			<img class="logo_img" alt="" src="static/img/logo.gif" >
		</div>
		
			<div class="login_banner">

				<div id="l_content">
					<span class="login_word">欢迎登录</span>
				</div>
				
				<div id="content">
					<div class="login_form">
						<div class="login_box">
							<div class="tit">
								<h1>尚硅谷会员</h1>
								<a href="pages/user/regist.jsp">立即注册</a>
							</div>
							<div class="msg_cont">
								<b></b>
								<span class="errorMsg">
<%--									<%=request.getAttribute("msg")==null?"请输入用户名和密码":request.getAttribute("msg")%>--%>
									${empty requestScope.msg ? "请输入用户名和密码" : requestScope.msg}
								</span>
							</div>
							<div class="form">
								<form action="userServlet" method="post">
									<input type="hidden" name="action" value="login" />
									<label>用户名称:</label>
									<input class="itxt" type="text" placeholder="请输入用户名"
										   autocomplete="off" tabindex="1" name="username"
<%--										   value="<%=request.getAttribute("username")==null?"":request.getAttribute("username")%>"--%>
										   value="${requestScope.username}"
									/>

									<br />
									<br />
									<label>用户密码:</label>
									<input class="itxt" type="password" placeholder="请输入密码" autocomplete="off" tabindex="1" name="password" />
									<br />
									<br />
									<input type="submit" value="登录" id="sub_btn" />
								</form>
							</div>
							
						</div>
					</div>
				</div>
			</div>

		<%-- 静态包含页脚内容 --%>
		<%@include file="/pages/common/footer.jsp"%>

</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

<!--    <servlet>-->
<!--        <servlet-name>RegistServlet</servlet-name>-->
<!--        <servlet-class>top.qaqaq.web.RegistServlet</servlet-class>-->
<!--    </servlet>-->
<!--    <servlet-mapping>-->
<!--        <servlet-name>RegistServlet</servlet-name>-->
<!--        <url-pattern>/registServlet</url-pattern>-->
<!--    </servlet-mapping>-->

<!--    <servlet>-->
<!--        <servlet-name>LoginServlet</servlet-name>-->
<!--        <servlet-class>top.qaqaq.web.LoginServlet</servlet-class>-->
<!--    </servlet>-->
<!--    <servlet-mapping>-->
<!--        <servlet-name>LoginServlet</servlet-name>-->
<!--        <url-pattern>/loginServlet</url-pattern>-->
<!--    </servlet-mapping>-->

    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>top.qaqaq.web.UserServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/userServlet</url-pattern>
    </servlet-mapping>
</web-app>
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇