转发和重定向区别

1、    重定向与转发的区别

1、    转发地址栏不发生变化 重定向地址栏指向目标网页

2、    转发是一次请求 重定向是2次请求

3、    转发只能是本应用的资源 而重定向可以是本应用也可以是其他应用的资源

4、    重定向的第二次请求一定是get

1

详情:https://blog.csdn.net/weixin_38447888/article/details/106315971

作用域

【1】ServletContext 域— application

ServletContext代表整个web应用的对象。

生命周期:web应用被tomcat服务器加载时,ServletContext对象产生,生命周期开始。

web应用被移除容器或者tomcat服务器关闭的时候,ServletContext对象销毁,生命周期结束。

作用范围:整个web应用。

主要功能:在整个web应用范围内共享数据。

【2】session 域—session

Session代表整个会话的对象

生命周期:当调用request.getSession()时,Session对象被创建。生命周期开始

调用session.invalidate()方法销毁Session对象

在设定的时间内,Session对象没有被使用,则Session对象被销毁。默认为30分钟

当服务器意外关闭的时候,Session对象被销毁。当服务器正常关闭的时候,Session对象中仍有数据,会序列化到磁盘上形成一个文件,

这个过程称之为钝化。在服务器再次启动的时候,这个文件会被重新读取到服务器中使用,这个过程称之为活化。

作用范围:整个会话范围

主要功能:在会话范围内共享数据

【3】request 域—request

Request代表请求的对象

生命周期:请求链开始,request对象被创建,请求链结束,request对象销毁。

作用范围:整个请求链

主要功能:在请求链内共享数据

【4】pageContext域—pageContext

PageContext代表当前页面的对象

生命周期:在访问jsp页面时,pageContext对象产生,生命周期开始。在结束访问jsp页面时,pageContext对象销毁,生命周期结束。

作用范围:整个jsp页面

主要功能:在整个jsp页面内共享数据

request请求

response响应

JS中获取session的值

var length='<%=request.getSession().getAttribute("aclength")%>';

更改服务器编码

//更改服务器的编码
TomCat server.xml  URIEncoding="utf-8"

jsp动态网页的技术

serlvet是一个类 能够处理动态网页的请求

Servlet的生命周期是什么?

Init (初始化)-- service(doget dopost )---destroy(销毁)
<%@ page import="java.util.*"%>//导入java类
 <input type="hidden"/>隐藏标签
acction为空提交给自己

清除所有session

request.getSession().invalidate();

request

请求中文编码问题

//设置请求的中文编码
request.setCharacterEncoding("UTF-8");
String name=request.getParameter("textname");
String pwd =request.getParameter("textpass");
/* out.println("账号:"+name);
out.println("密码:"+pwd); */

获取单选复选的值

//获取单选 复选这一类的值
String [] sour=request.getParameterValues("textsource");
for(String i:sour){
out.println(i);
}

输出

out.println("<h1>中国人民富裕起来了</h1>");
//获取数据
request.setCharacterEncoding("UTF-8");//设置中文编码
String p=request.getProtocol();//得到协议
String m=request.getMethod();//客户端请求方法
String h=request.getServerName();//得到服务器名称
String name=request.getParameter("baidun");//得到账号
String pwd=request.getParameter("baidup");//得到密码

action动作

//post设置utf-8中文编码
request.setCharacterEncoding("utf-8");//设置中文编码
String mc=request.getParameter("uname2");
//get设置utf-8中文编码
String name=request.getParameter("uname");//请求name
byte [] temp=name.getBytes("ISO-8859-1");//获取变量name的字节数组
String news=new String(temp,"utf-8");//将字符数组转换成指定格式的字符串

include引用文件内容

//include 引用文件内容 放到jsp中
<jsp:include page="文件名称"></jsp:include>

forward 转发

