JavaEE基础----Servlet
一、Servlet介绍
Servlet在javaEE中作用很大,javaEE的三大组件分别是Servlet,Filter,Listener。Servlet是服务器中核心处理单元,可以处理不同的请求。
-
使用方法
-
实现Servlet接口
public class HelloServlet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("初始化方法"); } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("服务方法"); } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
这里面涉及到了Servlet的生命周期,这里简单介绍一下:
-
init()
方法,这个是初始化方法,随着servlet被创建时候调用,整个过程中只会开始调用一次。 -
service()
方法,当服务器调用servlet时候,该方法可以提供服务。这个方法在整个过程中,调用一次就会被执行一次。 -
destroy()
方法,该方法是服务器关闭后,当前servlet对象就会被销毁了。这三个就是servlet的出生,人生,死亡的三个阶段,还有两个方法,用的极少,就不介绍了。
-
-
继承GenericServlet抽象类
public class HelloServlet02 extends GenericServlet { @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("我是第二个,GenericServlet"); } }
这个方式,里面只有一个方法
service()
,进源码可以看出,这里只保留了这个方法,其余的做了空实现。这个用的也不多。 -
继承HttpServlet抽象类
这个方法应该是开发中用的最多的方法了
public class HelloServlet03 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet方法"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost方法"); } }
这里可以清晰的看到可以用来处理get和post请求
-
-
相关配置
上面实现了servlet,但是相关配置还没有的话,还是不能使用的。
配置也有两种方法:
-
在
web.xml
中配置:<!--HelloServlet处理--> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> servlet的名称 <url-pattern>/hello</url-pattern> 处理的路径 </servlet-mapping> <servlet> <servlet-name>HelloServlet</servlet-name> servlet的名称 <servlet-class>com.wang.web.HelloServlet</servlet-class> </servlet>
这里面一个servlet可以配置多个路径
-
使用注解:
上面的配置显得 很麻烦,其实说白了,就是需要配置一个路径就完事了,但是我们还是要写很多的标签,还要表明哪个servlet,是不是很繁琐,要是有几十个servlet,是不是很崩溃,这里注解版就很好解决这个问题了,将这个封装起来了,只用通过注解
@WebServlet({"/cs","/css","/ccs"})
来使用:@WebServlet("/as") public class AnnotServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("这是注解版的"); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
这样既省心,又不容易出错。我本人也是比较喜欢用注解版,因为xml我很不喜欢使用。能用注解的我绝对不用xml。
-
二、Request
这里不单独说Request,结合上面提到的
HttpServletRequest
这个创建的参数来说明:
-
获取请求行(了解)
//1.获取请求方式 GET/POST
String m = request.getMethod();
//2.获取虚拟路径,工程访问路径 /req
String contextPath = request.getContextPath();
//3.获取servlet路径 /as
String servletPath = request.getServletPath();
//4.获取get方式的请求参数,
String qs = request.getQueryString();
//5.获取uri :contextPath+servletPath /req/as
String uri = request.getRequestURI();
//6.获取url:http://localhost:80/req/as?name=aa
StringBuffer url = request.getRequestURL();
//7.获取传输协议名 http
String protocol = request.getProtocol();
//8.获取客户端的ip: localhost
String ip = request.getRemoteAddr(); -
获取请求头(了解)
//1.根据头名称获取头值
String userAgent = request.getHeader(“user-agent”);
System.out.println(userAgent);
String referer = request.getHeader(“referer”);
System.out.println(referer);
//2.获取所有头名称
Enumeration hnames = request.getHeaderNames();
while (hnames.hasMoreElements()){
//循环变量迭代器,取出每一个头名称
String name = hnames.nextElement();
//根据头名称获取头值
String value = request.getHeader(name);
System.out.println(name+"–"+value);
} -
获取请求体数据(了解)
//1.从request对象中获取字符流–字符流中包含请求体数据
BufferedReader br = request.getReader();
//2.从字符输入流中读取一行数据—请求体数据
String data = br.readLine();
System.out.println(data); -
获取请求参数(重点)
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>$Title$</title> </head> <body> $END$ <form action="/servlet/aServlet" method="post"> 用户名:<input type="text" name="username" placeholder="请输入用户名"><br> 密码:<input type="password" name="password" placeholder="请输入密码"><br> 爱好:<input type="checkbox" name="hobby" value="游泳">游泳 <input type="checkbox" name="hobby" value="JAVA">JAVA <input type="checkbox" name="hobby" value="Python">Python <br> <input type="submit" value="提交"> </form> </body> </html>
-
根据参数名来获取单个的参数
//获取用户名 String username = request.getParameter("username"); System.out.println("用户名:"+username); //获取密码 String password = request.getParameter("password"); System.out.println("密码是:"+password);
-
获取复选框的参数值,返回数组
//获取爱好 String[] hobbies = request.getParameterValues("hobby"); for (String hobby : hobbies) { System.out.println(hobby); }
-
获取form表单中的所有请求参数名
Enumeration<String> pnames = request.getParameterNames(); while (pnames.hasMoreElements()){ //获取Enumeration集合中的每一个参数名 String name = pnames.nextElement(); //获取单个请求参数--根据参数名 获取参数值 String [] value = request.getParameterValues(name); System.out.println(name+"--"+ Arrays.toString(value)); }
-
获取所有的请求参数和参数值,返回map集合
Map<String, String[]> map = request.getParameterMap(); Set<Map.Entry<String, String[]>> entries = map.entrySet(); for (Map.Entry<String, String[]> entry : entries) { String key = entry.getKey(); String[] value = entry.getValue(); System.out.println(key+"---------->"+ Arrays.toString(value)); }
-
三、转发
在开发的时候我们一个请求并不能在一个servlet完成它的使命,需要其他的servlet,这个时候转发就成了很好的方式了,比如登录时候,登录成功了,我们需要转发到处理登录成功的servlet中进行处理。
使用的方法:request.getRequestDispatcher("/he").forward(request,response);
@WebServlet("/bs")
public class BServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("这里是B的servlet");
request.setAttribute("name","wang");//设置域对象
request.getRequestDispatcher("/cs").forward(request,response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
@WebServlet("/cs")
public class CServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("这是C的servlet");
//获取域对象
String name = (String) request.getAttribute("name");
System.out.println(name);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
四、域对象
这个是和转发结合使用的,具体怎么使用我在上面例子中演示了。这个作用就是在转发过程中传递参数的。比如我们登录时候,获取到用户名和密码,这个时候封装成对象,我们可能后续会用到这些信息,像登录成功会有XXx欢迎你,这个时候我们需要把这个对象放在域对象中,让转发后的可以调出来使用。