day34(V19(实现发表文章的功能),V20(实现动态数据的处理),V21(将html页面存入response),V22(显示所有文章的动态页面,二维码))

day34(V19(实现发表文章的功能),V20(实现动态数据的处理),V21(将html页面存入response),V22(显示所有文章的动态页面,二维码))

1.V19(实现发表文章的功能)

1.主要内容:

1.流程:

1:用户在首页点击发表文章的超链接来到发表文章页面
2:在页面输入文章标题和文章内容并点击发表按钮
3:服务端将该文章保存后响应发表结果页面(成功或失败)

2.实现:

  • 1:在static/myweb下新建对应的页面
    1.1:writeArticle.html 发表文章页面,页面form表单action指定的值"/myweb/writeArticle"
    1.2:article_success.html 发表成功提示页面
    1.3:article_fail.html 发表失败提示页面
  • 2:在com.webserver.controller包下新建处理文章相关的业务类:ArticleController并定义处理发表文章的方法:writeArticle()
  • 3:在com.webserver.entity下新建表示文章的对象:Article并实现序列化接口
  • 4:在writeArticle方法中将表单提交上来的标题和文章内容以Article对象形式序列化到目录articles
    下文件名格式:标题.obj
    保存后响应发表成功。如果标题或内容没有输入则响应发表失败页面。

2.ArticleController(writeArticle())

package com.webserver.controller;

import com.webserver.core.DispatcherServlet;
import com.webserver.entity.Article;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.*;
import java.net.URISyntaxException;

public class ArticleController {
    private static File articleDir;
    private static File root;
    private static File staticDir;

