Servlet 之超详解【2023年最新版】(三)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: Servlet 之超详解【2023年最新版】(三)

7.2 响应乱码

分类:

①获得输出流直接写数据

写法如下:

response.addHeader("Content-Type","text/html;charset=utf-8);
//简写
response.setContentType("text/html;charset=utf-8");

不信?请看如下演示:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class ResponseServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //添加响应头以规避中文乱码
//        response.setContentType("text/html;charset=utf-8");
        //输出响应数据流给客户端
        PrintWriter writer = response.getWriter();
        writer.print("<html>");
        writer.print("<head>");
        writer.print("</head>");
        writer.print("<body>");
        writer.print("<h1>success 成功</h1>");
        writer.print("</body>");
        writer.print("</html>");
    }
}

代码整体不变,仅添加一句代码如下所示:

//添加响应头以规避中文乱码
        response.setContentType("text/html;charset=utf-8");
        //输出响应数据流给客户端
        PrintWriter writer = response.getWriter();

②转发

③重定向


八. 案例:连接数据库版的登录注册功能

案例:实现登录注册功能,要和数据库比对

8.1 注册功能

步骤:

①搭建环境

  1. 导入jar包(数据库驱动包、数据库连接池、DBUtils),放在WEB-INF下的lib目录下

  2. 创建]DBCTools和BaseDao

  3. 数据库连接池的配置文件(放到src目录下)

  4. 在MySQL中创建users表格
  5. 创建实体类(User)

②编写注册功能

  1. 创建注册页面
  2. 创建UsersDAOlmpl
  3. 创建Registe’rServlet

这里提供部分代码:

