发表于: 2018-03-07 23:29:23

1 657


完成

1.新写了一个登出页面,用到了删除cookie

setMaxAge方法设置cookie经过多长秒后被删除。如果参数是0,就说明立即删除。如果是负数就表明当浏览器关闭时自动删除。如果没有设定cookie的age可以用getMaxAge方法来查看cookie的默认存活时间。

@RequestMapping(value = "/logout", method = RequestMethod.GET)
public String Seven(HttpServletRequest request, HttpServletResponse response) {
   Cookie[] cookies = request.getCookies();
   for (int i = 0; i < cookies.length; i++) {
       if (cookies != null) {
           if (cookies[i].getName().equals("Token")) {
               cookies[i].setMaxAge(0);
               cookies[i].setPath("/");
               response.addCookie(cookies[i]);
           }

       }
   }
   return "d";
}


2.学习servlet

什么是servlet?

处理请求和发送响应的过程是由一种叫做Servlet的程序来完成的,并且Servlet是为了解决实现动态页面而衍生的东西。理解这个的前提是了解一些http协议的东西,并且知道B/S模式(浏览器/服务器)。

tomcat和servlet的关系

Tomcat 是Web应用服务器,是一个Servlet/JSP容器. Tomcat 作为Servlet容器,负责处理客户请求,把请求传送给Servlet,并将Servlet的响应传送回给客户.而Servlet是一种运行在支持Java语言的服务器上的组件. Servlet最常见的用途是扩展Java Web服务器功能,提供非常安全的,可移植的,易于使用的CGI替代品。

从http协议中的请求和响应可以得知,浏览器发出的请求是一个请求文本,而浏览器接收到的也应该是一个响应文本。但是在上面这个图中,并不知道是如何转变的,只知道浏览器发送过来的请求也就是request,我们响应回去的就用response。

①:Tomcat将http请求文本接收并解析,然后封装成HttpServletRequest类型的request对象,所有的HTTP头数据读可以通过request对象调用对应的方法查询到。

②:Tomcat同时会要响应的信息封装为HttpServletResponse类型的response对象,通过设置response属性就可以控制要输出到浏览器的内容,然后将response交给tomcat,tomcat就会将其变成响应文本的格式发送给浏览器

servlet的生命周期

服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该servlet时,就会初始化一个Servlet对象,也就是会执行初始化方法init(ServletConfig conf)

该servlet对象去处理所有客户端请求,在service(ServletRequest req,ServletResponse res)方法中执行最后服务器关闭时,才会销毁这个servlet对象,执行destroy()方法

我写了一个servlet例子

@WebServlet(name = "Demo")
public class Demo extends HttpServlet {
   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

   }

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       //设置网页响应类型
       response.setContentType("text/html;charset=UTF-8");
       //实现具体操作
       PrintWriter out = response.getWriter();

       Map<String, String> data = getData();
       try {
           // Write some content
           out.println("<html>");
           out.println("<head>");
           out.println("<title>Demo</title>");
           out.println("</head>");
           out.println("<body>");
           out.println("<h2>Servlet Demo at " + request.getContextPath() + "</h2>");
           out.println("<h2>Hello " + data.get("username") + ", " + data.get("message") + "</h2>");
           out.println("<h2>The time right now is : " + new Date() + "</h2>");
           out.println("</body>");
           out.println("</html>");
       } finally {
           out.close();
       }
   }

   //This method will access some external system as database to get user name, and his personalized message
   private Map<String, String> getData() {
       Map<String, String> data = new HashMap<>();
       data.put("username", "Guest");
       data.put("message", "Welcome to my world !!");
       return data;
   }
}

运行结果如下

 

我们发现Demo是继承HttpServlet的

public class Demo extends HttpServlet

为什么创建的servlet是继承自httpServlet,而不是直接实现Servlet接口?

进入HttpServlet可以看到:

