servlet的创建方式
1.servlet简介
servlet是一个专门用来接收客户端发送过来的请求的小的web程序,servlet的本质是一个类。
这个接口是JAVA官方写的,实现类是我们自己来实现,当然实现servlet的实现类需要一些参数,这些参数是tomcat接收了前端的信息,发送到了servlet(实现流程,前端可以识别xml,所以前端发送给xml,xml发送给tomcat,tomcat解析了xml然后发给了servlet)。
所以可以总结一下xml的功能
1.接收浏览器发送过来的消息
2.给浏览器返回消息,浏览器可以识别html,可以动态去输出html
2.创建servlet
1.实现servlet接口
首先我们得确定一点,所有的编码必须是UTF-8,否则会出现乱码问题。
当然实现一个接口,我们需要重写接口里的方法。我们可以发现接口里面有五个方法
我们先一步一步的来,先只看Service方法
package testWeb;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class FirstServlet implements Servlet{
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("这是我的第一个servlet");
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
当我们写完service之后,由于我们现在还在学习阶段,所以xml需要我们自己配置,所以我们找到web.xml在里面进行配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>testWeb.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/first</url-pattern>
</servlet-mapping>
</web-app>
这里我们要分两个步骤
1.让tomcat认识JAVA
我们解释一下里面的标签《servlet-name》里面存放的是个字符串,能看到和我们刚才servlet的名字是一样的通过我们前面的讲解,tomcat解析获取了里面的字符串,然后《servlet-class》中存放的是类的全类名,还是tomcat进行解析xml获取字符串,然后反射有个class.forName(全类名),这样就可以获取这个类对象,既然获取了类对象我们就可以调用类的方法例如类里的service方法。
2.让浏览器认识tomcat
为了保证一直所以《servlet-name》里面的字符串和上面的一样都是servlet的名字,然后需要去写url-pattern 注意需要加 /
那这个url在哪可以使用呢,首先保证我们的项目在tomcat里面启动了,由于我们现在是在使用自己tomcat所以端口号写的是localhost:8080,这个是tomcat默认使用的端口号,然后输入我们的项目名,接下来输入我们的url-pattern,最后应该长这个样子
不要直接运行servlet,现在运行则会404,然后我们回到JAVA控制台,接下来我们会发现在控制台输出了我们service里面的输出语句,每访问一次就会输出一次。
那浏览器认识java的流程是什么呢,我们刚才在最后输入了/first,他会在xml里面的《url-pattten》找,然后找到了,接着发现这个《servlet-mapping》里面还有一个《servlet-name》,然后他解析了这个字符串,去《servlet》寻找有没有相同的《servlet-name》发现有了,然后就去解析里面的《servlet-class》得到了字符串,然后class.forName(全类名)获取反射对象,然后调用了service方法,在控制台输出了我们在service方法里面编写的输出语句。
2.继承GenericServlet
GenericServlet这个类是个抽象类,所以不是所有方法都是抽象方法,我们只需要实现部分方法即可,所以在创建之后我们可以惊讶的发现只需要重写一个service方法。
package testWeb;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class SecondServlet extends GenericServlet{
private static final long serialVersionUID = 1L;
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
但是我们会发现有个黄叹号,这是为什么呢,因为我们现在在网络编程对吧,他的本质是个流对吧,而且是一个对象流,tomcat帮我们实现了序列化接口,所以我们要给他实现一个序列化,但是如果你不提供他就走默认了。
然后我们重复上面的操作这里就不过多解释了
<servlet>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>testWeb.SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/second</url-pattern>
</servlet-mapping>
这个时候运行就可以在Servlet里面右键运行了,虽然html页面是空白,但是控制台可以正确输出刚才的输出语句。
但我们还是觉得很麻烦,所以有了另一种创建servlet的方式
3.继承HttpServlet
那我们还是先创建一个类,然后让他继承HttpServlet
package testWeb;
import javax.servlet.http.HttpServlet;
public class ThirdServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
}
然后还是上面的流程,配置xml
<servlet>
<servlet-name>ThirdServlet</servlet-name>
<servlet-class>testWeb.ThirdServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>THirdServlet</servlet-name>
<url-pattern>/third</url-pattern>
</servlet-mapping>
这个时候我们可以直接右键运行,然后我们就会发现一个问题
这是为什么呢,那我们看看源代码。
我们可以发现他重写了service方法
直接抛出了一个错误405,所以我们必须要自己重写service方法。
然后我们就生成一个重写的service方法
package testWeb;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ThirdServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// TODO Auto-generated method stub
super.service(req, resp);
}
}
我们会发现有个方法是 super.service(req,resp),我们一定要把这个方法删除,因为他调用了父类的service方法,如果不删除这句代码,不管怎么样都会报405异常。所以我们改一下。
package testWeb;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ThirdServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("这是我的第三个servlet");
}
}
接下来右键运行,然后我们可以发现控制台输出了刚才的输出语句
但是,我们还是觉得这样子创建servlet非常的麻烦,所以我们还有更加简单的方法
4.在2.5版本的项目里面创建servlet
我们刚才的操作都是创建了一个类,然后让他实现接口或者继承其他类来重写service方法,但是我们还有个更简单的方法
我们可以在刚才的包下面直接创建一个servlet
这个时候不要急,我们要点next 不要点击finish 因为还没有配置完
这里有一个URL mapping 我们双击进行更改,改为我们想要更改的路径。
这里我把他改为了/hello 一定要记得加斜杠啊
然后继续点击next进入下面的界面
这里我们只需要重写service方法即可
然后就可以点击finish了
我们可以直接在这把TODO改为输出语句并运行,发现控制台也有输出语句
这个时候我们去看看web.xml你可以发现,他自动帮我们配置了xml,我们就可以不需要自己写了
5.在3.1版本中创建servlet
首先我们要找到一个3.1版本的动态web项目,然后和刚才的流程一样,创建一个servlet,然后重写他的service方法,但是我们仔细一点就可以发现
这里面增加了一个注解,反而我们的xml中没有代码了,这是通过webservlet这个注解实现了之前的功能, 这里我们可以点一下,看一下源代码怎么写的
我们发现他是一个runtime的注解,可以被反射识别 ,直接识别这个里面的字符串,这个注解里面的字符串就是我们之前在servlet里面的url-pattern,然后因为这个servlet属于这个类,所以就不需要全类名了
需要我们注意的是,我们已经有了注释,这个时候我们再去xml里面配置,服务器是会报错的,直接就启动不了
这种情况,我们需要删一个,但是注解少写了这么多代码,肯定是删xml啊。当然这是作者的暴论,没有任何参考价值。