看视频自学Servlet

来源:互联网 发布:浙江大学海洋学院,知乎 编辑:程序博客网 时间:2024/05/01 03:14

(一)如何创建一个Servlet

1.继承 GenericServlet

代码:

public class ServletDemo1 extends GenericServlet{@Overridepublic void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {res.getOutputStream().write("Hello servlet!".getBytes());}}

web.xml中配置

  <servlet>    <servlet-name>ServletDemo1</servlet-name>    <servlet-class>com.boom.servlet.ServletDemo1</servlet-class>    <load-on-startup>1</load-on-startup>  </servlet>  <servlet-mapping>    <servlet-name>ServletDemo1</servlet-name>    <url-pattern>/ServletDemo1</url-pattern>  </servlet-mapping>

2.继承 HttpServlet

代码:

public class ServletDemo2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getOutputStream().write("Hello HttpServlet!".getBytes());}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

web.xml

  <servlet>    <description></description>    <display-name>ServletDemo2</display-name>    <servlet-name>ServletDemo2</servlet-name>    <servlet-class>com.boom.servlet.ServletDemo2</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>ServletDemo2</servlet-name>    <url-pattern>/ServletDemo2</url-pattern>  </servlet-mapping>

(二)用new 键 新建Servlet 包含(init方法,destory方法),web.xml文件就不需要配置了

代码:

public class ServletDemo3 extends HttpServlet {//servlet  方法只 调用一次@Overridepublic void init() throws ServletException { // TODO Auto-generated method stubsuper.init();System.out.println("init");}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.getOutputStream().write("Hello HttpServlet!".getBytes());}/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}@Overridepublic void destroy() {System.out.println("destroy");}}

web.xml不用配置了

(三)线程安全问题
1.静态变量的使用导致线程安全问题,静态变量尽量少使用

代码:

/** * 线程安全出现在多个线程操作同一资源上,就是静态的使用要慎重 * @author Boom * */public class Person {//如果不是静态变量的时候,当多个线程使用时用到的age是不同的,不会有线程安全public int age;//如果是静态变量,因为静态变量在类加载的时候都会创建,每个线程都是用到同一个对象,当同一个对象被多个线程使用时,就会产生线程并发事件// public static int age;//在开发中,用静态要小心,可能会造成内存奔溃public List list = new ArrayList();//public static List list = new ArrayList();}
/** * 线程安全 * @author Boom * */public class Demo {//假设100个线程跑这个方法,看age的状态public static void main(String[] args) {Person person = new Person();person.age++;//person.list.add("aaa");System.out.println(person.age);}}

2.实现SingleThreadModel接口解决线程安全问题

代码:

/** * 在web开发中,我们不用同步代码块去解决并发事件,而是通过实现一个接口SingleThreadModel(不太建议),就是打个标记 * 这种接口叫做标记接口,同理的有序列化接口,就是标记这个类有特权 * @author Boom *Servlet就像一个网页,当出错了,我们就要抓起来 */public class ServletDemo5 extends HttpServlet implements SingleThreadModel {/** * 线程安全问题 *///在这里初始化数据会出现并发事件int i=0; //子类在覆盖父类的方法,不能抛出比父类更多的异常 (子类要比父类强,形象的说就是父亲做东西抛出了异常,子类又要比父类强我们就不能在子类抛更多的异常)protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {i++;try {Thread.sleep(1000*4);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//String.getBytes(); 把字符串输入到字节流中response.getOutputStream().write((i+"").getBytes());}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

3.用同步代码块synchronized(this){}解决线程安全问题

代码:

public class ServletDemo4 extends HttpServlet {/** * 线程安全问题 */int i=0; //在这里初始化数据会出现并发事件protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//假设100个人同时操作这个dOGet()方法 ,会不会出现并发问题//在方法内部定义初始化不会出现线程并发事件//int i=0;//同步代码块,单线程执行//用线程锁解决线程并发问题,但是这种方法不行,如果一个线程正在访问一个资源,而另一个也要等第一个线程访问完才执行获取资源synchronized(this){i++;try {Thread.sleep(1000*4);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//String.getBytes(); 把字符串输入到字节流中response.getOutputStream().write((i+"").getBytes());}}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

(四)ServletConfig

/** * ServletConfig * 在配置文件中定义数据,在java中获取(使用情况:在实际开发中,有些数据不适合在servlet中写死,这类数据就可以通过配置方式配置给servlet, * 例如:servlet采用哪个码表,servlet连接哪个库,servlet就配置哪个配置文件) * @author Boom *  其实,struts就是一个特殊的servlet */public class ServletDemo6 extends HttpServlet {//方法一/*    private ServletConfig servletConfig;        @Override    public void init(ServletConfig config) throws ServletException {    this.servletConfig=config;    String value = servletConfig.getInitParameter("data");    System.out.println(value);    }*/    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//String value = servletConfig.getInitParameter("data");  方法一//方法二String value = this.getServletConfig().getInitParameter("data");//得到指定的Enumeration em = this.getServletConfig().getInitParameterNames();while (em.hasMoreElements()) {String name = (String) em.nextElement();String value1 =this.getServletConfig().getInitParameter(name);System.out.println(name+"="+value);}    System.out.println(value);response.getOutputStream().write("Hello HttpServlet!".getBytes());}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubdoGet(request, response);}}

(五)ServletContext

/** * ServletContext 以及ServletDemo8 多个servlet之间传值(相当于聊天室)示例 * @author Boom * ServletContext说的就是整个应用程序的范围  在多个servlet中共享数据 */public class ServletDemo7 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//得到ServletContext的方式一:ServletContextcontext = this.getServletConfig().getServletContext();//得到ServletContext的方式二://ServletContextcontext1 = this.getServletContext();String data="aaa";context.setAttribute("data",data);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

(六)使用ServletContext 多个servlet之间传值

/** * 多个servlet之间传值(相当于聊天室) * @author Boom *  */public class ServletDemo8 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//应用场景  之前给每个servlet都配置数据连接,我们可以直接通过context域配置数据库连接String value1 =this.getServletContext().getInitParameter("data1");String value = (String) this.getServletContext().getAttribute("data");System.out.println(value);}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

(七)Servlet中不适合对数据进行输出,我们要应用Servlet的转发

/** * Servlet中不适合对数据进行输出,我们要应用Servlet的转发 * @author Boom * ServletDemo9和ServletDemo10 */public class ServletDemo9 extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String value =this.getServletContext().getInitParameter("data1");//Servlet数据输出比较麻烦,我们通过转发来实现  让jsp实现// servlet的重定向是让他自己去做// Servlet的转发是让我来帮他找人做response.getOutputStream().write(("<font color='red'>"+value+"</font>").getBytes());}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

(八)同过servletcontext实现请求转发,每个web应用都有一个servletcontext

/** * 同过servletcontext实现请求转发,每个web应用都有一个servletcontext * Servlet的转发 ServletDemo9和ServletDemo10 * @author Boom * 转发对象     RequestDispatcher */public class ServletDemo10 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {String data="aaaaa";this.getServletContext().setAttribute("dt", data);  //不能放在context域中,为什么呢?(涉及多线程问题,就是用的是同一对象,会覆盖数据)//把数据放到context域对象中,并转发给jsp去实现界面RequestDispatcher rd= this.getServletContext().getRequestDispatcher("/1.jsp");rd.forward(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}

(九)读取资源文件 

1.通过ServletContext访问资源文件 db.propertis

/** * 读取资源文件 通过ServletContext访问资源文件 db.propertis *  * @author Boom * */public class ServletDemo11 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {test5();}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}//在项目的相对路径src下新建db.properties文件public void test1() throws IOException {InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");// 固定套路 (把流输出到properties中)Properties properties = new Properties();properties.load(in);String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");System.out.println(url);System.out.println(username);System.out.println(password);}//在com.boom.thread包下新建db.properties文件public void test2() throws IOException {InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/boom/thread/db.properties");// 固定套路 (把流输出到properties中)Properties properties = new Properties();properties.load(in);String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");System.out.println(url);System.out.println(username);System.out.println(password);}//在WEB-INF下新建db.properties文件public void test3() throws IOException {InputStream in = this.getServletContext().getResourceAsStream("/db.properties");// 固定套路 (把流输出到properties中)Properties properties = new Properties();properties.load(in);String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");System.out.println(url);System.out.println(username);System.out.println(password);}//读取资源文件需要注意的问题(但是我们得在tomcat的bin文件考入文件db.properties,才能实现)  最好采用servletcontext来读取资源文件public void test4() throws IOException {FileInputStream in = new FileInputStream("classes/db.properties");// 固定套路 (把流输出到properties中)Properties properties = new Properties();  //mapproperties.load(in);String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");System.out.println(url);System.out.println(username);System.out.println(password);}public void test5() throws IOException{String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");String filename=path.substring(path.lastIndexOf("\\")+1);System.out.println(filename);FileInputStream in=new FileInputStream(path);// 固定套路 (把流输出到properties中)Properties properties = new Properties();  //mapproperties.load(in);String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");System.out.println(url);System.out.println(username);System.out.println(password);}}


2.如果读取资源文件的程序不是servlet的话,就只能通过类加载器去读了

代码:

新建一个UserDao

/** * 类装载器 * 如果读取资源文件的程序不是servlet的话,就只能通过类装载器去读了 * @author Boom * */public class UserDao {//把东西放到预编译中,在类加载时就生成了,而且只有一次private static Properties dbconfig = new Properties();static{try {//针对如果修改了配置文件中的数据,查看运行后的输出  方案一:无论文件中怎么改还是原来的//以下代码虽然可以读取资源文件的数据,但是无法获取更新后的数据InputStream in = UserDao.class.getClassLoader().getResourceAsStream("db.properties");//方案二:修改后,数据也跟着修改了//String path = UserDao.class.getClassLoader().getResource("db.properties").getPath();//FileInputStream inputStream  = new FileInputStream(path); //获取文件中的东西dbconfig.load(in);} catch (IOException e) {//抛一个初始化错误throw new ExceptionInInitializerError(e);}}//不能传入一个servletcontext对象,避免耦合public void update() throws IOException {System.out.println(dbconfig.getProperty("url"));System.out.println(dbconfig.getProperty("username"));System.out.println(dbconfig.getProperty("password"));}public void find(){}public void delete(){}/** * 总结:读取资源文件 * 1.在servlet中,我们可以通过servletcontext去读取资源文件的数据 * 2.在其他类中,我们需要通过类加载器去读取资源文件的数据 *  */}

新建测试类

/** * 如果读取资源文件的程序不是servlet的话,就只能通过类加载器去读了 * @author Boom * */public class ServletDemo12 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {UserDao userdao =new UserDao();userdao.update();}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}


0 0
原创粉丝点击