public abstract class HttpServlet extends GenericServlet {

接着进入GenericServlet,可以看到继承了Servlet,ServletConfig

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {

GenericServlet类可以看到,Servlet生命周期的三个关键方法,init、service、destroy。还有另外两个方法,一个getServletConfig()方法来获取ServletConfig对象,ServletConfig对象可以获取到Servlet的一些信息

再看看Servlet类,

ServletConfig类,其中主要关注:ServletContext对象是servlet上下文对象,功能有很多,获得了ServletContext对象,就能获取大部分我们需要的信息,比如获取servlet的路径,等方法。

到此,就知道了Servlet接口中的内容和作用,总结起来就是,三个生命周期运行的方法,获取ServletConfig,而通过ServletConfig又可以获取到ServletContext。

而GenericServlet实现了Servlet接口后,也就说明我们可以直接继承GenericServlet,就可以使用上面我们所介绍Servlet接口中的那几个方法了,能拿到ServletConfig,也可以拿到ServletContext,不过那样太麻烦,不能直接获取ServletContext,所以GenericServlet除了实现Servlet接口外,还实现了ServletConfig接口,那样,就可以直接获取ServletContext了。

servlet的生命周期中,可以看出,执行的是service方法,为什么我们就只需要写doGet和doPost方法呢?

我们看HttpServlet类,可以看到划红线的就是之前例子里调用的方法,doGet,  doPost

其中调用的参数类型为HttpServletRequest , HttpServletResponse ,

而service方法的参数是ServletRequest和ServletResponse。

Service方法里

可以看到ServletRequest和ServletResponse对象被转换为httpServletRequest和HttpServletResponse对象,之后再调用service(HttpServletRequest req, HttpServletResponse resp)方法。

这个方法就是判断浏览器过来的请求方式是哪种,每种的处理方式不一样,我们常用的就是get,post,并且,我们处理的方式可能有很多的内容,所以,在该方法内会将get,post等其他5种请求方式提取出来,变成单个的方法,然后我们需要编写servlet时,就可以直接重写doGet或者doPost方法就行了,而不是重写service方法,更加有针对性。

结论:当通过继承HttpServlet来创建一个Servlet时,我们只需要根据要处理的请求的类型,来重写不同的方法。处理get请求,则重写doGet();处理post请求,则重写doPost()。


问题

我把包含拦截器的war包放到服务器,访问报错如下,说我53行空指针错误,代码如下

但过不了多久又可以打开所需页面了???

还有一点,这个项目在本地跑没问题。。。

Type Exception Report
Message Request processing failed; nested exception is java.lang.NullPointerException
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:980) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859) javax.servlet.http.HttpServlet.service(HttpServlet.java:635) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) javax.servlet.http.HttpServlet.service(HttpServlet.java:742) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Root Cause
java.lang.NullPointerException com.wlj.Interceptor.SpringMVCInterceptor.preHandle(SpringMVCInterceptor.java:53) org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:134) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:954) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:859) javax.servlet.http.HttpServlet.service(HttpServlet.java:635) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) javax.servlet.http.HttpServlet.service(HttpServlet.java:742) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
Note The full stack trace of the root cause is available in the server logs.


收获

对servlet的了解加深了些

alt+7看工具类,接口结构


任务5总结

任务名称:Java=task5

成果连接:http://39.107.103.103:8080/HelloWeb2/

任务耗时:5天

技能脑图:

官方:



总结:

a.任务要求最多3天,我用了5天,包含做任务和温故知新。

b.脑图两者的内容相差不大,就是一些规范表达不会用,如通信协议,开发模式,安全。

c.过程中发现自己比较懒,像Token我直接定义了一串字符,虽然我也查到了JWT方法但是懒得去实现;还有就是我花了半天时间去看DES算法,结果现在也没怎么弄懂,有点遗憾;最后就是war包在本地,服务器分别跑,各有一个问题没解决(数据库连接异常和空指针异常)。




返回列表 返回列表
评论

    分享到