前言
作为一个Java web开发者,掌握sshi等框架是必要的技能,但是用多了框架也要回过头来看看最土的,最原始的servlet。毕竟mvc框架(struts1/2,springmvc)都是源于它的。
搭建servlet项目
那么首先要回忆servlet相关知识,不是去看书,最好最直接的办法就是直接打开IDE搭建个简单的项目。
1.打开IDE新建个web项目,一般来说只要你的IDE有装jdk和tomcat就无需引入任何jar包了(不准备涉及任何数据库操作)。
2.在WEB-INF下新建web.xml文件,先把schema写好,不知道怎么写直接网上复制一下。
3.开始写servlet,具体来说就是写个自己的XXServlet extends HttpServlet,并override两个必要的方法doGet和doPost就可以了,有心的同学可以把service、destroy、init方法都简单的实现下,最好在console打印下以便了解这些方法的执行顺序。
4.写好servlet后,要到刚才的web.xml中配置一下,也就是servlet+servlet-mapping,这步有个稍微要注意的就是servlet-mapping中的url-pattern,要知道什么模式匹配什么样的url。大概有三种:
①
完全匹配,不解释如:"/test/list.do"。
②
目录匹配:也就是以*结尾的如:"/"或者"/*"或者"/test/*"。
③
扩展匹配:以*开头的如:"*.do"。
还有一个要注意的就是load-on-startup这个值一般可以不写,不写的话,tomcat会在使用到的时候才去实例化,而写一个大于0的数的话就会在tomcat启动的时候就实例话,所以一般来说只有在tomcat启动时候需要使用的servlet才写,比如web.xml中默认配置的org.apache.catalina.servlets.DefaultServlet和org.apache.jasper.servlet.JspServlet这两个servlet就是分别是1和3。
这种配置的麻烦在于每写一个servlet就要来这边配置一次,很是繁琐。
5.开始写jsp文件,这里一直有个纠结的地方,就是jsp文件是放在webRoot下还是放在WEB-INF下面,其实,这是没有规定的,放在WEB-INF下面比较安全,直接全路径访问是会报404错误的,放在WebRoot下面比较方便,安全方面就用filter去配置权限。写jsp的时候一般都知道要在头部加上一句
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
这句话的意思就是当前页面的上下文类型以及编码格式,并且支持java。其他的和html就差不多了。
6.这几步弄好就可以启动项目了,相当简单吧。
servlet和jsp的跳转
一、从Jsp发送请求到servlet(比如request.getContextPath()值是/appname)
①、全路径访问,如:/appname/index.jsp
二、从servlet跳转Jsp
①、request.getRequestDispatch("index.jsp").forword(req, res);//相对路径
②、response.sendRedirect(requst.getContextPath() + "/index.jsp");//绝对路径
参数传递以及EL表达式
一、jsp传递到servlet
①、url传递,如list.do?limit=10,servlet中通过request.getParamter("limit")获取
②、form传递,servlet中也是通过request.getParamter("xx")获取
二、servlet传递到jsp
①、request.setAttribute()
②、session.setAttribute()
三、jsp接收参数
①、<%= session.getAttribute()%>或<%= request.getAttribute()%>
②、EL表达式:如${info}。它会依次到page、request、session、application中查找,找到则返回,找不回返回null。 <%@ page isELIgnored="true" %>可以启用禁用el表达式,且默认是启用的。
深入servlet和线程安全
servlet是单例多线程的,意思就是初始化(init:可以传入ServletConfig对象,然后用getInitParamter获取)一次之后,后面如果要使用它的服务(service),tomcat就会找到它来用而不会新建一个。那么这就要求我们在实现servlet的时候注意线程安全的问题。当tomcat要销毁(destroy)它的时候,注意在destroy里释放用到资源。
下面主要来说说怎么保证servlet的线程安全。
①、首先一点init是tomcat执行的,它是单线程的,所以是线程安全的,所以只要考虑的是service();
②、service方法中如果只涉及到本地变量(也就是局部变量和参数),那么就是线程安全的,为什么这么说:jvm的每个线程每执行一个方法就为该方法创建一个栈帧并压入栈中,也就是说栈帧内的本地变量不是线程共享的,所以说线程安全。
③、如果service方法访问(这里的访问是指有读又有写,如果只是仅仅读了那么完全不需要担心线程安全问题)了这三种:servlet的成员变量、全局静态变量、全局静态资源(系统文件之类的)等,就需要加上同步控制语句了(这里不展开了。。。其实我自己也没用过。。逃)。
④、destroy和init一样,是单线程的,在服务器重启的时候或者长时间不用的时候,都会被销毁。