//forward 转发 网页地址不变 
<jsp:forward page="跳转的网页"></jsp:forward>
<jsp:forward page="qqhedader.jsp"></jsp:forward>
//判断账号对错进行跳转
<%
String uname = request.getParameter("uname");//获取账号
String upwd = request.getParameter("upwd");//获取密码
if (uname.equals("admin") && upwd.equals("admin")) {//判断是否相同
%>
<jsp:forward page="qqhedader.jsp"></jsp:forward>//jsp跳转
<% 
}else{
//错误时
out.println("账号或密码错误!");
}
%>

//判断账号对错进行跳转

<%
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
if (uname.equals("admin") && upwd.equals("admin")) {
%>
<jsp:forward page="qqhedader.jsp"></jsp:forward>
<% 
}else{
out.println("账号或密码错误!");
%>
//跳回登入界面
<jsp:forward page="LoginForward.jsp"></jsp:forward>
<% 
}
%>

response响应对象

改变响应方式

//改变响应的方式类型
response.setContentType("application/msword;charset=GB2312"); 下载保存文件为word
response.setContentType("application/vnd.ms-excel;charset=GB2312"); 下载保存为excel

重定向

//重定向 响应2次 转发1次  多个页面数据请求时用转发  不共享时用重定向
response.sendRedirect("jdorder.jsp");
response.sendRedirect("跳转网页");

重定向错误

//重定向错误
response.sendError(404,"账号或密码错误!");
response.sendError(数值,"报错内容")

转发重定向

//利用转发实现重定向
RequestDispatcher rd=request.getRequestDispatcher("JDlogin.jsp");
rd.forward(request, response);
或者
request.getRequestDispatcher("跳转地址").forward(request, response)
//利用重定向实现
response.sendRedirect("jdorder.jsp");
超链接属于重定向	
<a href="mailto:xyhghy@outlook.com">heloo</a> //打开本地邮件
<a href="tencent://message/?uin=2730023437&Site=&Menu-=yes"> qq</a>//打开QQ

带JS发送内容

也可以用来发送错误

PrintWriter out = response.getWriter();
out.print("<script>localStorage.clear();location.href='/examproject/html/Score.jsp'</script>");

session对象 会话对象

关闭浏览器也相当于销毁了 session

http协议特点: 不会主动响应客户端 单向  连接是一次性的

