一、什么是Servlet(控制器)
- Servlet是在服务器端运行的Java程序,可以接收客户端请求并做出响应(是个Java程序,运行于服务器端、运行时需要Servlet容器支持)
- Servlet可以动态生成HTML内容对客户端进行响应
二、Servlet与JSP的关系
Servlet与JSP都可以动态生成HTML内容,二者之间是否存在什么联系?
- Test.jsp在运行时首先解析成一个Java类Test_jsp.java,而这个Test_jsp.java继承于org.apache.jasper.runtime.HttpJspBase类,而HttpJspBase又是继承自HttpServlet的类,由此可以得出一个结论,就是JSP在运行时会被Web容器翻译为一个Servlet
三、Servlet类的基本构成
1.初识Servlet
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloServletTest extends HttpServlet {
public void doGet ( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {//继承javax.servlet.http.HttpServlet类
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//Servlet输出HTML标签和内容
out.println("<html>");
out.println(" <head><title>Servlet</title></head>");
out.println(" <body>");
out.println("你好,欢迎来到Servlet世界");
out.println(" </body>");
out.println("</html>");
out.close();
}
}
2.Servlet体系结构
3.Servlet接口
- 定义了所有Servlet需要实现的方法
方法名称 | 功能描述 |
void init (ServletConfig config) | 由 Servlet 容器调用,用于完成Servlet对象在处理客户请求前的初始化工作 |
void service ( ServletRequest req, ServletResponse res) | 由 Servlet 容器调用,用来处理客户端的请求 |
void destroy ( ) | 由 Servlet 容器调用,释放Servlet对象所使用的资源 |
ServletConfig getServletConfig ( ) | 返回ServletConfig 对象,该对象包含此 Servlet 的初始化和启动参数。返回的 ServletConfig 对象是传递给 init( ) 方法的对象 |
String getServletInfo ( ) | 返回有关 Servlet 的信息,比如作者、版本和版权。返回的字符串是纯文本,而不是任何种类的标记(如 HTML、XML等) |
4.GenericServlet抽象类
- 提供了Servlet与ServletConfig接口方法的默认实现(service( )方法除外)
方法名称 | 功能描述 |
public void init ( ServletConfig config ) | 对Servlet接口中init()方法的实现,对ServletConfig实例进行了保存。此方法还有一个无参的重载方法,可用于子类中重写 |
public String getInitParameter (String name ) | 返回web.xml中名称为name的初始化参数的值 |
public ServletContext getServletContext ( ) | 返回ServletContext对象的引用 |
5.HttpServlet抽象类
- 继承自GenericServlet
- 处理HTTP协议的请求和响应
方法名称 | 功能描述 |
public void service ( ServletRequest req, ServletResponse res ) | 对GenericServlet类中service()方法的实现,将请求分发给protected void service (HttpServletRequest req, HttpServletResponse res ) |
protected void service ( HttpServletRequest req, HttpServletResponse res ) | 接收HTTP 请求,并将它们分发给此类中定义的 doXXX( ) 方法 |
protected void doXXX ( HttpServletRequest req, HttpServletResponse res ) | 根据请求方式的不同分别调用的相应处理方法,如doGet()、doPost()等 |
6.ServletConfig接口
- 在Servlet初始化过程中获取配置信息
- 一个Servlet只有一个ServletConfig对象
方法名称 | 功能描述 |
String getInitParameter ( String name ) | 获取web.xml中设置的以name命名的初始化参数值 |
ServletContext getServletContext( ) | 返回Servlet的上下文对象引用 |
7.ServletContext接口
- 获取Web应用上下文,与Servlet容器进行通信(application内置对象即为ServletContext实例)
方法名称 | 功能描述 |
String getInitParameter ( String name ) | 获取名为name的系统范围的初始化参数值,系统范围的初始化参数可在部署描述符中使用<context-param>元素定义 |
void setAttribute (String name, Object object ) | 设置名称为name的属性 |
Object getAttribute ( String name ) | 获取名称为name的属性 |
String getRealPath ( String path ) | 返回参数所代表目录的真实路径 |
void log ( String message ) | 记录一般日志信息 |
8.请求、响应相关接口
9.ServletRequest接口
- 获取客户端请求的数据
方法名称 | 功能描述 |
Object getAttribute ( String name ) | 获取名称为name的属性值 |
void setAttribute ( String name, Object object ) | 在请求中保存名称为name的属性 |
void removeAttribute ( String name ) | 清除请求中名字为name的属性 |
String getCharacterEncoding ( ) | 返回请求体所使用的字符编码 |
void setCharacterEncoding ( String charset ) | 设置请求体的字符编码 |
String getParameter ( String name ) | 返回指定请求参数的值 |
String[ ] getParameterValues ( String name ) | 返回指定请求参数的全部值 |
RequestDispatcher getRequestDispatcher( String path ) | 返回指向指定路径的请求分发对象 |
10.HttpServletRequest接口
- 除了继承ServletRequest接口中的方法,还增加了一些用于读取HTTP请求信息的方法
方法名称 | 功能描述 |
String getContextPath( ) | 返回请求URI中表示请求上下文的路径,上下文路径是请求URI的开始部分 |
Cookie[ ] getCookies( ) | 返回客户端在此次请求中发送的所有cookie对象 |
HttpSession getSession( ) | 返回和此次请求相关联的session,如果没有给客户端分配session,则创建一个新的session |
String getMethod( ) | 返回此次请求所使用的HTTP方法的名字,如GET、POST |
String getHeader( String name ) | 返回指定的请求头信息 |
11.ServletResponse接口
- 设置响应参数和向客户端发送响应数据
方法名称 | 功能描述 |
PrintWriter getWriter ( ) | 返回PrintWriter对象,用于向客户端发送文本 |
String getCharacterEncoding ( ) | 返回在响应中发送的正文所使用的字符编码 |
void setCharacterEncoding ( String charset ) | 设置响应的字符编码 |
void setContentType ( String type ) | 设置发送到客户端的响应的内容类型,此时响应的状态属于尚未提交 |
12.HttpServletResponse接口
- 除了继承ServletResponse接口中的方法,还增加了适用于HTTP响应的新方法
方法名称 | 功能描述 |
void addCookie ( Cookie cookie ) | 增加一个cookie到响应中,这个方法可多次调用,设置多个cookie |
void addHeader ( String name, String value ) | 将一个名称为name,值为value的响应报头添加到响应中 |
void sendRedirect(String location) | 发送一个临时的重定向响应到客户端,以便客户端访问新的URL |
void encodeURL ( String url ) | 使用session ID对用于重定向的URL进行编码 |
四、Servlet的应用
1.Servlet的应用步骤
1)创建Servlet(需要下载servlet-api.jar放到lib文件夹中)
- 继承HttpServlet
- 重写doPost()或doGet()方法(所有请求先到service再到doPost()或doGet()方法,所以可以直接在service方法用反射实现)
定义一个公共控制器来继承HttpServlet
public class BaseController extends HttpServlet {
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
Sysotem.out.println(getClass()); //获取当前类
Sysotem.out.println(HttpServletRequest.class);//获取HttpServletRequest这个类的编译文件
response.setContentType("text/html;charset=UTF-8");//设置相应给客户端的内容类型和编码格式
request.setCharacterEncoding("UTF-8");//设置请求的字符编码格式
String action=request.getParameter("action");//执行控制器方法的参数
Method method=null;//方法类
//获取执行的方法
try {
method=getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);//通过反射找到方法
method.invoke(this,request,response);//调用方法,this就是当前对象
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
public class IndexController extends BaseController {
public void index(HttpServletRequest request, HttpServletResponse response) throws SQLException, ServletException, IOException {
request.setAttribute("news", new NewsServiceImpl().getTopicNews(1));
request.setAttribute("tNews", new NewsServiceImpl().getTopicNews(2));
request.setAttribute("hNews", new NewsServiceImpl().getTopicNews(5));
request.setAttribute("topics",new TopicServiceImpl().getTopicList());
request.getRequestDispatcher("/view/index.jsp").forward(request,response);
}
}
2)部署Servlet
- 编译Servlet到/WEB-INF/classes目录
- 编辑部署描述文件web.xml
<!--创建servlet-->
<servlet>
<servlet-name>UserController</servlet-name>
<servlet-class>cn.gwj.controller.UserController</servlet-class>
</servlet>
<!--映射servlet 访问地址,访问名为Login的servlet上面定义的-->
<servlet-mapping>
<servlet-name>UserController</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>
3)启动Tomcat,访问Servlet
在客户端访问indexServlet:localhost:8080/index.html?action=index
2.使用Servlet实现控制器
- 修改控制器
public class TopicServlet extends HttpServlet {
public void doGet( HttpServletRequest request, HttpServletResponse
response ) throws ServletException, IOException {
... ...
String opr = request.getParameter( "opr" );
TopicsService topicsService = new TopicsServiceImpl();
String contextPath = request.getContextPath();
if ( opr.equals( "list" ) ) { //查找所有主题
List<Topic> list = topicsService.getAllTopics();
request.setAttribute( "list", list );
request.getRequestDispatcher (
contextPath + "/newspages/topic_list.jsp" )
.forward( request, response );
}
… …
}
}
<div id="opt_list">
<ul>
<li><a href="../util/news_control.jsp?opr=findTopics">添加新闻</a></li>
<li><a href="../util/news_control.jsp?opr=list">编辑新闻</a></li>
<li><a href="../newspages/topic_add.jsp">添加主题</a></li>
<li><a href="../util/topics?opr=list">编辑主题</a></li>
</ul>
</div>
五、Servlet的生命周期
1.生命周期的各个阶段
2.Servlet的生命周期
六、获取Servlet初始化参数
1.Servlet初始化参数配置(在web.xml文件中配置)
<web-app>
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>demo.servlet.HelloServlet</servlet-class>
<init-param>
<param-name>initParam</param-name>
<param-value>Hello Servlet</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
</web-app>
2.获取初始化参数
public void doGet ( HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("处理请求时,doGet()方法被调用。");
String initParam = getInitParameter( "initParam" );
System.out.println(initParam);
}
七、获取Servlet上下文参数
1.配置Servlet上下文
<web-app>
<context-param>
<!--初始化参数的名字-->
<param-name>contextParam</param-name>
<!--初始化参数的值 -->
<param-value>Hello Servlet</param-value>
</context-param>
<!--省略其他配置-->
</web-app>
2.Servlet上下文参数与初始化参数有何区别?
首先,这两个都叫做初始化参数,只不过servlet初始化参数才在DD配置中包含“init”一词。
上下文初始化参数:
在<web-app>元素中,但不在具体的<servlet>元素中。比如:
<web-app>
<context-param>
<param-name>foo</param-name>
<param-value>bar</param-value>
</context-param>
<!-- other stuff including servlet declarations-->
</web-app>
Servlet初始化参数:
在每个特定的Servlet的<servlet>元素中,比如:
<servlet>
<servlet-name>BeerParamTests</servlet-name>
<servlet-class>TestInitParams</servlet-class>
<init-param>
<param-name>foo</param-name>
<param-value>bar</param-value>
</init-param>
</servlet>
在Servlet代码中调用初始化参数:
上下文初始化参数调用: getServletContext().getInitParameter("foo"); 对Web应用的所有servlet和JSP都可用。
Servlet初始化参数调用:getServletConfig().getInitParameter("foo"); 只对配置了<init-param>的相应servlet可用。
注意:每个servlet有一个ServletConfig,每个Web应用有一个ServletContext.要把初始化参数认为是部署时常量,可用在运行时得到这些初始化参数,但不能设置初始化参数,根本没有setInitParameter().如果修改XML来改变一个初始化参数的值,只有当Web应用重新部署时Web应用其他部分才会看到,因为servlet只会初始化一次,在初始化时会为它提供ServletConfig和ServletContext。
---------------------
作者:dancheren
来源:CSDN
原文:https://blog.csdn.net/dancheren/article/details/53086875
版权声明:本文为博主原创文章,转载请附上博文链接!
3.读取Servlet上下文
public class HelloServlet extends HttpServlet {
// …省略其他代码
public void doGet ( HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException {
System.out.println("处理请求时,doGet()方法被调用。");
String initParam = getInitParameter( "initParam" );
//根据参数名称进行读取
String contextParam = this.getServletContext().getInitParameter( "contextParam" );
System.out.println("Servlet初始化参数" + initParam);
System.out.println("系统初始化参数" + contextParam);
}
}
八、实例
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--创建servlet-->
<servlet>
<!--<servlet-name><servlet-class>不能分开-->
<servlet-name>Login</servlet-name>
<servlet-class>cn.gwj.controller.Login</servlet-class>
<!--设置初始化参数-->
<init-param>
<param-name>zs</param-name>
<param-value>张三</param-value>
</init-param>
<init-param>
<param-name>ls</param-name>
<param-value>李四</param-value>
</init-param>
</servlet>
<!--映射servlet 访问地址,访问名为Login的servlet上面定义的-->
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<!--locahost/demoNews/login.html-->
<!--创建servlet-->
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>cn.gwj.controller.UserServlet</servlet-class>
</servlet>
<!--映射servlet 访问地址,访问名为Login的servlet上面定义的-->
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>
<!--创建servlet-->
<servlet>
<servlet-name>TopicServlet</servlet-name>
<servlet-class>cn.gwj.controller.TopicServlet</servlet-class>
</servlet>
<!--映射servlet 访问地址,访问名为Login的servlet上面定义的-->
<servlet-mapping>
<servlet-name>TopicServlet</servlet-name>
<url-pattern>/admin/topic</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>NewsServlet</servlet-name>
<servlet-class>cn.gwj.controller.NewsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>NewsServlet</servlet-name>
<url-pattern>/admin/new.html</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.gwj.controller.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login.html</url-pattern>
</servlet-mapping>
<!--过滤器-->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>cn.gwj.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>cn.gwj.filter.EncodingFilter</filter-class>
<init-param>
<param-name>en</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>cn.gwj.listener.CountListener</listener-class>
</listener>
</web-app>
- java
package cn.gwj.controller;
/*
Created by IntelliJ IDEA.
Package:cn.gwj.controller
User:1093499975@qq.com
Date:2019/7/1 0001
Time:10:13
*/
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class BaseController extends HttpServlet {
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("UTF-8");
String action=request.getParameter("action");
Method method=null;
try {
method=getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this,request,response);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
package cn.gwj.controller;
/*
Created by IntelliJ IDEA.
Package:cn.gwj.controller
User:1093499975@qq.com
Date:2019/7/1 0001
Time:16:38
*/
import cn.gwj.entity.User;
import cn.gwj.service.impl.UserServiceImpl;
import com.alibaba.fastjson.JSONArray;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
public class UserServlet extends BaseController {
public void add(HttpServletRequest request, HttpServletResponse response){
String uName=request.getParameter("user");
String uPwd=request.getParameter("pwd");
UserServiceImpl userService=new UserServiceImpl();
User user=new User();
user.setuName(uName);
user.setuPwd(uPwd);
if(userService.addUser(user)){
request.setAttribute("msg","注册成功!");
}else {
request.setAttribute("msg","注册失败!");
}
try {
request.getRequestDispatcher("/msg.jsp").forward(request,response); //转发请求 forward方法把请求信息和响应信息传过去
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void checkUser(HttpServletRequest request,HttpServletResponse response){
String name=request.getParameter("uname");
User user=new User();
user.setuName(name);
try {
PrintWriter pw=response.getWriter();
boolean flag=false;
String msg="恭喜可以注册!";
StringBuffer sb=new StringBuffer();
//已有此账号
if(new UserServiceImpl().getUser(user).getId()>0){
flag=true;
msg="该用户已存在!";
}
// sb.append("{");
// sb.append("\"status\":"+flag+",");
// sb.append("\"msg\":"+"\""+msg+"\"");
// sb.append("}");
//
// pw.println(sb);
//第二种方式转化json字符串
Map map=new HashMap();
map.put("status",flag);
map.put("msg",msg);
pw.println(JSONArray.toJSONString(map));
} catch (IOException e) {
e.printStackTrace();
}
}
public void show(HttpServletRequest request,HttpServletResponse response){}
}