package DAO;
import bean.users;
import java.sql.SQLException;
public class UsersDAOlmpl extends BaseDAOImpl implements UsersDAO {
    @Override
    public users findUserByUsername(String username) {
        String sql="select * from users where username=?";
        try {
            return getBean(users.class, sql, username);
        } catch (Exception e) {
           throw new RuntimeException(e);
        }
    }
    @Override
    public boolean addUser(users user) {
        String sql="insert into users values(null,?,?,?)";
        try {
            int len = update(sql, user.getUsername(), user.getPassword(), user.getEmail());
            if (len>0){
                return true;
            }
            return false;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
package DAO;
import bean.users;
public interface UsersDAO {
    //注册
    //根据用户名来查找相应的用户信息
    users findUserByUsername(String username); //登录
    //添加用户
    boolean addUser(users user);
}

8.2 登录功能

步骤:

  1. 创建登录页面
  2. 创建UsersDAOlmpl
  3. 创建LoginServlet

8.3 实现效果

①测试注册功能

②测试登录功能


九. 使用Beanutils优化代码

简介:

Beanutils是一个Java库,提供了一组实用类,用于处理JavaBeans。JavaBeans是遵循特定约定的Java类,例如具有默认构造函数和用于其属性的getter和setter方法。Beanutils提供了在JavaBeans之间复制属性、将属性值转换为字符串以及执行其他与JavaBeans相关的常见任务的方法。 它是Apache Commons项目的一部分,被广泛用于Java应用程序中。

功能:

自动将map集合中的数据映射到javaBean内

使用条件:

Map集合中的key值必须和javaBean中的属性名一致,不然不一致的那个key值映射不进去

使用步骤:

  1. 导入jar包
    ①复制下面的三个jar包,然后粘贴至要应用的本地动态web项目中Web/WEB-INF/lib下


    ②在lib目录中选中刚才的三个jar包,右击打开–> Add as Library --> Create Library里选相应的参数


  2. 直接使用Beanutils调用方法即可

案例如下:对上述连接数据库版的登录注册功能的案例中的注册功能使用Beanutils进行优化

代码演示如下:

import DAO.UsersDAOlmpl;
import bean.users;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.ServletException;
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.util.Map;
public class RegistServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理注册业务
      /*  String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
        //数据库中user表的uid字段是自增长列
        users user=new users(null,username,password,email);*/
        //使用BeanUtils,减少代码冗余,这样即使注册表单中有300个name属性值,我也不用一个个手动输入,然后再一一添加进user对象里,那样代码量太大
        Map<String, String[]> parameterMap = req.getParameterMap();//map集合中的key值是表单中的name属性值
        users user=new users();
        try {
            BeanUtils.populate(user,parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        UsersDAOlmpl dao=new UsersDAOlmpl();
        users userByUsername = dao.findUserByUsername(user.getUsername());
        if (userByUsername==null){
            dao.addUser(user);
            req.getRequestDispatcher("regist_success.html").forward(req,resp);
        }else {
            req.getRequestDispatcher("regist_error.html").forward(req,resp);
        }
    }
}

十. web项目的路径问题 ★

10.1 url(常用)

释义:

统一资源定位符(从整个网络环境中找一个资源),例如http://localhost:9999/day06_servlet_war_exploded/login.html

相对路径相对于ur1去作为参照物

绝对路径url就是绝对路径(从ip地址开始)

涉及到路径的位置有:

  • 网页中的超链接、表单、link、img、script…
  • 转发
  • 重定向
  • web.xml

注意:

在web项目内,路径前添加/,采用的是绝对路径

建议使用绝对路径,因为绝对路径一旦写死,不管该资源上有多少个上级目录,依然可以找到,若用相对路径,则要时刻注意该资源的上级目录的变化

/代表什么含义?

  1. 服务器解析
从当前项目下开始找  例如http://localhost:9999/day06_servlet_war_exploded/
  1. ①web.xml
    例如:
<!--  设置访问loginservlet的路径  /login  -->
<servlet>
    <servlet-name>loginServlet</servlet-name>
    <servlet-class>t1.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>loginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>
  1. 上述样例设置LoginServlet的访问路径是直接从项目下访问login
<!--  设置访问loginservlet的路径  /abc/login  -->
<servlet>
    <servlet-name>loginServlet</servlet-name>
    <servlet-class>t1.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>loginServlet</servlet-name>
  <url-pattern>/abc/login</url-pattern>
</servlet-mapping>
  1. 上述样例设置Loginservlet的访问路径是从项目下要先找到abc,然后从abc下找login就能找到LoginServlet
    ②转发
    例如:
//建议使用绝对路径
request.getRequestDispatcher("/second").forward(request,response);
//http://localhost:9999/day06_servlet_war_exploded/second
  1. 浏览器解析
从当前服务器下去找  例如:在 http://localhost:9999/ 下去找
  1. ①网页内所有的路径(超链接、表单、link、img、script…)
    ②重定向
    代码举例如下:
response.sendRedirect("second");//不加/,默认前面是./second
//重定向是在浏览器里解析,它是从当前服务器下去找,即http://localhost:9999/second去找,绝对找不到,遂报404
/*
解决方案:在second前面加上/day06_servlet_war_exploded/,这样就是在当前项目下去找second,一定能找到
即从http://localhost:9999/day06_servlet_war_exploded/second去找
但是这样写有一个弊端,若修改了上下文路径,代码里也得改,比较麻烦,扩展性不是很好
推荐这样写,即动态的获取上下文路径+/second
response.sendRedirect(request.getContextPath()+"/second");
*/

总结:

路径前加/,就是使用绝对路径 /的含义,由服务器解析就是当前项目下,由浏览器解析就是当前服务器下,网页内和重定向路径的/由浏览器解析。转发和web.ml中的/由服务器解析

10.2 uri(极少用)

释义:

统一资源标识符(从当前项目下找一个资源)

例如

/day06_servlet_war_exploded/login.html

在名为day06_servlet_war_exploded的war包(在服务器上部署的web项目)下去找login.html


相关文章
|
7月前
|
安全 Java 应用服务中间件
Servlet 教程 之 Servlet 简介 1
Servlet是运行在Web服务器上的Java程序,用于处理HTTP请求,充当浏览器和服务器间的中间层。它们接收用户输入,与数据库交互并动态生成网页。相比CGI,Servlet性能更优,运行在服务器地址空间内,跨平台且受安全管理器保护,可访问全部Java类库。
36 0
|
7月前
|
XML 安全 Java
Servlet 教程 之 Servlet 简介 3
Servlet是运行在Web服务器上的Java程序,用于处理HTTP请求和响应,与数据库或应用交互。相比CGI,Servlet性能更优,平台无关,并受服务器安全管理器保护。它们主要任务包括读取客户端数据、处理信息、生成结果及发送响应。Servlet利用javax.servlet和javax.servlet.http包构建,遵循Java Servlet 2.5和JSP 2.1规范,可被编译成Java类运行。
51 1
|
7月前
|
XML 缓存 安全
Servlet 教程 之 Servlet 简介 2
Servlet是Java编写的Web服务器程序,用于处理HTTP客户端请求和与服务器/数据库交互。相比CGI,Servlet性能更优,平台无关,并受服务器安全管理系统保护。Servlet的主要任务包括读取表单数据、处理HTTP请求、访问数据库、生成结果及发送响应。它们可以与applets、数据库或其他软件通信,支持多种文档格式。
36 1
|
7月前
|
Java 应用服务中间件 API
Servlet 教程 之 Servlet 调试 2
Servlet调试常面临挑战,建议采用日志记录,推荐使用log4J。Servlet API的`log()`方法也能辅助调试,如示例代码所示,通过`ServletContext`记录消息。当参数缺失时,它能生成带有异常的日志。Tomcat容器会将这些日志保存在安装目录的logs文件夹下,有助于识别和追踪错误。在不常见异常的catch块中使用`log()`函数是良好实践。
61 8
|
7月前
|
小程序
Servlet 教程 之 Servlet 调试 3
Servlet调试是开发中的挑战,涉及复杂交互且错误难复现。使用JDB调试器,将HttpServer视为Servlet响应HTTP请求的调试目标。调试时,需配置调试器的classpath以包含HttpServer、Servlet及其相关类。为启用Servlet重载,通常将`server_root/servlets`加入classpath,但在调试时此规则有助于在加载Servlet前设置断点。在正确配置后,可在Servlet代码中设定断点,通过浏览器请求该Servlet以启动调试,程序会在断点处暂停。
68 6
|
7月前
|
缓存 小程序 Java
Servlet 教程 之 Servlet 调试 6
Servlet调试涉及大量客户端/服务器交互,常带来困难。使用JDB调试器调试HttpServer来模拟HTTP请求,需设置正确类路径,包括servlet和相关类,以及servlet和支撑类的路径。通过在Servlet代码中设置断点,通过浏览器触发请求进行调试。注释法也可辅助调试,通过暂时移除部分代码观察bug变化。查看HTTP头信息对理解Servlet行为有帮助。关键技巧包括:注意classes目录不重载,强制浏览器刷新避免缓存,确保servlet的init()方法正确处理ServletConfig。
52 3
|
7月前
|
Java
Servlet 教程 之 Servlet 调试 1
Servlet调试常面临挑战,尤其是复杂的客户端/服务器交互导致的错误。`System.out.println()`是常用的调试工具,用于验证代码执行和显示变量值,尤其在无需额外类的环境中,如Servlet、JSP等。它不会中断程序执行,适合时序关键的场景。调试信息会出现在Web服务器日志中,例如:`System.out.println(&quot;Debugging message&quot;)`。
48 2
|
7月前
|
Unix 应用服务中间件 Linux
Servlet 教程 之 Servlet 包 1
Servlet教程介绍了Servlet应用程序的打包部署。默认存放于&lt;Tomcat-installation-directory&gt;/webapps/ROOT,类文件在WEB-INF/classes。例如,Servlet类com.myorg.MyServlet应置于WEB-INF/classes/com/myorg/MyServlet.class。
40 0
|
7月前
|
小程序 Java
Servlet 教程 之 Servlet 调试 4
Servlet调试教程提供了使用JDB调试器的技巧。设置调试器类路径以包含HttpServer和Servlet相关类,以及Servlet本身及其支持类。在Servlet代码中设置断点,通过浏览器访问触发调试。注释法也是调试工具,通过临时移除代码段来定位问题。当bug消失时,检查所注释的代码以找到根源。
36 0
|
7月前
|
小程序 Java
Servlet 教程 之 Servlet 调试 5
Servlet调试是开发中的挑战,涉及复杂客户端/服务器交互。使用JDB调试器来调试HttpServer,调整类路径以包含Servlet和相关类。设置断点并在浏览器中调用Servlet以触发调试。注释代码以帮助定位问题。检查HTTP头信息对解决Servlet未按预期工作的问题也很有帮助。
42 0