(4)没有编码问题,数据在链接中,tomcat8以上会用UTF-8处理;
2.post请求:
特点:
(1)请求数据不在地址栏,而在请求体中;
(2)原则没有长度限制,取决于浏览器的设置;
(3)两次请求;
(4)post的数据放到请求体里面,请求体的内容,tomcat拿到后不处理,直接放request请求体中;
结论:post请求和get请求的区别
(1)post请求更安全(不会作为url的一部分,不会被缓存、保存在服务器日志、以及浏览器浏览记录中,get请求的是静态资源,则会缓存,如果是数据,则不会缓存)
(2)post请求发送的数据更大(get请求有url长度限制,http协议本身不限制,请求长度限制是由浏览器和web服务器决定和设置)
(3)post请求能发送更多的数据类型(get请求只能发送ASCII字符),但是后端需要处理编码问题
(4)传参方式不同(get请求参数通过url传递,post请求放在request body中传递)
(5)get请求产生一个TCP数据包;post请求产生两个TCP数据包(get请求,浏览器会把http header和data一并发送出去,服务器响应200返回数据;post请求,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 返回数据)
注意:
- 直接在浏览器地址栏输入链接,不通过表单发送的请求,也是get请求。
- 那我们什么时候用get,什么时候用post呢?一般如果是要找服务器查询数据用get,如果给服务器提交登陆注册等信息用post。
- 如果是post发送的数据有特殊字符和中文,后端需要使用req.setCharacterEncoding(“UTF-8”);来设置编码
编码设置代码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
响应response
服务器如果要返回数据怎么办?,我们学习web要清楚,一切的请求信息,都在request对象中,一切的响应,都是由response对象来处理。
// 解决中文的显示问题
response.setCharacterEncoding("UTF-8"); // 设置成编码
response.setContentType("text/html;charset=utf-8"); // 展示的方式
response.getWriter().write("<h2>inputSuccess<h2>");
1.用户登陆前端显示一段话
response.getWriter().write();方法
如何实现用户登陆的业务逻辑:
用户登陆的服务,注意不能用log
1.username + password 查询对象出来,对象有,登陆成功,否则失败;
2.查询数量出来,1成功,否则失败;
3.【建议】springSecurity 推荐,用username 查一个对象;
3.1 查不到,登陆失败(没有注册过,数据库无这个用户名);
3.2 查到了,用户名正确,就用这一条记录的密码和前端发送的密码对比;
如果正确,登陆成功,不登录失败;
package com.tianju.web.servlet.user;
import com.tianju.web.entity.User;
import com.tianju.web.service.IUserService;
import com.tianju.web.service.impl.UserServiceImpl;
import com.tianju.web.util.StringUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/\*\*
\* 用户登陆的服务,注意不能用log
\* 1.username + password 查询对象出来,对象有,登陆成功,否则失败;
\* 2.查询数量出来,1成功,否则失败;
\* 3.【建议】springSecurity 推荐,用username 查一个对象;
\* 3.1 查不到,登陆失败(没有注册过,数据库无这个用户名);
\* 3.2 查到了,用户名正确,就用这一条记录的密码和前端发送的密码对比;
\* 如果正确,登陆成功,不登录失败;
\*/
@WebServlet("/loginUserNew")
public class LoginServlet extends HttpServlet {
private IUserService userService = new UserServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决编码的问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
// 获取前端传来的用户名
String username = req.getParameter("username");
String password = req.getParameter("password");
if (StringUtils.isBlank(username) || StringUtils.isBlank(password)){
resp.getWriter().write("<h1>必填项为空</h1>");
return;
}
// 登陆错误,重新输入
User user = userService.findByUsername(username);
if (user==null || !password.equals(user.getPassword())){
resp.getWriter().write("<h1>用户名|密码错误</h1>");
return;
}
String out = "<h1>用户名"+user.getUsername() +"/"+ user.getNickname() +"登陆成功"+"</h1>";
resp.getWriter().write(out);
}
}
2.如何在前端显示一张表
(1)登陆成功----跳转到首页;response request 可以一定程度解决;
(2)查询所有用户信息;jsp——>ajax-axios【主流】——>thymelaf
方案:在servlet中把前端拼出来,放到resp.getWriter().write(out);中进行显示:
转发和重定向
1.请求转发—request
有人来咨询,转给对接咨询的人,请求——>前台(servlet)——>咨询(servlet)
特点:一次性,共享数据
请求转发是指一个请求到服务器后,第一个Servlet接收到这个请求,可以把这个请求再发送给下一个处理的Servlet或者资源,整个过程中,都只有一个请求,比如我们去饭店点餐,下单后,服务员收到请求,发送给厨师,厨师做好后,给端菜的服务员,最终到我们收里,这整个过程,处理的其实是一个请求。Servlet也类似。
req.getRequestDispatcher(“/b”).forward(req,resp);
@WebServlet("/a")
public class AServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//把请求"/a"转发到"/b"
req.getRequestDispatcher("/b").forward(req,resp);
}
}
转发过程中,也可以共享A数据,比如A处理完以后,可以在一个请求内共享数据,然后要交给B处理,B 也可以获取共享的数据。如下:
@WebServlet("/a")
public class AServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//共享一个菜名
req.setAttribute("name","鱼香肉丝");
//把请求"/a"转发到"/b"
req.getRequestDispatcher("/b").forward(req,resp);
}
}
在转发的下一个Servlet中,获取这个菜名
@WebServlet("/b")
public class BServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("name","鱼香肉丝");
//把请求"/a"转发到"/b"
req.getRequestDispatcher("/b").forward(req,resp);
}
}
@WebServlet("/b")
public class BServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = (String)req.getAttribute("name");
System.out.println(name);
}
}
注意转发(forward)的特点:
- 转发地址栏路径不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,可以使用request对象来共享数据
- 转发由request控制
2.响应重定向----response
特点:值不共享,浏览器的地址变化
重定向的意思是:第一次请求到达服务器后,服务器处理完成,可以在响应信息中告诉浏览器去下一个地址,浏览器会自动请求下一个路径。这个过程中浏览器发送了两次请求。从这里可以看出重定向是由响应response发起的。
resp.sendRedirect("/day01/demo2");
重定向的特点:redirect
- 地址栏发生变化,因为浏览器要访问重定向的地址
- 重定向可以访问其他站点(服务器)的资源
- 重定向是两次请求。不能使用request对象来共享数据
- 重定向由response控制
【需求】表格显示在网页
方案一:把网页拼出来—本质是用response
resp.getWriter().write(sb.toString());
package com.tianju.web.servlet.bookType;
import com.tianju.web.entity.BookType;
import com.tianju.web.service.IBookTypeService;
import com.tianju.web.service.impl.BookTypeServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/\*\*
\* 把图书类型表格拼出来,显示到页面上
\*/
@WebServlet("/bookTypes/list")
public class ListServlet extends HttpServlet {
private IBookTypeService bookTypeService = new BookTypeServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 先定义编码方式
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
List<BookType> typeList = bookTypeService.findAll();
// 把前端拼出来
StringBuffer sb = new StringBuffer();
sb.append("<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <title>Title</title>\n" +
"</head>\n" +
"<body>\n" +
"<table width=\"500px\" border=\"1px\">\n" +
" <tr>\n" +
" <th>id</th>\n" +
" <th>姓名</th>\n" +
" <th>简介</th>\n" +
" <th>操作人</th>\n" +
" </tr>\n");
for(BookType bookType:typeList){
sb.append(" <tr>\n" +
" <td>"+bookType.getId()+"</td>\n" +
" <td>"+bookType.getName()+"</td>\n" +
" <td>"+bookType.getIntro()+"</td>\n" +
" <td>"+bookType.getOperator()+"</td>\n" +
" </tr>");
}
// 再把结尾拼进来;
sb.append("</table>\n" +
"\n" +
"</body>\n" +
"</html>");
resp.getWriter().write(sb.toString());
}
}
存在问题:
前后端代码耦合;
实现不够灵活;
方案二:用jsp解耦前后端代码—本质是request转发
Jsp本质是一个Servlet
resp.sendRedirect(req.getContextPath() + “/b”);
1.pom.xml导包
<!-- jsp导包-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<!-- 加provided-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
2.web.xml换高版本 — 不然没法显示
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app\_4\_0.xsd"
version="4.0">
</web-app>
3.Servlet转发到webApp中的jsp中
共享值:req.setAttribute(“typeList”, typeList);
转发:req.getRequestDispatcher(“/bookType/list.jsp”).forward(req,resp);
访问http://localhost:10081/day01/bookList/jsp 转发到jsp
servlet部分代码:
package com.tianju.web.servlet.bookType;
import com.tianju.web.entity.BookType;
import com.tianju.web.entity.User;
import com.tianju.web.service.IBookTypeService;
import com.tianju.web.service.IUserService;
import com.tianju.web.service.impl.BookTypeServiceImpl;
import com.tianju.web.service.impl.UserServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@WebServlet("/bookList/jsp")
public class ListServletJSP extends HttpServlet {
private IBookTypeService bookTypeService = new BookTypeServiceImpl();
private IUserService userService = new UserServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 先定义编码方式
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
List<BookType> typeList = bookTypeService.findAll();
// 共享到request请求中
req.setAttribute("typeList", typeList);
User user = userService.findByUsername("admin");
req.setAttribute("user", user);
// 转发到/bookType/list.jsp,内部转发,是同一个请求
// 所以jsp可以拿到
req.getRequestDispatcher("/bookType/list.jsp").forward(req,resp);
}
}
4.jsp部分代码----显示结果
获取值的方法:${typeList}
获取属性的方法:${user.username}
循环的方法:c:forEach items=“${typeList}” var=“booktype”
${user.username}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${typeList}" var="booktype">
完整代码
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP获得图书类型</title>
</head>
<body>
<%--调用toString方法--%>
${typeList}<br>
<hr>
获得对象
${user}<br>
<hr>
获取属性
${user.username}<br>
<hr>
<%--显示表格--%>
<table width="800px" border="1px">
<tr>
<th>id</th>
<th>类型名称</th>
<th>简介</th>
<th>创建时间</th>
<th>修改时间</th>
<th>操作人员</th>
</tr>
<%-- 用foreach方法--%>
<c:forEach items="${typeList}" var="booktype">
<tr>
<td>${booktype.id}</td>
<td>${booktype.name}</td>
<td>${booktype.intro}</td>
<td>${booktype.createTime}</td>
<td>${booktype.updateTime}</td>
<td>${booktype.operator}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
5.访问转发过程分析
核心是值共享,内部转发