Servlet

tomcat的下载与安装

tomcat的下载与安装:
https://www.cnblogs.com/KmilyLee/p/9358657.html
解决Tomcat: Can’t load IA 32-bit .dll on a AMD 64-bit platform问题:https://blog.csdn.net/xiaokui_wingfly/article/details/8736142

tomcat的目录结构

在这里插入图片描述

  • bin:放置可执行文件
  • conf:配置文件在这里插入图片描述 server.xml文件中存放服务器的配置信息在这里插入图片描述
    web.xml存放项目部署描述符
  • lib:存放的是API文件,Servlet的API就存放在lib文件夹中
  • logs:存放的是日志文件
  • temp:存放临时文件
  • webapps:存放所有的web项目,一个文件夹就对应着一个web项目,访问文件夹名时直接在端口号后面添加文件夹名,如:http://localhost:8080/文件夹名,root文件夹无需添加文件夹名可直接访问。项目部署就是将web项目的文件夹拷贝到webapps文件夹下。在这里插入图片描述
    一个web项目下有WEB-INF,lib和静态资源组成。在这里插入图片描述lib存放核心类库,WEB-INF存放web项目下的核心文件,WEB-INF中的内容不能被直接访问。
  • work:存放运行时产生的文件。

Servlet(Server Applet)

  1. 定义:狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。
  2. Servlet工作过程:浏览器产生请求,Servlet容器加载对应的Servlet并且请求封装为ServletRequest对象,Servlet容器调用对应Servlet容器的service方法,Servlet处理请求,Servlet容器解析ServletResponse并将结果返回给浏览器。
public interface Servlet {
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();
}
  1. Servlet层次结构
    Servlet是个接口,实现它时需要实现5个方法,GenericServlet实现了其中的四个方法,只有一个service方法需要自己实现。
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    private static final long serialVersionUID = 1L;
    private transient ServletConfig config;

    public GenericServlet() {
    }

    public void destroy() {
    }

    public String getInitParameter(String name) {
        return this.getServletConfig().getInitParameter(name);
    }

    public Enumeration<String> getInitParameterNames() {
        return this.getServletConfig().getInitParameterNames();
    }

    public ServletConfig getServletConfig() {
        return this.config;
    }

    public ServletContext getServletContext() {
        return this.getServletConfig().getServletContext();
    }

    public String getServletInfo() {
        return "";
    }

    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }

    public void init() throws ServletException {
    }

    public void log(String message) {
        this.getServletContext().log(this.getServletName() + ": " + message);
    }

    public void log(String message, Throwable t) {
        this.getServletContext().log(this.getServletName() + ": " + message, t);
    }

    public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    public String getServletName() {
        return this.config.getServletName();
    }
}

HttpServlet继承了GenericServlet

package javax.servlet.http;
public abstract class HttpServlet extends GenericServlet {
    public HttpServlet() {
    }
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String msg = lStrings.getString("http.method_get_not_supported");
        this.sendMethodNotAllowed(req, resp, msg);
    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String msg = lStrings.getString("http.method_post_not_supported");
        this.sendMethodNotAllowed(req, resp, msg);
    }
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }
    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(lStrings.getString("http.non_http"));
        }

        this.service(request, response);
    }
}

HttpServlet重写并且重载了service方法,在servlet容器调用service方法时,先调用重写的service方法,重写的service方法又调用了重载的service方法,而重载的service又调用了doGet(),doPost()等方法,因此我们只需要重写doGet(),doPost()等方法。

  1. Servlet的访问
    Servlet放在WEB-INF的classes文件夹下,不可通过链接直接访问。需要配置映射,将Servlet的访问映射为链接的访问。有两种方式:
    配置web.xml文件:
	<!-- 添加节点 -->
    <servlet>
        <servlet-name>hs</servlet-name>
        <servlet-class>servlet.MyHttpServlet</servlet-class>
        <load-on-startup>-1</load-on-startup>
    </servlet>
    <!-- 将链接映射为servlet -->
    <servlet-mapping>
        <servlet-name>hs</servlet-name>
        <url-pattern>/hs</url-pattern>
    </servlet-mapping>

