持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
Request和Response
Request:获取请求数据
Response:设置相应数据
@WebServlet({"/demo03","/demo04"})
public class demo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//使用req对象 获取请求数据
String name = req.getParameter("name");
//使用resp对象 设置相应数据
resp.setHeader("content-type","text/html;charset=utf-8");
resp.getWriter().write("<h1>"+name+",欢迎你!</h1>");
}
Request继承体系
1.Tomcat需要解析请求数据,封装为request对象, 并且创建request对象传递到service方法中
2.使用request对象,查阅JavaEE API文档的 HttpServletRequest接口
请求数据分为三部分
post:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取post请求体:请求参数
//1.获取字符输入流
BufferedReader reader = req.getReader();
//2.读取数据
String line = reader.readLine();
System.out.println(line);
}
<form action="/tomcat1/demo04" method="post">
<input name="username"><input type="submit">
</form>
通用方式获取请求参数
为了简化代码,将2者获取请求参数的方式统一起来
Request通用方式获取请求参数
Map<String,String[]>getParameterMap()的代码演示
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get...");
//1.获取所有参数的map集合
Map<String, String[]> map = req.getParameterMap();
for (String key:map.keySet()) {
//username:zhangsan
System.out.println(key+":");
//获取值
String[] values = map.get(key);
for(String value:values){
System.out.print(value+" ");
}
System.out.println();
}
String[ ] getParameterValues(String name)的代码演示
//2.根据key获取参数值,数组
String[] hobbies = req.getParameterValues("hobby");
for(String hobby:hobbies){
System.out.println(hobby);
}
String getParameter(String name)的代码演示
//3.根据key获取单个参数值
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
既然通用,那么在doPost使用上述代码也可以完成相应业务
请求参数中文乱码处理
Post的解决方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//post解决中文乱码的问题
req.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
System.out.println(username);
}
get的解决方法
//get解决中文乱码的问题:编码:1.转换为字节数据
//2.把字节数组转为字符串,解码
String s = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
System.out.println(s);
该方法也可以解决post的乱码问题
Request请求转发
请求转发(forward):一种在服务器内部的资源跳转方式
实现方式
请求转发资源间共享数据:使用Request对象
请求转发特点:
浏览器地址栏路径不发生变化
能转发到当前服务器的内部资源
一次请求,可以在转发的资源间使用request共享数据
Response
相应数据分为三部分
Response完成重定向
重定向:
一种资源跳转方式
重定向的图解
重定向方式1:
//重定向
//1.设置相应状态码302
resp.setStatus(302);
//2.设置相应头
resp.setHeader("Location","resp2");
System.out.println("resp1...");
重定向方式2:
resp.sendRedirect("resp2");
重定向特点:
与请求转发的特点几乎相反,因此需要具体场景具体分析使用哪种方法
路径问题
路径给浏览器使用:需要加虚拟目录
服务端使用:不需要加虚拟目录
response响应字符数据
//1.获取字符输出流
PrintWriter writer = resp.getWriter();
//content-type
resp.setHeader("content-type","text/html");
writer.write("<h1>aaa</h1>");
}
上述代码可以解析html代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//1.获取字符输出流
PrintWriter writer = resp.getWriter();
//content-type
writer.write("<h1>aaa</h1>");
}
上述代码是上上述代码的优化,可以解决中文乱码问题
PS:该流不需要关闭
response响应字节数据
//1.读取文件
FileInputStream fis = new FileInputStream("d://小哀.jpg");
//2.获取response字节输出流
ServletOutputStream os = resp.getOutputStream();
//3.完成流的copy
byte[] buff = new byte[1024];
int len = 0;
while((len=fis.read(buff))!=-1){
os.write(buff,0,len);
}
fis.close();
也能导入坐标使用
案例:用户登录
流程说明: 1.用户填写用户名密码,提交到LoginServlet
2.在LoginServlet中使用MyBatis查询数据库,验证用户名密码是否正确
3.如果正确,响应“登录成功”,如果错误,响应“登录失败”
准备环境:
1.复制资料中的静态页面到项目的webapp目录下
2.创建db1数据库,创建tb_user表,创建User实体类
3.导入MyBatis坐标,MySQL驱动坐标
4.创建mybatis-config.xml核心配置文件,UserMapper.xml映射文件,UserMapper接口
5.在UserMapper中
//根据用户名和密码查询用户对象
@Select("select * from tb_user where username = #{username} and password = #{password}")
User select(@Param("username") String username, @Param("password")String password);
6.最关键的在servlet中重写doGet方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.接收用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
//2.调用Mybatis完成查询
//2.1获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.2获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//2.3获取Mapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//2.4调用方法
User user = mapper.select(username, password);
//2.5释放资源
sqlSession.close();
//3.判断user是否为null
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
if(user!=null){
//登录成功
writer.write("登录成功");
}else {
writer.write("登录失败");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
用户注册
流程说明: 1.用户填写用户名、密码等信息,点击注册按钮,提交到RegisterServlet
2.在RegisterServlet中使用MyBatis 保存数据
3.保存前,需要判断用户名是否已经存在:根据用户名查询数据库
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.接收用户数据
String username = req.getParameter("username");
String password = req.getParameter("password");
//封装用户对象
User user = new User();
user.setUsername(username);
user.setPassword(password);
//2.调用mapper根据用户名查询用户对象
//2.1获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.2获取sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//2.3获取Mapper
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//2.4调用方法
User u = mapper.selectByUsername(username);
//3.判断用户对象是否为null
if(u==null){
//用户名不存在,添加用户
mapper.add(user);
//提交事务
sqlSession.commit();
sqlSession.close();
}else {
//用户名存在,不能添加
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("用户名已存在");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
//根据用户名查询对象
@Select("select * from tb_user where username = #{username}")
User selectByUsername(String username);
//添加用户
@Insert("insert into tb_user values(null,#{username},#{password})")
void add(User user);
}
代码优化
创建SqlSessionFactory代码优化
上述方式存在问题:
1.代码重复:解决方法:工具类
2.SqlSessionFactory工厂只创建一次,不要重复创建:解决方法:静态方法
public class SqlSessionFactoryUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
//静态代码块会随着类的加载而自动执行,且只执行一次
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory(){
return sqlSessionFactory;
}
}
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
上述在servlet中的代码改成下述代码即可
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();