Servlet(三)
@WebServlet注解
学习使用Servlet3.0规范引入一个新的概念:Servlet注解,可以代替web.xml * 1. 格式: @WebServlet(....) * 2. 位置: 放在想要访问的组件的类上面。 该类必须继承HttpServlet * * 注意事项: * - urlPatterns和value,只需要配置一个就可。 是数组形式,使用逗号隔开, 元素是字符串类型,每个元素都是以斜杠开头。 * 如果只有一个元素,{}可以省略 * - urlPatterns依然支持精确匹配,通配符匹配,后缀匹配 * - 每个属性都是使用逗号隔开
@WebServlet(name="m1",urlPatterns ={"/login.lr","/regist.lr","/getCode.lr"},initParams = {@WebInitParam(name="company",value = "佑才教育"),@WebInitParam(name="school",value="南开大学")},loadOnStartup = 1)
public class WebServletDemo extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("--------Servlet注解的应用--------");ServletConfig config = getServletConfig();String company = config.getInitParameter("company");String school = config.getInitParameter("school");System.out.println(company+" "+school);}
还有以下写法:
@WebServlet(urlPatterns = {"*.do"})
//@WebServlet(urlPatterns = "*.do")
//@WebServlet("*.do")
public class WebServletDemo02 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("-----Servlet最简单的配置,只需要配置urlPatterns-----------");}
}
获取Session对象
* HttpSession getSession(boolean f) * -- true: 服务器端一定会获取一个Session对象。 * 通过浏览器传过来的sid去查找session池里的session对象,如果找到了就返回。 * 没找到,或者根据就没有传过来sid。就新建。 * -- false: 如果没找到,或者压根没有传过来sid, 就返回null. 如果根据sid找到了,则返回找到的那个。 * * HttpSession getSession() * -- 相当于 第一个方法传入了true. 所以该方法一定会返回一个session对象 * * * Session对象,一旦创建后,会将SessionID以Cookie模式发送给浏览器端。 * -- SessionId是对象的唯一标识符。在浏览器端以: JSessionId = 具体值的方法存储在浏览器端。
public class SessionDemoServlet implements Servlet {Logger logger = Logger.getLogger(SessionDemoServlet.class.getName());@Overridepublic void init(ServletConfig servletConfig) throws ServletException {}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {端。*/HttpServletRequest request = (HttpServletRequest)servletRequest;//HttpSession session = request.getSession(true);HttpSession session = request.getSession();//绑定数据到session对象,调用setAttribute(String name,Object obj)session.setAttribute("username","zhangsan");session.setAttribute("user",new User("lisi","888888"));}@Overridepublic String getServletInfo() {return "";}@Overridepublic void destroy() {}
}
Filter接口
Filter接口,是Servlet规范中的三大接口之一,(Servlet接口,Listener接口,Filter接口) * 1. 是一个可插拔的Web组件 * 2. 可以在浏览器发送请求到Servlet组件之前,以及响应到浏览器之前进行筛选和过滤。 * 3. 过滤和筛选的逻辑在doFilter方法中编写
public class CommentFilter implements Filter {private FilterConfig config;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {config = filterConfig;}/**** @param request 请求对象* @param response 响应对象* @param filterChain 过滤器链: 可以有多个过滤器,想要执行到Servlet组件,必须调用过滤器链的doFilter方法* @throws IOException* @throws ServletException*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");String illegal1 = config.getInitParameter("illegal1");String illegal2 = config.getInitParameter("illegal2");String comment = request.getParameter("comment");if (comment.contains(illegal1)||comment.contains(illegal2)) {//使用响应对象告诉浏览器PrintWriter pw = response.getWriter();pw.write("您输入的内容非法,请重新输入");}else{//如果想要向下执行到servlet组件,需要调用过滤器链的doFilter方法,同时将请求对象和响应对象传过去filterChain.doFilter(request,response);System.out.println("---执行完service方法,才执行到此处----");}}@Overridepublic void destroy() {Filter.super.destroy();}}
验证码
生成验证码图片时,可以将字符串绑定到session对象上,因为浏览器不关闭,session就是同一个
登录或者注册使用的都是同一个session对象
number变量为什么不能提成成员变量,因为验证码组件可以单独写一个。 还需要考虑每次访问组件时,是同一个对象吗?
public class LoginOrRegistServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uri = req.getRequestURI();if (uri.contains("/login.lr")) {}else if (uri.contains("/register.lr")) {String checkCode = req.getParameter("checkCode");HttpSession session = req.getSession();String code = (String)session.getAttribute("code");if (!code.equalsIgnoreCase(checkCode)) {}}else if (uri.contains("getCheckCode.lr")){//创建一个图片面板对象BufferedImage image = new BufferedImage(80, 30, BufferedImage.TYPE_INT_RGB);//获取面板上的画笔对象Graphics g = image.getGraphics();//上色,绘制面板上的形状,绘制方形Random random = new Random();g.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));g.fillRect(0, 0, 80, 30);//上色,设置字体大小,绘制字符串到面板上String number = getRandomNumber(4);g.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));g.setFont(new Font("Times New Roman", Font.BOLD, 30));//绘制字符串时,是从左下角进行定位的g.drawString(number, 3, 24);/*** 生成验证码图片时,可以将字符串绑定到session对象上,因为浏览器不关闭,session就是同一个* 登录或者注册使用的都是同一个session对象** number变量为什么不能提成成员变量,因为验证码组件可以单独写一个。 还需要考虑每次访问组件时,是同一个对象吗?*/HttpSession session = req.getSession();session.setAttribute("code",number);//绘制线条,简单干扰一下注册/登录机器人。for (int i = 0; i < 4; i++) {g.setColor(new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256)));g.drawLine(random.nextInt(80), random.nextInt(30), random.nextInt(80), random.nextInt(30));}}}/*** 获取一个随机的字符串,作为验证码图片上的字符* @param num* @return*/public String getRandomNumber(int num){char[] chars = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9'};StringBuffer sb = new StringBuffer();for(int i=0;i<num;i++){int index = (int)(Math.random()*chars.length);sb.append(chars[index]);}return sb.toString();}