匹配方式:
精确匹配:/具体名称
通配符匹配:*.xxx匹配以xxx结尾的链接
匹配所有:/*
匹配不包含jsp的所有请求:/
设置加载顺序:load-on-startup
值为-1或者不设置:启动服务器时不加载,访问时加载
值大于等于0:启动时加载,值越小越先加载
使用注解:
@WebServlet(name = "hs", value = {"/hs"}, loadOnStartup = 0)
name:指定servlet的名字
value:设置url,可替换为urlPatterns,作用与value相同但不能同时使用
loadOnStartup:设置启动时加载Servlet的顺序
5. HttpServletRequest和HttpServletResponse
HttpServletRequest主要方法:

getParameter读取对应键的值
setCharacterEncoding设置读取流文件时的编码方式
req.setCharacterEncoding("utf-8");
String name = req.getParameter("name");

HttpServletResponse主要方法:

setHeader(name,value)设置响应头
setContentType(String)设置响应文件类型,响应文件编码
setCharacterEncoding(String)设置服务器端响应内容编码格式
getWriter()获取字符输出流
  1. 乱码问题的解决
    产生乱码的原因:默认情况下,客户端以utf-8编码发送数据,服务器端的request使用ISO8859-1接受数据;服务器端的response使用ISO8859-1发送数据,而客户端使用GB2312接收数据。
    解决方法:
接收数据时将接收的数据按ISO8859-1转化为字节流,再将字节流以utf-8的形式编码或者设置request的编码方式为utf-8
发送数据时设置response的编码方式为utf-8并且通知客户端也以utf-8的形式接收数据
/*.....接收数据......*/
//第一种方式
String name = req.getParameter("name");
name = new String(name.getBytes("ISO8859-1"),"utf-8");
//第二种方式
req.setCharacterEncoding("utf-8");
String name = req.getParameter("name");
/*.....接收数据......*/
//第一种方式
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("utf-8");
//第二种方式
resp.setHeader("Content-type","text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
  1. 转发和重定向
req.getRequestDispatcher("/login.html").forward(req,resp);

转发由服务器实现,转发实现web应用内的跳转,转发是实现请求的转发。在同一次请求中,HttpRequest对象在多次转发后仍然能够访问。

resp.sendRedirect("http://baidu.com");

重定向由客户端实现,服务器端将请求的链接发送给客户端,客户端重新访问对应的网站。重定向时服务器端只能返回重定向的链接,想要传输数据时只能在链接的末尾添加信息。

  1. 状态管理
request只在一次请求中有效
cookie存放在客户端,可以设置有效时间
session一次会话中有效,一次会话指的是同一浏览器发送的多次请求,浏览器关闭则这次会话结束
ServletContext服务器启动中有效,作用于整个web应用

cookie的工作过程:服务器创建cookie并通过响应返回给客户端,客户端将cookie存储起来,下一下发送请求时将cookie发送给服务器。

/*......cookie的创建......*/
//创建cookie
Cookie cookie = new Cookie(String, String);
//设置cookie访问路径
cookie.setPath(String);//cookie只有指定访问路径的资源才能访问
//设置cookie的生存时间
cookie.setMaxAge(int);//小于0表示内存存储;等于0浏览器打开;大于0指定生存时间单位为秒
//添加cookie
response.addCookie(cookie);
/*.......cookie的获取.....*/
Cookie[] cookies = request.getCookies();
//获取属性名
cookie.getName();
//获取值
cookie.getValue();
/*......修改cookie........*/
Cookie cookie = new Cookie(String, String);
cookie.setPath();
responset.addCookie(cookie);
cookie的属性名和路径相同的情况下会替换值
/*........Cookie的编码与解码.......*/
//cookie使用的是ASCII码,直接传送会产生乱码
Cookie cookie = new Cookie(URLEncoder.encode(String), URLEncoder.encode(String));
String s1 = (String) URLDecoder.decode(cookie.getName());
String s2 = (String) URLDecoder.decode(cookie.getValue());

session的工作过程,如果浏览器是第一次访问某个web应用,web应用会自动创建一个session保存相关的信息,并且创建一个键为“JSESSIONID ”值为“…”的cookie返回给浏览器,浏览器存储cookie,下次访问这个web应用时会将cookie发送给服务器,服务器通过JSESSIONID来查找对应的session。随着浏览器的关闭,cookie会自动消失,也就是说setMaxAge(0)。

/*............session的获取..........*/
HttpSession session = request.getSession();
//存值
session.setAttribute(String, Object);//可以存任何对象,cookie只能存字符串
//取值
session.getAttribute(String);
//删除属性
session.removeAttribute(String);
//设置有效期
session.setMaxInactiveInterval(int);
//设置session失效
session.invalidate();
/*...........URL重定向..........*/
//用户禁用cookie时浏览器无法获取JSESSIONID,在重定向时可以通过向链接的末尾加入JSESSIONID来解决
//重写链接
String newURL = response.encodeRedirectURL("/...");
response.sendRedirect(newURL));

ServletContext:整个web应用的上下文。

/*.........ServletContext的获取方法..........*/
Servlet context = this.getServletContext();
Servlet context = request.getServletContext();
HttpSession session = req.getSession();
Servlet context = session.getServletContext();
//获取项目真实路径
context.getRealPaht("/");
//获取相对路径
context.getContextPath();
//存储数据
context.setAttribute(String, Object);
//访问数据
context.getAttribute(String);
//删除数据
context.removeAttribute(String);
  1. 过滤器
    客户端发送请求,过滤器拦截请求,处理完后放行给对应的资源,资源处理完后将结果发送给过滤器,过滤器处理完后返回给客户端。
/*..............实现Filter接口..............*/
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    	//拦截前的操作
    	System.out.println("filter before");
    	//放行
        filterChain.doFilter(servletRequest, servletResponse);
        //拦截后的操作
        System.out.println("filter after");
    }
    @Override
    public void destroy() {}
}

配置拦截对象

<filter>
	<filter-name>myfilter</filter-name>
	<filter-class>filter.MyFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>myfilter</filter-name>
	<!--要拦截的目标资源而不是filter的访问路径-->
	<!--*.xxx:匹配特定后缀的资源;/*匹配所有资源;/aaa/*:拦截aaa下的所有-->
	<url-pattern>/target</url-pattern>
</filter-mapping>

配置注解时使用的是@WebFilter(value = “/target”)
使用xml文件配置是,先配置的过滤器先执行,使用注解配置时根据filter的类的全名称的字母顺序执行,xml配置高于注解配置,如果同时配置xml和注解则会创建多个对象。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值