Java Servlet

Servlet

开发流程

编写一个java类,直接实现HttpServlet接口或者通过扩展实现这个这个接口的类
重写HttpServlet类的doGet方法和doPost方法
配置web.xml文件,或者使用注解对servlet进行配置

Servlet是一个接口,如何继承这个接口,就需要实现接口中的所有的方法。而HttpServlet继承了这个接口,就代表已经实现了关于Servlet的所有接口,并且比较规范和实用。我们只需要通过HttpServlet中的doPost()和doGet()方法去实现业务逻辑既可以。

流程
客户端发送请求至服务器
服务器依据Servlet映射找到对应的Servlet
Servlet依据客户端请求生成响应内容并将其传给服务器
服务器将响应返回客户端

网页->url-pattern->servlet-name->servlet-class->解释字节码->响应

servlet配置

使用web.xml配置

<!--
	注册servlet
	使用标签:<servlet>
	<servlet-name>:名称,为这个servlet起名
	<servlet-class>:路径
-->

	<servlet>
	<servlet-name>ServletDemo</servlet-name>
	<servlet-class>mian.java.com.servlet.test.ServletDemo</servlet-class>
	</servlet>

<!-- 
	servlet映射
	<servlet-name>确定使用哪一个servlet
	<url-pattern>浏览器访问的路径,要求/开头且名称唯一
 -->
	<servlet-mapping>
    	<servlet-name>ServletDemo</servlet-name>
    	<url-pattern>/ServletDemo</url-pattern>
  	</servlet-mapping>

public class ServletDemo implements Servlet{
}

使用注解配置

@WebServlet("/test")
public class test extends HttpServlet {

}

生命周期

@WebServlet("/test")
public class test implements Servlet {
	@Override
	public void init(ServletConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
	}
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}
	@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 service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
		// TODO Auto-generated method stub
		
	}

第一次请求:
调用构造函数
获取init()方法
调用init,服务器创建ServletConfig对象,作为实参
获取service()方法
调用service,服务器创建ServletRequse和ServletResponse,作为实参

第二次请求
从缓存中获取class
获取service方法↓
调用service服务器先创建ServletRequest ServletResponse

服务器关闭
获取class
获取destory方法
调用

init( ),service( ),destroy( )是Servlet生命周期的方法。代表了Servlet从“出生”到“工作”再到“死亡 ”的过程。Servlet容器(例如TomCat)会根据下面的规则来调用这三个方法:
1.init( )方法,当Servlet第一次被请求时Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用。我们可以利用init( )方法来执行相应的初始化工作。调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化。例如数据库连接初始化。
2.service( )方法,每当请求Servlet时,Servlet容器就会调用这个方法。第一次请求时,Servlet容器会先调用init( )方法初始化一个Servlet对象出来,然后会调用它的service( )方法进行工作,但在后续的请求中,Servlet容器只会调用service方法了。
3.destory( )方法,当要销毁Servlet时,Servlet容器就会调用这个方法,在卸载应用程序或者关闭Servlet容器时,就会发生这种情况,一般在这个方法中会写一些清除代码

另外:
getServletInfo( ),这个方法会返回Servlet的一段描述,可以返回一段字符串。
getServletConfig( ),这个方法会返回由Servlet容器传给init( )方法的ServletConfig对象。

GenericServlet

HTTPServlet

	
@WebServlet("/test")
public class test extends HttpServlet {
    public test() {
        super();
        // TODO Auto-generated constructor stub
    }
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

doGet和doPost
不同点一:
通过get方式提交的数据有大小的限制,通常在1024字节左右。也就是说如果提交的数据很大,用get方法就可需要小心;而post方式没有数据大小的限制,理论上传送多少数据都可以。

不同点二:
通过get传递数据,实际上是将传递的数据按照”key,value”的方式跟在URL的后面来达到传送的目的的;而post传递数据是通过http请求的附件进行的,在URL中并没有明文显示。
不同点三:
通过Get方式提交的数据安全性不高,而Post方式的更加安全

Servlet 接口中定义的方法

ServletConfig

当Servlet容器初始化Servlet时,Servlet容器会给Servlet的init( )方式传入一个ServletConfig对象。可以获得配置参数

ServletContext

ServletContext对象表示Servlet应用程序。每个Web应用程序都只有一个ServletContext对象。在将一个应用程序同时部署到多个容器的分布式环境中,每台Java虚拟机上的Web应用都会有一个ServletContext对象。
通过在ServletConfig中调用getServletContext方法,也可以获得ServletContext对象。
有了ServletContext对象,就可以共享从应用程序中的所有资料处访问到的信息,并且可以动态注册Web对象。前者将对象保存在ServletContext中的一个内部Map中。保存在ServletContext中的对象被称作属性。

1、共享数据
在这个Servlet中保存的数据,可以在另外一个servlet中拿到

主要方法:
setAttribute(String var1, Object var2);
removeAttribute(String var1);
getAttribute(String var1);