//将登入消息保存到session
session.setAttribute("nakey", name);
session.setAttribute("pwdkey", pwd);
//设置有效时间 默认30分钟 单位秒
session.setMaxInactiveInterval(60);
//获取会话中的指定键的值 返回类型是object
Object obj=session.getAttribute("nakey"); //获取设置的seeAttribute name
Object p=session.getAttribute("pwdkey");   //获取设置的seeAttribute pwd
//判断获取的是不是为空
if(obj==null || p==null){
response.sendRedirect("JDlogin.jsp");
}else{
//转化类型
String pwd=(String)p;
String name=(String)obj;
if(name.equals("admin") && pwd.equals("admin")){
%> 
<% 
}else{
response.sendRedirect("JDlogin.jsp");
}

销毁session

session.invalidate();//退出时销毁

JSP_JDBC

//属性值可以是一个类 
session.setAttribute("ukey", name);
session.setAttribute("pkey", pwd);
//创建一个类 
package com.it.entity;
public class Loginuser {
public String loginname;
public String loginpwd;
public String logindate;
public Loginuser() {

}
public Loginuser(String loginname, String loginpwd, String logindate) {
this.loginname = loginname;
this.loginpwd = loginpwd;
this.logindate = logindate;
}
}

String name=request.getParameter("na");//获取账号
String pwd=request.getParameter("pwd");//获取密码
if(name.equals("admin") && pwd.equals("admin")){
//获取当前时间
Date nowdate=new Date();
//格式化时间
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
String dat=sdf.format(nowdate);
//new 创建的类
Loginuser u=new Loginuser(name,pwd,dat);
//将登入消息保存到session
session.setAttribute("ukey", u);
session.setAttribute("pkey", u);
//重定向到index.jsp
response.sendRedirect("index.jsp");
}else{
//重定向到登入login.jsp
response.sendRedirect("Login.jsp");
}

<%
Object obj1=session.getAttribute("ukey");
Object obj2=session.getAttribute("pkey");
if(obj1==null || obj2==null){
response.sendRedirect("Login.jsp");
}else{
Loginuser logna=(Loginuser)obj1;
out.println("<h3 style='color:red'>欢迎"+logna.loginname+"登入时间:"+logna.logindate+"</h3>");
out.println("<h1>商品列表</h1>");
//利用jdbc技术实现数据展示
String dburl="jdbc:mysql://localhost:3306/cctv";
String dbpass="root";
String dblogin="root";
String drive="com.mysql.jdbc.Driver";
Class.forName(drive);
//创建连接对象
Connection conn= DriverManager.getConnection(dburl,dblogin,dbpass);
//sql命令对象
Statement sta=conn.createStatement();
String sel="select * from goods";
//结果集对象
ResultSet res=sta.executeQuery(sel);
%>
<!-- 构建表格-->
<table border="1px" cellspacing="0px" width="50%" style="text-align:center">
<tr>
<td>编号</td>
<td>名称</td>
<td>价格</td>
<td>数量</td>
<td>入库时间</td>
<td>产地</td>
</tr>
<%
//遍历结果集 并展示
while(res.next()){
String bh=res.getString("gdid");
String gna=res.getString("gdname");
String gdp=res.getString("gdprice");
String gdn=res.getString("gdnumber");
String tie=res.getString("gddate");
String adr=res.getString("gdaddr");
out.println("<tr><td>"+bh+"</td><td>"+gna+"</td><td>"+gdp+"</td><td>"+gdn+"</td><td>"+tie+"</td><td>"+adr+"</td></tr>");
}
%>
</table>
<%
}
%>

JSP_JDBCinsert
<%
//1、得到页面提交的信息
request.setCharacterEncoding("utf-8");
String id=request.getParameter("id");
String name=request.getParameter("name");
String price=request.getParameter("price");
String numb=request.getParameter("number");
String time=request.getParameter("time");
String addr=request.getParameter("add");
//2、将信息添加到数据库
String dburl="jdbc:mysql://localhost:3306/cctv";
String dbpass="root";
String dblogin="root";
String drive="com.mysql.jdbc.Driver";
Class.forName(drive);
//创建连接对象
Connection conn= DriverManager.getConnection(dburl,dblogin,dbpass);
//sql命令对象
Statement sta=conn.createStatement();
String ins="inser into goods(gdid,gdname,gdprice,gdnumber,gddate,gdaddr) values('"+id+"','"+name+"','"+price+"','"+numb+"','"+time+"','"+addr+"')";
/* System.out.println(ins); */
StringBuilder sb=new StringBuilder();
sb.append("insert into goods(gdid,gdname,gdprice,gdnumber,gddate,gdaddr)");
sb.append(" values('");
sb.append(id);
sb.append("','");
sb.append(name);
sb.append("',");
sb.append(price);
sb.append(",");
sb.append(numb);
sb.append(",'");
sb.append(time);
sb.append("','");
sb.append(addr);
sb.append("');");
int i=sta.executeUpdate(sb.toString());
//3.根据结果判断
if(i>0){
response.sendRedirect("index.jsp");
}else{
response.sendRedirect("gadd.jsp");
}

%>

JSP_JDBCupdate  修改

<a href="gdupdate.jsp?kid=<%=kid %>">编辑</a>  ?kid拼接

while(res.next()){
String kid=res.getString(1);//获取主键的ID
String bh=res.getString(2);
String gna=res.getString(3);
String gdp=res.getString(4);
String gdn=res.getString(5);
String tie=res.getString(6);
String adr=res.getString(7);
/* out.println("<tr><td>"+bh+"</td><td>"+gna+"</td><td>"+gdp+"</td><td>"+gdn+"</td><td>"+tie+"</td><td>"+adr+"</td></tr>"); */
%>
<tr>
<td><%=bh %></td>
<td><%=gna %></td>
<td><%=gdp %></td>
<td><%=gdn %></td>
<td><%=tie %></td>
<td><%=adr %></td>
<!-- 通过主键id来传值 -->
<td><a href="gdupdate.jsp?kid=<%=kid %>">编辑</a>&nbsp;&nbsp;<a href="#">删除</a></td>
</tr>
<%

//数据库工具类
package com.it.mysql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCTool {
static String uname="root";
static String upwd="root";
static String dburl="jdbc:mysql://localhost:3306/cctv";
static String drive="com.mysql.jdbc.Driver";
static Connection conn=null;
static Statement sta=null;
static ResultSet rs= null;

public static Connection opencon() {
try {
Class.forName(drive);
try {
conn=DriverManager.getConnection(dburl, uname, upwd);

} catch (SQLException e) {
// TODO Auto-generated catch block

}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block

e.printStackTrace();
}
return conn;
}

public static ResultSet SQuery(String sql) {
Connection con=opencon();
try {
sta=conn.createStatement();
rs=sta.executeQuery(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rs;
}

public static int SQlUpdate(String sqlstr) {
int t=0;
Connection con=opencon();
try {
sta=con.createStatement();
t=sta.executeUpdate(sqlstr);
} catch (SQLException e) {
// TODO Auto-generated catch block

e.printStackTrace();
}
return t;
}
}
onclick="location.href='index.jsp'"  点击取消跳转的地方

访问步骤: 加载JDBC驱动  —与数据库建立连接 --发送SQL语句 并得到返回值 —处理返回结果 —释放资源

JSP_JDBdelete

onclick 点击事件  return 返回选择的对象 true/false

//删除前的确认
<a href="gdde2.jsp?gkid=<%=kid %>" onclick="return confirm('是否删除?')";>删除</a>
<%
String id=request.getParameter("id");
Connection conn=JDBCTool.opencon();
String de="delete from goods where kid='"+id+"'";
int i=JDBCTool.SQlUpdate(de);
if(i>0){
response.sendRedirect("index.jsp");
}
%>

JSTL标签  EL表达式  简化java代码

//需要导入包
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

test="${param.na=='admin'}"  ---EL表达式    
na是input的name    test... 判断的条件



<c:if></c:if> 普通if   
<c:out></c:out> 普通out  value输出的值 



<c:if test="${param.na=='admin'}" var="adminvar">
<c:out value="欢迎管理员!"></c:out>
</c:if>

输出前面的$  需要在前面用转义 \

<h1>\${2==6}的结果是:${2==6}</h1>
<h1>\${2!=6}的结果是:${2!=6}</h1>
<h1>\${2>6}的结果是:${2>6}</h1>
<h1>\${2<6}的结果是:${2<6}</h1>
<h1>\${2>=6}的结果是:${2>=6}</h1>
<h1>\${2<=6}的结果是:${2<=6}</h1>

${(6!=8)?"不成立":"成立" }  为真输出:前面的   为假输出:后面的



<h2>EL集合</h2>
<%
ArrayList<String> alist=new ArrayList<String>();

alist.add("淘宝");
alist.add("拼多多");
alist.add("拼爹爹");
session.setAttribute("al", alist);//将集合保存会话中
HashMap<String,String> ma=new HashMap<String,String>();
ma.put("01", "中国");
ma.put("02", "米国");
ma.put("03", "德国");
session.setAttribute("makey", ma);
%>
<!-- .和[ ]都是用来表示数据的获取 获取集合里面-->
<h2>主流电商平台:${al[0]},${al[1]},${al[2]}</h2><br>
<%
for(String h:alist){
out.println(h);
}
%>

<h2>国家:${makey.get('01')},${makey.get('02')},${makey.get('03')}</h2>

//得到参数
<!-- param就是 request.getParameter("type") -->

<h1>\${param.type}:${param.type}</h1>



<!-- 利用EL获取复选框的值 -->

<h1>你选择的是:</h1>
${paramValues.st[0] }
${paramValues.st[1] }
${paramValues.st[2] }
${paramValues.st[3] }
</body>

out标签

//out标签 default 默认
<c:out value="厦门鼓浪屿"></c:out><br>
<c:out value="${yna }"></c:out><br>                        <% String name="张三"  request.setAttribute("nkey",name)%>
<c:out value="${null }">如果为空,则输出默认值!</c:out>
<!-- escapeXml 是否忽略xml字符  true 不忽略       false忽略 -->
<c:out value="&lt good morning &lt" escapeXml="false"></c:out>
<c:out value="&get good morning &get" escapeXml="true"></c:out>

set标签

<!-- 设置值  var名字  value值   scope范围  (page,request,session,application) -->
<c:set var="price" value="500" scope="session"></c:set>
<h1><c:out value="${price }"></c:out></h1>

<!-- 没有值时输出默认 -->
<c:out value="${ynae }" default="大理"></c:out><br>
<c:out value="${ynae }" >菏泽</c:out><br>
<c:out value="${null }">如果为空,则输出默认值!</c:out><br>

remove标签

<!-- remove移掉某个变量 -->
<c:set var="fir" value="上海"></c:set>
<c:out value="${fir }"></c:out>
<c:remove var="fir"></c:remove>
<c:out value="${fir }"></c:out>

if标签

<!-- test 条件     var得到值的结果 true/false result变量名称 
param.score=request.getparameter("score")  -->
<c:if test="${param.score>=60}" var="result">
<c:out value="成绩合格!"></c:out>
</c:if>
<c:out value="${result }"></c:out>

多重if 即choose

	<!-- 多重if 即choose 
c:when test="条件"
c:otherwise 其他
 -->
 例1
<c:choose>
<c:when test="${param.score<60 }">
<c:out value="不及格"></c:out>
</c:when>
<c:when test="${param.score>=60 && param.score<=70  }">
<c:out value="及格"></c:out>
</c:when>

<c:when test="${param.score>=71 && param.score<=80  }">
<c:out value="一般"></c:out>
</c:when>

<c:when test="${param.score>=81 && param.score<=90  }">
<c:out value="良好"></c:out>
</c:when>

<c:when test="${param.score>=91 && param.score<=100 }">
<c:out value="优秀"></c:out>
</c:when>

<c:otherwise>
<c:out value="输入错误!"></c:out>
</c:otherwise>
</c:choose>
 <!-- new Car是一个类 里面有属性 id brand price  构造方法 -->
<%
ArrayList<Car> mcar=new ArrayList<Car>();
mcar.add(new Car(1224,"特斯拉",90));
mcar.add(new Car(1244,"丰田",23));
mcar.add(new Car(1234,"大众",18));
mcar.add(new Car(1274,"玛莎拉蒂",34));
request.setAttribute("cars",mcar);
%>
<table border="1px" cellspacing="0px" width="50%" style="text-align:center">
<tr><td>编号</td><td>品牌</td><td>价格(万元)</td></tr>

<c:forEach var="ca" items="${cars }">
<tr><td>${ca.id}</td><td>${ca.brand}</td><td>${ca.price}</td></tr>
</c:forEach>
</table>
<%
ArrayList<String> lis = new ArrayList<String>();
lis.add("拼多多");
lis.add("天猫");
lis.add("京东");
lis.add("国美");
session.setAttribute("lkey", lis);
%>
<!-- var 变量名 代表当前条目的变量名称  items 要被循环的信息 用EL表达式 -->
<c:forEach var="site" items="${lkey }">
<c:out value="${site }"></c:out>
</c:forEach>
	//得到复选框后的值 利用写forEach   1 2 3 4 是value  cartoon是name
<c:forEach items="${paramValues.cartoon}" var="car">
<c:if test="${car=='1' }"
<c:out value="科幻类"></c:out>
<c:out value="科幻类"></c:out>
</c:if>

<c:if test="${car=='2' }">
<c:out value="励志类"></c:out>
</c:if>

<c:if test="${car=='3' }">
<c:out value="格斗类"></c:out>
</c:if>

<c:if test="${car=='4' }">
<c:out value="教育类"></c:out>
</c:if>
</c:forEach>

Servlet01

//类编码问题
res.setContentType("text/html; charset=UTF-8");

servlet特点:方便 、跨平台、灵活性高

接口—到抽象类

jsp

action后的地址填 web.xml配置servlet的url-pattern

<body>
<form action="testservlet" method="get">
<input type="text" name="na"/>
<input type="submit" value="提交"/>
</form>

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstServlet extends HttpServlet{
//重写父类get方法 接收客户的get请求
@Override
protected void doGet(HttpServletRequest req,HttpServletResponse res) throws IOException {
PrintWriter out=res.getWriter();//向客户端输出文本
out.print("<html><head><title>我的第一个servlet程序</title></head>");
out.print("<body>欢迎光临! 你的地盘我做主!</body>");
out.print("</html>");
out.flush();//清空缓冲区 
out.close();//关闭输出
}

//重写父类post方法 接收客户的post请求
@Override
    protected void doPost(HttpServletRequest req,HttpServletResponse res) {
this.doGet(req,res);
}
}

Web.xml配置servlet

   <!-- 定义servlet -->
  <servlet>
  <!-- servlet-name 代表servlet的名称  --> 
  <servlet-name>myservlet01</servlet-name>
  <!-- servlet-class 代表servlet类的完整路径 -->
  <servlet-class>com.servlet.FirstServlet</servlet-class>
  </servlet>
  
  <!-- 映射servlet  上面的name==下面的name  保持一致-->
  <servlet-mapping>
  <servlet-name>myservlet01</servlet-name>
 <!--  url-patternhttp的访问格式 -->
  <url-pattern>/testservlet</url-pattern>
  </servlet-mapping>
  
  //列2
    <servlet>
  <!--  名称需要与下面的servlet name一样 -->
  <servlet-name>myservlet01</servlet-name>
   <!-- 类的地方 包名.类名 -->
  <servlet-class>com.servlet.firsetservlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
<!--   需要与上面的servlet name名字相同 -->
  <servlet-name>myservlet01</servlet-name>
  <!-- url地址 地址为显示的地址  jsp页面的提交网页是一个名字   -->
  <url-pattern>/testservlet</url-pattern>
  </servlet-mapping>

Servlet02

//doget dopost处理中文的问题
req.setCharacterEncoding("utf-8");
res.setContentType("text/html;charset=UTF-8");

JSPServlet数据库增删改查

登入并显示错误   Login.jsp登入页面
String name=request.getParameter("na");
String pwd=request.getParameter("pwd");
//账号密码写死
if(name.equals("admin") && pwd.equals("admin")) {
//转发到指定页面 computers.jsp
}else {
//转发向到登入页面 并显示错误消息
request.setAttribute("error", "账号或密码错误!");
request.getRequestDispatcher("Login.jsp").forward(request, response);

//输出错误  error是类的request 
<span id="er"><c:out value="${error }"></c:out></span>

JSPServlet02

/**
 * Servlet implementation class LoginServlet
  *  这个是serlvet注解  有了这个注解就不需要在web.xml文件写servlet 配置
 */
@WebServlet("/LoginServlet")

JSPServlet03 数据分页

总页数=(总条数/每页的条数)+1

每页起点=(当前页-1)*每页数量

//得到路径 String path=request.getRealPath(“”);

代理抛出异常

错误: 代理抛出异常错误: java.rmi.server.ExportException: Port already in use: 1099; nested exception is
java.net.BindException: Address already in use: JVM_Bind

解决办法:

--查找相关进程
netstat -aon|findstr 1099

--关闭进程
taskkill -f -pid 22320

2