zoukankan      html  css  js  c++  java
  • Servlet(Server Applet) 详解

    Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。

    Servlet的工作模式

    1. 客户端发送请求至服务器
    2. 服务器启动并调用Servlet,Servlet根据客户端请求生成响应内容并将其传给服务器
    3. 服务器将响应返回客户端

    Servlet 的工作原理

     Servlet接口定义了Servlet与servlet容器之间的契约:
        Servlet容器将Servlet类载入内存,并产生Servlet实例和调用它具体的方法。
        在一个应用程序中,每种Servlet类型只能有一个实例。
    
    ServletRequest对象和ServletResponse对象:
        ServletRequest对象和ServletResponse对象都是由Servlet容器(例如TomCat)封装好的,
        并不需要程序员去实现,程序员可以直接使用这两个对象。
    
    ServletContext对象:
        这个对象中封装了上下文(应用程序)的环境详情,可以共享应用程序的信息。。
        每个应用程序只有一个ServletContext。
    
    ServletConfig对象:
        配置信息
    
    
    web.xml的配置文件:
    
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.LoginServlet</servlet-class>
        <!-- 初始参数: 这些参数会在加载web应用的时候,封装到ServletConfig对象中 -->
        <init-param>
        	<param-name>location</param-name>
        	<param-value>aaa</param-value>
        </init-param>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
    
    
    转发:request.getRequestDispatcher("/welcome.jsp").forward(request,response);
    
    重定向:response.sendRedirect("/welcome.jsp");
    
    二者区别:
        转发不会改变地址栏中的URL,而重定向则会改变
        转发只能访问到当前web应用中的内容,而重定向则可以访问到任意web应用中的内容
        转发后,在转发后的页面中仍然可以使用原来的request对象,而重定向,原来的request对象则失去作用
    

    Servlet接口

    package javax.servlet;
    
    public interface Servlet {
    
        /**
         * 当Servlet第一次被请求时,Servlet容器就会调用这个方法(传入ServletConfig对象),
         * 从而对Servlet对象进行初始化。但是这个方法在后续请求中不会在被Servlet容器调用
         */
        void init(ServletConfig var1) throws ServletException;
    
        //返回由Servlet容器传给init()方法的ServletConfig对象
        ServletConfig getServletConfig();
    
        /**
         * 每当请求Servlet时,Servlet容器就会调用这个方法。
         */
        void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    
        String getServletInfo();
    
        /**
         * 当要销毁Servlet时,Servlet容器就会调用这个方法。
         */
        void destroy();
    }
    
    
    ServletConfig接口:
    
        public interface ServletConfig {
            String getServletName();
    
            ServletContext getServletContext();
    
            String getInitParameter(String var1);
    
            Enumeration getInitParameterNames();
        }
    
    
    GenericServlet抽象类:
        GenericServlet实现了Servlet和ServletConfig接口,为Servlet接口中的所有方法提供了默认的实现
    

    HttpServlet抽象类

    HttpServlet在实现Servlet接口时,覆写了service方法:
        该方法体内的代码会自动判断用户的请求方式:
            如为GET请求,则调用doGet方法。
            如为Post请求,则调用doPost方法。
        因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
    
    package javax.servlet.http;
    
    public abstract class HttpServlet extends GenericServlet implements Serializable {
    
        public HttpServlet() {
        }
    
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String protocol = req.getProtocol();
            String msg = lStrings.getString("http.method_get_not_supported");
            if (protocol.endsWith("1.1")) {
                resp.sendError(405, msg);
            } else {
                resp.sendError(400, msg);
            }
    
        }
    
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String protocol = req.getProtocol();
            String msg = lStrings.getString("http.method_post_not_supported");
            if (protocol.endsWith("1.1")) {
                resp.sendError(405, msg);
            } else {
                resp.sendError(400, msg);
            }
    
        }
    
        protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String protocol = req.getProtocol();
            String msg = lStrings.getString("http.method_put_not_supported");
            if (protocol.endsWith("1.1")) {
                resp.sendError(405, msg);
            } else {
                resp.sendError(400, msg);
            }
    
        }
    
        protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String protocol = req.getProtocol();
            String msg = lStrings.getString("http.method_delete_not_supported");
            if (protocol.endsWith("1.1")) {
                resp.sendError(405, msg);
            } else {
                resp.sendError(400, msg);
            }
    
        }
    
        protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String CRLF = "
    ";
            String responseString = "TRACE " + req.getRequestURI() + " " + req.getProtocol();
    
            String headerName;
            for(Enumeration reqHeaderEnum = req.getHeaderNames();
                    reqHeaderEnum.hasMoreElements();
                    responseString = responseString + CRLF + headerName + ": " + req.getHeader(headerName)) {
                headerName = (String)reqHeaderEnum.nextElement();
            }
    
            responseString = responseString + CRLF;
            int responseLength = responseString.length();
            resp.setContentType("message/http");
            resp.setContentLength(responseLength);
            ServletOutputStream out = resp.getOutputStream();
            out.print(responseString);
            out.close();
        }
    
        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
            HttpServletRequest request;
            HttpServletResponse response;
            try {
                request = (HttpServletRequest)req;
                response = (HttpServletResponse)res;
            } catch (ClassCastException var6) {
                throw new ServletException("non-HTTP request or response");
            }
    
            this.service(request, response);
        }
    }
    

    HttpServletRequest接口

    HttpServletRequest表示Http环境中的Servlet请求:
    
        String getContextPath();    //项目(应用)名(当前应用的根目录)
    
        Cookie[] getCookies();    //返回一个cookie对象数组
    
        String getHeader(String var1);    //返回指定HTTP请求头的值
    
        String getMethod();    //返回客户端的请求方式
    
        String getQueryString();    //Get请求提交url地址后的参数字符串
    
        HttpSession getSession();    //返回与这个请求相关的会话对象
    
        String getRequestURI()    // app/login.jsp
    
        StringBuffer getRequestURL()    // http://localhost:8080/app/login.jsp
    
        String getParameter(String name)
    
        String[] getParameterValues(String name)
    
        Enumeration getParameterNames()
    
        Map<String,String[]> getParameterMap()
    
    
    乱码解决:
        Get:
                String name = request.getParameter("name");    //接收数据
                name =new String(name.getBytes("ISO8859-1"), "UTF-8")
        Post:
                request.setCharacterEncoding("UTF-8");
    

    HttpServletResponse接口

    void addCookie(Cookie var1);    //给这个响应添加一个cookie
    
    void addHeader(String var1, String var2);    //给这个请求添加一个响应头
    
    setHeader(String name, String value)
    
    void sendRedirect(String var1) throws IOException;    //重定向
    
    void setStatus(int var1);    //设置响应行的状态码
    
    
    PrintWriter getWriter():
        获得字符流,通过字符流的write(String s)方法可以将字符串设置到response缓冲区中,
        随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
    
    ServletOutputStream getOutputStream():
        获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。
    
    
    乱码解决:
        response.setContentType("text/html;charset=UTF-8");
    

    示例

    @WebServlet("/addServlet")    //该注解等价于在web.xml中配置的该servlet的<servlet-mapping>元素中的<url-pattern>
    public class AddServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");    //处理乱码
            Map<String, String[]> parameterMap = request.getParameterMap();    //获取参数
            User user = new User();
            try {
                BeanUtils.populate(user, parameterMap);    //封装参数
            } catch (Exception e) {
                e.printStackTrace();
            }
            ServiceImpl service = new ServiceImpl();    //转发到service处理
            service.addUser(user);
            //response.setContentType("application/json;charset=utf-8");
            //response.getWriter().write("添加成功!");
            response.sendRedirect(request.getContextPath() + "/findUserServletByPage");    //重定向
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
    
    @WebFilter("/*")
    public class SensitiveWordsFilter implements Filter {
        private List<String> words = new ArrayList<>();
    
        public void init(FilterConfig config) {
            String realPath = config.getServletContext().getRealPath("/WEB-INF/classes/敏感词汇.txt");
            BufferedReader bufferedReader = null;
            try {
                bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(realPath), Charset.forName("utf-8")));
                String line = null;
                while ((line = bufferedReader.readLine()) != null) {
                    words.add(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            //创建代理对象
            ServletRequest getParameter = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), 
                                            req.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if (method.getName().equals("getParameterMap")) {
                        //增强该方法
                        Map<String, String[]> map = (Map<String, String[]>) method.invoke(req, args);
                        //处理参数列表中的敏感词汇
                        . . .
                        return map;
                    }
                    return method.invoke(req, args);
                }
            });
            chain.doFilter(getParameter, resp);
        }
    
        public void destroy() {
        }
    }
    
  • 相关阅读:
    最简单的图片轮播
    首页图片轮播效果
    windows简单杀死进程的批处理程序
    js实现无限级树形导航列表
    漂亮竖向菜单 有缓存 javascript
    竖向折叠二级导航JS代码(可防刷新ul/li结构)
    bzoj 1060: [ZJOI2007]时态同步【树形dp】
    bzoj 2733: [HNOI2012]永无乡【并查集+权值线段树】
    洛谷 P3952 时间复杂度【模拟】
    bzoj 2208: [Jsoi2010]连通数【tarjan+拓扑+dp】
  • 原文地址:https://www.cnblogs.com/loveer/p/11552111.html
Copyright © 2011-2022 走看看