    @Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());

		ServletContext context = this. getServletContext();

		String username = "patrick";//数据
		context.setAttribute("username", username);//将一个数据保存在ServletContext中
		
	}
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		ServletContext context = this. getServletContext();
		
		String username = (String)context.getAttribute("username");
		
		resp.getWriter().print("name"+username);
	}

2、获取初始化参数

    <!--配置一些web应用初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>


protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}

3、请求转发

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    System.out.println("进入了ServletDemo04");
    //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径
    //requestDispatcher.forward(req,resp); //调用forward实现请求转发;
    context.getRequestDispatcher("/gp").forward(req,resp);
}
//在服务器内部请求Demo04转到gp,Demo04从gp获取资源

Requset

Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息。

String getContextPath();//返回请求上下文的请求URI部分
Cookie[] getCookies();//返回一个cookie对象数组
String getHeader(String var1);//返回指定HTTP标题的值
String getMethod();//返回生成这个请求HTTP的方法名称
String getQueryString();//返回请求URL中的查询字符串
HttpSession getSession();//返回与这个请求相关的会话对象

获取前端参数并请求转发

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 这里超交的路径,需要寻找到项目的路径
${pageContext.request.contextPath}代表当前的项目
 -->
<form action="form" method="get">
    <span>用户名</span><input type="text" name="username"><br>
    <span>密码</span><input type="password" name="password"><br>
    <span>爱好</span>
    <input type="checkbox" name="hobbys" value="1">阅读
    <input type="checkbox" name="hobbys" value="2">写作
    <input type="checkbox" name="hobbys" value="3">音乐
    <input type="checkbox" name="hobbys" value="4">敲代码
    <br>
    <input type="submit" name="submit">
</form>
 
</body>
</html>
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//设置响应的编码格式为UTF-8编码,否则发生中文乱码现象
    	request.setCharacterEncoding("utf-8");
    	response.setCharacterEncoding("utf-8");
    	//1.获得请求方式
       String method = request.getMethod();
       //2.获得请求的资源相关的内容
      String requestURI = request.getRequestURI();//获得请求URI
       String webName = request.getContextPath();//获得应用路径(应用名称)
       String querryString = request.getQueryString();//获得查询字符串
       //3.获得前端
    	String username = request.getParameter("username");
        String password = request.getParameter("password");
        String hobby = request.getParameter("hobbys");
    	String[] hobbys = request.getParameterValues("hobbys");

    	System.out.println("==========");
    	//后台接收中文乱码问题
    	System.out.println(username);
    	System.out.println(password);
    	System.out.println(hobby);
    	System.out.println(Arrays.toString(hobbys));
    	System.out.println("============");
    	System.out.println(request.getContextPath());
        System.out.println(username+":"+password);
       response.getWriter().write("method(HTTP方法):"+method+"<br>");
       response.getWriter().write("requestURi(请求URI)" + requestURI + "");
       response.getWriter().write("webname(应用名称):<" + webName + "<br>");
       response.getWriter().write("querrystring(查询字符串):" + querryString + "");

        request.getRequestDispatcher("/index.jsp").forward(request,response);
   }

Response

响应

addCookie(Cookie var1);//给这个响应添加一个cookie
addHeader(String var1, String var2);//给这个请求添加一个响应头
sendRedirect(String var1) throws IOException;//发送一条响应码,讲浏览器跳转到指定的位置
setStatus(int var1);//设置响应行的状态码

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;

负责向浏览器发送数据的方法:

下载文件
要获取下载文件的路径
下载的文件名是啥?
设置想办法让浏览器能够支持下载我们需要的东西
获取下载文件的输入流
创建缓冲区
获取OutputStream对象
将FileOutputStream流写入到bufer缓冲区
使用OutputStream将缓冲区中的数据输出到客户端!

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 要获取下载文件的路径
    String realPath = this.getServletContext().getRealPath("/1.png");
    System.out.println("下载文件的路径:"+realPath);
    // 2. 下载的文件名是啥?
    String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
    resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
    // 4. 获取下载文件的输入流
    FileInputStream in = new FileInputStream(realPath);
    // 5. 创建缓冲区
    int len = 0;
    byte[] buffer = new byte[1024];
    // 6. 获取OutputStream对象
    ServletOutputStream out = resp.getOutputStream();
    // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
    while ((len=in.read(buffer))>0){
        out.write(buffer,0,len);
    }

    in.close();
    out.close();
}

实现重定向

B一个web资源收到客户端A请求后,B他会通知A客户端去访问另外-一个web资源C,这个过程叫重定向

response.sendRedirect(location);
重定向到location

resp. setHeader("Location","/r/img");
resp. setstatus (302);

重定向和请求转发
相同点:页面会跳转

cookie&session

保存会话的两种技术
cookie

客户端技术 (响应,请求)
session

服务器技术,利用这个技术,可以保存用户的会话信息,可以把信息或者数据放在Session中

cookie

Cookie[] cookies = req.getCookies(); //获得Cookie
cookie.getName(); //获得cookie中的key
cookie.getValue(); //获得cookie中的vlaue
new Cookie("lastLoginTime", System.currentTimeMillis()+""); //新建一个cookie
cookie.setMaxAge(24*60*60); //设置cookie的有效期
resp.addCookie(cookie); //响应给客户端一个cookie

解码

URLEncoder.encode("name","utf-8")
URLDecoder.decode(cookie.getValue(),"UTF-8")

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
    	request.setCharacterEncoding("utf-8");
    	response.setCharacterEncoding("utf-8");
    	
    	PrintWriter out = response.getWriter();
    	
    	//Cookie,服务端从用户端获取
    	Cookie[] cookies = request.getCookies();//这里返回数组,说明cookie存在多个
    	
    	//判断cookie是否存在
    	if (cookies!=null) {
    		//如果存在
    		out.write("你上一次访问的时间");
    		for (int i=0;i<cookies.length;i++) {
    			Cookie cookie = cookies[i];
    			//获取cookie的名字
    			if (cookie.getName().equals("lastLoginTime")) {
    				//获取值
    				out.write(URLDecoder.decode(cookie.getValue(), "UTF-8"));
    			}
    		}
    		
    	}else {
    		out.write("这是您第一次访问本站");
    	}
    	
    	//服务器给客户响应一个cookie
    	Cookie cookie = new Cookie("lastLoginTime",System.currentTimeMillis()+"");
    	response.addCookie(cookie);
	}

session

Session:

服务器会给每一个用户(浏览器)创建一个Seesion对象;
一个Seesion独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
用户登录之后,整个网站它都可以访问!–> 保存用户的信息;保存购物车的信息……


Session和cookie的区别:

Cookie是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
Session把用户的数据写到用户独占Session中,服务器端保存 (保存重要的信息,减少服务器资源的浪费)
Session对象由服务创建;
使用场景:

保存一个登录用户的信息;
购物车信息;
在整个网站中经常会使用的数据,我们将它保存在Session中

<!--设置Session默认的失效时间-->
<session-config>
    <!--15分钟后Session自动失效,以分钟为单位-->
    <session-timeout>15</session-timeout>
</session-config>

获取session

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		
        //解决乱码问题,设置浏览器响应格式
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
		
		//得到Session
		HttpSession session = request.getSession();

		String name = (String) session.getAttribute("name");

		System.out.println(name);


	}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
        //解决乱码问题,设置浏览器响应格式
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=utf-8");
        
        //得到Session
        HttpSession session = request.getSession();
        //给Session中存东西
        session.setAttribute("name","patrick");
        //session.setAttribute("name",new Person("patrick",1));
        //获取Session的ID
        String sessionId = session.getId();

        //判断Session是不是新创建
        if (session.isNew()){
            response.getWriter().write("session创建成功,ID:"+sessionId);
        }else {
            response.getWriter().write("session以及在服务器中存在了,ID:"+sessionId);
        }

        //Session创建的时候做了什么事情;
//        Cookie cookie = new Cookie("JSESSIONID",sessionId);
//        resp.addCookie(cookie);

    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤影墨客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值