    static {
        try {
            root = new File(DispatcherServlet.class.getClassLoader().getResource(".").toURI());
            staticDir = new File(root, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        articleDir = new File("./articles");
        if (!articleDir.exists()) {
            articleDir.mkdirs();
        }
    }

    /*保存文章*/
    public void writeArticle(HttpServletRequest request, HttpServletResponse response) {
//    1.获取用户输入的信息,即获取form表单上提交的内容
        String title = request.getParameter("title");
        String author = request.getParameter("author");
        String content = request.getParameter("content");

        if (title == null ||author==null|| content == null) {
            File file = new File(staticDir, "/myweb/article_fail.html");
            response.setContentFile(file);
            return;
        }
        System.out.println(title + "," + author + "," + content);
//        2.保存内容
        File articleFile = new File(articleDir, title + ".obj");
         if(articleFile.exists()){//文件存在则说明是重复文章
            File file = new File(staticDir,"/myweb/article_fail.html");
            response.setContentFile(file);
            return;
        }
        try (FileOutputStream fos = new FileOutputStream(articleFile);
             ObjectOutputStream oos = new ObjectOutputStream(fos);
             )
        {
            Article article=new Article(title,author,content);
            oos.writeObject(article);
            /*保存成功*/
            File file=new File(staticDir,"/myweb/article_success.html");
            response.setContentFile(file);
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.Article(新建对象并实现序列化)

package com.webserver.entity;

import java.io.Serializable;

public class Article implements Serializable {
    static final long serialVersionUID =1L;
    private String title;
    private  String author;
    private String content;

    public Article(String title, String author, String content) {
        this.title = title;
        this.author = author;
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Article{" +
                "title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}

2.V20(实现动态数据的处理)

1.主要内容:

1.实现动态数据的处理

  • 以显示用户列表的需求为例:在首页上点击超链接,希望看到的页面上可以体现当前所有注册用户信息.
  • 问题:该页面不能是实现准备好的页面,因为该页面上的数据会随着用户的操作(新注册用户,修改密码等)
    不断变化.我们不可能实时的人为修改页面内容.因此我们需要实现当用户请求这个页面时,将现有的所有
    用户信息获取到并生成一个html页面响应给用户.

静态资源:实现准备好的,数据内容(资源的2进制数据)不会改变的资源.
例如:index.html页面,logo.png图片,或视频或gif图等等都属于静态资源.
动态资源:每次查看该资源时,都由程序临时生成的资源.
例如:动态页面(此版本要实现的),验证码图片等

2.思路:

  • 首页上点击超链接(该链接与form的action一样,由我们指定并由DispatcherServlet配合拦截),
  • 之后DispatcherServlet拦截该请求并调用UserController生成动态页面的方法.
  • 该方法中我们先将所有用户信息读取出来,并拼接一个html代码,拼接过程中将用户数据拼接进去.
  • 然后将拼接好的页面发送给浏览器显示即可.

2.Index.html

    <!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
      <title>我的首页</title>
  </head>
  <body>
      <!--
           <h1>--<h6>:标题,标题独立占一行,分别表示1级-6级标题
           <center>:居中显示,该标签在html5中已经不再建议使用了。
           <input>:输入组件,该组件用来在页面上获取用户的输入。
                   该组件有一个重要的属性:type,用来指定组件的样子。
                   常见的值有:
                   type="text":文本框
                   type="password":密码框
                   type="radio":单选框
                   type="checkbox":复选框
                   type="button":按钮
           <br>:换行
           <a>:超链接,标签中间的文本就是超链接上显示的内容,href属性用于指定点击后
               跳转的路径。
           <table>标签:表格。属性border用于指定边框。
                    <table>标签中包含<tr>标签用于表示行
                    <tr>标签中包含<td>标签用于表示列
                    <td>标签中常见属性:
                    align:对其方式。left左对齐,right右对齐,center剧中对其
                    colspan:跨列合并列,合并是从左向右合并列
                    rowspan:跨行合并列,合并是从上向下合并列
           <img>:图片,属性src用于指定图片的位置。
       -->
      <center>
          <!-- <h1>百度</h1> -->
          <img src="logo.png"><br>
          <input type="text" size="32">
          <input type="button" value="百度一下"><br>
          <!-- 单选框和复选框可以用name属性将其划分为一组,名字相同的为一组。 -->
          <input type="radio" name="gender">男
          <input type="radio" name="gender">女<br>
          <a href="/myweb/reg.html">注册</a><br>
          <a href="/myweb/login.html">登陆</a><br>
          <a href="/myweb/showAllUser">用户列表</a><br>
          <a href="/myweb/writeArticle.html">发表文章</a><br>
          <a href="http://www.taobao.com">淘宝</a>
          <a href="http://www.jd.com">京东</a><br>
          <table border="1">
              <tr>
                  <td>第一列</td>
                  <td>第二列</td>
                  <td colspan="2" align="center">第三列</td>
              </tr>
              <tr>
                  <td>第一列</td>
                  <td rowspan="2">第二列</td>
                  <td>第三列</td>
                  <td>第四列</td>
              </tr>
              <tr>
                  <td>第一列</td>

                  <td>第三列</td>
                  <td>第四列</td>
              </tr>
          </table>
      </center>
  </body>
</html>

3.DispatcherServlet(调用showAllUser())

package com.webserver.core;

import com.webserver.controller.ArticleController;
import com.webserver.controller.UserController;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.File;
import java.net.URISyntaxException;

/**
 * 用于处理请求
 */
public class DispatcherServlet {
    private static File root;
    private static File staticDir;

    static {
        try {
            root = new File(DispatcherServlet.class.getClassLoader().getResource(".").toURI());
            staticDir = new File(root, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    public void service(HttpServletRequest request, HttpServletResponse response) {
        String path = request.getRequestURI();

//        首先判断是否为请求一个业务
        if ("/myweb/reg".equals(path)) {
            System.out.println("开始处理注册!!!!!!!!!!");
            UserController controller=new UserController();
            controller.reg(request,response);
        } else if ("/myweb/login".equals(path)) {
            System.out.println("开始处理登陆!!!!!!!!!!");
            UserController controller=new UserController();
            controller.login(request,response);
        } else if ("/myweb/writeArticle".equals(path)){
            System.out.println("开始处理文章发表!!!!!!!!!");
            ArticleController controller=new ArticleController();
            controller.writeArticle(request,response);
        }else if("/myweb/showAllUser".equals(path)){
            System.out.println("开始处理用户列表的动态页面!!!!!!!!!!!");
            UserController controller=new UserController();
            controller.showAllUser(request,response);
        }else {

            File file = new File(staticDir, path);
            System.out.println("资源是否存在:" + file.exists());

            if (file.isFile()) {//当file表示的文件真实存在且是一个文件时返回true
                response.setContentFile(file);


            } else {//要么file表示的是一个目录,要么不存在
                response.setStatusCode(404);
                response.setStatusReason("NotFound");
                file = new File(staticDir, "root/404.html");
                response.setContentFile(file);

            }
        }

        //测试添加一个额外的响应头
        response.addHeader("Server", "WebServer");

    }
}

4.UserController(showAllUser()方法)

package com.webserver.controller;

import com.webserver.core.DispatcherServlet;
import com.webserver.entity.User;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.*;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;


/*处理与用户相关的操作
 * */
public class UserController {
    private static File userDir;
    private static File root;
    private static File staticDir;

    static {
        try {
            root = new File(DispatcherServlet.class.getClassLoader().getResource(".").toURI());
            staticDir = new File(root, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        userDir = new File("./users");
        if (!userDir.exists()) {
            userDir.mkdirs();
        }
    }

    /*注册页面*/
    public void reg(HttpServletRequest request, HttpServletResponse response) {
        //1.获取用户注册页面上输入的注册信息,获取form表单上提交的内容
          /*
            getParameter传入的值必须和页面表单上对应输入框的名字一致
            即:<input name="username" type="text">
                            ^^^^^^^
                            以它一致
         */
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String nickname = request.getParameter("nickname");
        String ageStr = request.getParameter("age");
        /*必要的验证,要求:
        * 四项不能为null,且一项必须为数字(正则表达式)
        * 否则直接给用户一个注册失败的页面:reg_input_error.html
        * 该页面显示一行字:输入信息有误,注册失败
        *
        * 实现思路:
        * 添加一个分支判断,如果符合上述情况,直接创建一个File对象表示
            错误提示页面,然后将其设置到响应对象的正文上即可。否则才执行下面
            原有的注册操作。
        * */

        if (username == null || password == null || nickname == null || ageStr == null || !ageStr.matches("[0-9]+")) {
            File file = new File(staticDir, "/myweb/reg_input_error.html");
            response.setContentFile(file);
            return;
        }
        int age = Integer.parseInt(ageStr);
        System.out.println(username + "," + password + "," + nickname + "," + ageStr);
        //2.将用户信息保存
        File userFile = new File(userDir, username + ".obj");
          /*
            判断是否为重复用户,若重复用户,则直接响应页面:have_user.html
            该页面剧中显示一行字:该用户已存在,请重新注册
         */
        if (userFile.exists()) {
            File file = new File(staticDir, "/myweb/have_user.html");
            response.setContentFile(file);
            return;
        }
        try (
                FileOutputStream fos = new FileOutputStream(userFile);
                ObjectOutputStream oos = new ObjectOutputStream(fos);
        ) {
            User user = new User(username, password, nickname, age);
            oos.writeObject(user);//保存到硬盘上
            /*注册成功了*/
            File file = new File(staticDir, "/myweb/reg_success.html");
            response.setContentFile(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //3 给用户响应一个注册结果页面(注册成功或注册失败)

    }

    /*处理登陆业务*/
    public void login(HttpServletRequest request, HttpServletResponse response) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        /*如果没有输入信息*/
        if (username == null || password == null) {
            File file = new File(staticDir, "/myweb/login_info_error.html");
            response.setContentFile(file);
            return;
        }
        /*将登录信息与保存的信息对应*/
        File userFile = new File(userDir, username + ".obj");
//                 判断用户是否存在
        if (userFile.exists()) {
            try {
//                反序列化
                FileInputStream fis = new FileInputStream(userFile);
                ObjectInputStream ois = new ObjectInputStream(fis);
                User user = (User) ois.readObject();
//                判断密码
                if (password.equals(user.getPassword())) {
                    File file = new File(staticDir, "/myweb/login_success.html");
                    response.setContentFile(file);
                    return;
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        }

        File file = new File(staticDir, "/myweb/login_fail.html");
        response.setContentFile(file);

    }

    /*处理动态用户列表*/
    public void showAllUser(HttpServletRequest request, HttpServletResponse response) {
        String username = request.getParameter("username");
        //1.先将user里的所有用户提取出来存入list集合列表
        List<User> userList = new ArrayList<>();
            /*
            首先获取users中所有名字以.obj结尾的子项 提示:userDir.listFiles()
            然后遍历每一个子项并用文件流连接对象输入流进行反序列化
            最后将反序列化的User对象存入userList集合

         */

        File[] files = userDir.listFiles(l -> l.getName().endsWith(".obj"));

        for (File userFile : files) {
            try (
                    FileInputStream fis = new FileInputStream(userFile);
                    ObjectInputStream ois = new ObjectInputStream(fis);
            ) {

                userList.add((User) ois.readObject());

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println(userList);

        //2.使程序生成一个页面,将list里的信息全部拼接到列表中
        try (
                PrintWriter pw = new PrintWriter("./userList.html", "UTF-8");
        ) {
            pw.println("<!DOCTYPE html>");
            pw.println("<html lang=\"en\">");
            pw.println("<head>");
            pw.println(" <meta charset=\"UTF-8\">");
            pw.println("<title>用户列表</title>");
            pw.println("</head>");
            pw.println("<body>");
            pw.println("<center>");
            pw.println("<h1>用户列表</h1>");
            pw.println("<table border=\"1\">");
            pw.println("<tr>");
            pw.println("<td>用户名</td>");
            pw.println("<td>密码</td>");
            pw.println("<td>昵称</td>");
            pw.println("<td>年龄</td>");
            pw.println("</tr>");
            for (User user : userList) {
                pw.println("<tr>");
                pw.println("<td>" + user.getUsername() + "</td>");
                pw.println("<td>" + user.getPassword() + "</td>");
                pw.println("<td>" + user.getNickname() + "</td>");
                pw.println("<td>" + user.getAge() + "</td>");
                pw.println("</tr>");
            }
            pw.println("</table>");
            pw.println("</center>");
            pw.println("</body>");
            pw.println("</html>");

            System.out.println("页面生成完毕!");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //3.将设置的页面设置到响应中发送给浏览器
        File file = new File("./userList.html");
        response.setContentFile(file);

    }

}

3.V21(将html页面存入response)

1.主要内容

上一个版本中我们已经实现了动态页面。

1.问题:

  • 将所有的用户记录读取出来并拼接好了html代码,但是需要现将数据写入文件userList.html,然后再
    将该页面设置到response中去。等到response在发送响应式再从该文件中将数据读取出来后作为正文
    响应给浏览器。
  • 这里存在一次浪费,实际上没必要将生成的页面先写入文件再从文件读取出来,若直接将生成的html页面
    数据存入response使其作为正文响应效率会高很多。
    对此,我们要重构HttpServletResponse,使其可以为响应动态数据提供操作。

2.HttpServletResponse(response(),发送响应正文:sendContent())

package com.webserver.http;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 响应对象
 * 该类的每一个实例用于表示HTTP协议要求的响应
 * 每个响应由三部分组成:
 * 状态行,响应头,响应正文
 */
public class HttpServletResponse {
    private Socket socket;
    //状态行相关信息
    private int statusCode = 200;
    private String statusReason = "OK";

    //响应头相关信息
    private Map<String, String> headers = new HashMap<>();

    //响应正文相关信息
    private File contentFile;

    private ByteArrayOutputStream baos;
    private byte[] contentData;//作为响应正文数据的节点数组

    public HttpServletResponse(Socket socket) {
        this.socket = socket;
    }

    /**
     * 将当前响应对象内容按照标准的HTTP响应格式发送给客户端
     */
    public void response() throws IOException {
//        发送前的准备工作
        sendBefore();
        //3.1发送状态行
        sendStatusLine();
        //3.2发送响应头
        sendHeaders();
        //3.3发送响应正文
        sendContent();
    }

    //发送前最后的准备工作
    private void sendBefore() {
//        先判断baos是否为null,不为null说明存在动态数据
        if (baos != null) {
//        得到其内部字节数组(动态数据)
            contentData = baos.toByteArray();
        }
//        如果动态数据不为null,添加响应头Content-Length
        if (contentData != null) {
            addHeader("Content-Length", contentData.length + "");
        }
    }

    /**
     * 发送状态行
     */
    private void sendStatusLine() throws IOException {
        println("HTTP/1.1" + " " + statusCode + " " + statusReason);
    }

    /**
     * 发送响应头
     */
    private void sendHeaders() throws IOException {
        /*
            headers这个Map中的内容:
            key              value
            Content-Type     text/html
            Content-Length   224
            Server           WebServer
            ...              ...
         */
        //遍历headers将所有的响应头发送给客户端
        Set<Map.Entry<String, String>> entrySet = headers.entrySet();
        for (Map.Entry<String, String> e : entrySet) {
            String key = e.getKey();
            String value = e.getValue();
            println(key + ": " + value);
        }

        println("");//单独发送回车换行表示响应头发送完毕了
    }

    /**
     * 发送响应正文
     */
    private void sendContent() throws IOException {
        if (contentData != null) {//有动态数据
            OutputStream out = socket.getOutputStream();
            out.write(contentData);
        } else if (contentFile != null) {

            OutputStream out = socket.getOutputStream();
            try (FileInputStream fis = new FileInputStream(contentFile);) {

                int len;
                byte[] data = new byte[1024 * 10];
                while ((len = fis.read(data)) != -1) {
                    out.write(data, 0, len);
                }
            }

        }
    }


    /**
     * 将一行字符串按照ISO8859-1编码发送给客户端,最后会自动添加回车和换行符
     *
     * @param line
     */
    private void println(String line) throws IOException {
        OutputStream out = socket.getOutputStream();
        byte[] data = line.getBytes(StandardCharsets.ISO_8859_1);
        out.write(data);
        out.write(13);//单独发送了回车符
        out.write(10);//单独发送换行符
    }

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getStatusReason() {
        return statusReason;
    }

    public void setStatusReason(String statusReason) {
        this.statusReason = statusReason;
    }

    public File getContentFile() {
        return contentFile;
    }

    public void setContentFile(File contentFile) {
        this.contentFile = contentFile;
        String contentType = null;

        try {
            contentType = Files.probeContentType(contentFile.toPath());
        } catch (IOException e) {
            e.printStackTrace();
        }
        /*当我们无法根据正文判断类型时,则不发送Content-Type
        在HTTP协议中响应包含正文,但不包含Content-Type时,让浏览器自行判断响应正文内容
        * */
        if (contentType != null) {

            addHeader("Content-Type", contentType);
        }
        addHeader("Content-Length", contentFile.length() + "");
    }

    /**
     * 添加一个要发送的响应头
     *
     * @param name
     * @param value
     */
    public void addHeader(String name, String value) {
        //将响应头的名字和值以key-value形式存入headers这个Map中
        headers.put(name, value);
    }

    public OutputStream getOutputStream() {
        if (baos == null) {
            baos = new ByteArrayOutputStream();

        }
        return baos;
    }

    /**
     * 通过该方法获取的缓冲输出流写出的文本会作为正文内容发送给浏览器
     */
    public PrintWriter getWrite() {
        return new PrintWriter(
                new BufferedWriter(
                        new OutputStreamWriter(
                                getOutputStream(),
                                StandardCharsets.UTF_8
                        )
                ), true
        );
    }

    /**
     *
     */
    public void setContentType(String mine) {
        addHeader("Content-Type", mine);
    }

}

4.V22(显示所有文章的动态页面,二维码)

1.主要内容

1.要求:

  • 首页index.html上有一个超链接,为:文章列表。对应的href="/myweb/showAllArticle"

  • 点击该超链接后,浏览器会看到一个动态页面,该页面为一个表格,2列

    第一列为文章的标题,第二列为文章的作者

2.实现:

  • 1:在index.html上添加超链接
  • 2:在ArticleController中添加一个方法:showAllArticle
    该方法可参考UserController的showAllUser方法来生成动态页面
  • 3:在DispatcherServlet上添加一个分支,如果path的值与该超链接
    一致,则调用showAllArticle方法来生成动态页面

2.ArticleController(showAllArticle())

package com.webserver.controller;

import com.webserver.core.DispatcherServlet;
import com.webserver.entity.Article;
import com.webserver.entity.User;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.*;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;

public class ArticleController {
    private static File articleDir;
    private static File root;
    private static File staticDir;

    static {
        try {
            root = new File(DispatcherServlet.class.getClassLoader().getResource(".").toURI());
            staticDir = new File(root, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        articleDir = new File("./articles");
        if (!articleDir.exists()) {
            articleDir.mkdirs();
        }
    }

    /*保存文章*/
    public void writeArticle(HttpServletRequest request, HttpServletResponse response) {
//    1.获取用户输入的信息,即获取form表单上提交的内容
        String title = request.getParameter("title");
        String author = request.getParameter("author");
        String content = request.getParameter("content");

        if (title == null ||author==null|| content == null) {
            File file = new File(staticDir, "/myweb/article_fail.html");
            response.setContentFile(file);
            return;
        }
        System.out.println(title + "," + author + "," + content);

//        2.保存内容
        File articleFile = new File(articleDir, title + ".obj");
        if(articleFile.exists()){//文件存在则说明是重复文章
            File file = new File(staticDir,"/myweb/article_fail.html");
            response.setContentFile(file);
            return;
        }
        try (FileOutputStream fos = new FileOutputStream(articleFile);
             ObjectOutputStream oos = new ObjectOutputStream(fos);
             )
        {
            Article article=new Article(title,author,content);
            oos.writeObject(article);
            /*保存成功*/
            File file=new File(staticDir,"/myweb/article_success.html");
            response.setContentFile(file);
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*读取文章*/
    public void showAllArticle(HttpServletRequest request,HttpServletResponse response){
//        1.先将article里所有文章提取出来
        List<Article> articleList=new ArrayList<>();
        File[] files=articleDir.listFiles(a->a.getName().endsWith(".obj"));
        for (File articleFile: files){
            try(
                    FileInputStream fis=new FileInputStream(articleFile);
                    ObjectInputStream ois=new ObjectInputStream(fis);
                    ){
                articleList.add((Article) ois.readObject());

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        }
        System.out.println(articleList);
//        2.使主程序生成一个页面,将list里的信息都拼接到列表中
        PrintWriter pw= response.getWrite();
        pw.println("<!DOCTYPE html>");
        pw.println("<html lang=\"en\">");
        pw.println("<head>");
        pw.println("<meta charset=\"UTF-8\">");
        pw.println("<title>文章列表</title>");
        pw.println("</head>");
        pw.println("<body>");
        pw.println("<center>");
        pw.println("<h1>文章列表</h1>");
        pw.println("<table border=\"1\">");
        pw.println("<tr>");
        pw.println("<td>标题名</td>");
        pw.println("<td>作者</td>");

        pw.println("</tr>");
        for (Article article : articleList) {
            pw.println("<tr>");
            pw.println("<td>" + article.getTitle() + "</td>");
            pw.println("<td>" + article.getAuthor() + "</td>");

            pw.println("</tr>");
        }
        pw.println("</table>");
        pw.println("</center>");
        pw.println("</body>");
        pw.println("</html>");

        System.out.println("页面生成完毕!");
//        3.设置响应头Content-Type用于告知动态数据是什么
        response.setContentType("text/html");
    }
}

3.DispatcherServlet

package com.webserver.core;

import com.webserver.controller.ArticleController;
import com.webserver.controller.ToolsController;
import com.webserver.controller.UserController;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.File;
import java.net.URISyntaxException;

/**
 * 用于处理请求
 */
public class DispatcherServlet {
    private static File root;
    private static File staticDir;

    static {
        try {
            root = new File(DispatcherServlet.class.getClassLoader().getResource(".").toURI());
            staticDir = new File(root, "static");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    public void service(HttpServletRequest request, HttpServletResponse response) {
        /*获取路径*/
        String path = request.getRequestURI();

//        首先判断是否为请求一个业务
        if ("/myweb/reg".equals(path)) {
            System.out.println("开始处理注册!!!!!!!!!!");
            UserController controller=new UserController();
            controller.reg(request,response);
        } else if ("/myweb/login".equals(path)) {
            System.out.println("开始处理登陆!!!!!!!!!!");
            UserController controller=new UserController();
            controller.login(request,response);
        } else if ("/myweb/writeArticle".equals(path)){
            System.out.println("开始处理文章发表!!!!!!!!!");
            ArticleController controller=new ArticleController();
            controller.writeArticle(request,response);
        }else if("/myweb/showAllUser".equals(path)){
            System.out.println("开始处理用户列表的动态页面!!!!!!!!!!!");
            UserController controller=new UserController();
            controller.showAllUser(request,response);
        }else if ("/myweb/showAllArticle".equals(path)){
            System.out.println("开始处理文章列表的动态页面!!!!!!!!!!!");
            ArticleController controller=new ArticleController();
            controller.showAllArticle(request,response);
        }else if("/myweb/createQr".equals(path)){
            System.out.println("!!!!!!!!!!!!!!!开始生成二维码");
            ToolsController controller = new ToolsController();
            controller.createQr(request, response);

        }
        else {

            File file = new File(staticDir, path);
            System.out.println("资源是否存在:" + file.exists());

            if (file.isFile()) {//当file表示的文件真实存在且是一个文件时返回true
                response.setContentFile(file);


            } else {//要么file表示的是一个目录,要么不存在
                response.setStatusCode(404);
                response.setStatusReason("NotFound");
                file = new File(staticDir, "root/404.html");
                response.setContentFile(file);

            }
        }

        //测试添加一个额外的响应头
        response.addHeader("Server", "WebServer");

    }
}

1.ToolsController(二维码,添加库)

package com.webserver.controller;

import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;
import qrcode.QRCodeUtil;

import java.io.FileOutputStream;

public class ToolsController {

    public void createQr(HttpServletRequest request, HttpServletResponse response){
        String content = request.getParameter("content");
        System.out.println("content:==========="+content);
        try {
            QRCodeUtil.encode(content,"logo.jpg",response.getOutputStream(),true);
            response.setContentType("image/jpeg");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        String message = "http://doc.canglaoshi.org";
        try {
            //参数1:二维码上包含的文本信息  参数2:图片生成的位置
//            QRCodeUtil.encode(message,"./qr.jpg");
            //参数1:二维码上包含的文本信息  参数2:图片生成后会通过该流写出
//            QRCodeUtil.encode(message,new FileOutputStream("./qr.jpg"));
            //参数1:二维码上包含的文本信息  参数2:二维码中间的logo图片 参数3:图片生成的位置 参数4:是否需要压缩logo图片到中间大小
//            QRCodeUtil.encode(message,"logo.jpg","./qr.jpg",true);

            QRCodeUtil.encode(message,"logo.jpg",new FileOutputStream("./qr.jpg"),true);

            System.out.println("二维码生成完毕!");
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}


posted @ 2022-04-16 13:32  约拿小叶  阅读(177)  评论(0)    收藏  举报