java中的接口是类吗
1221
2022-08-24
Java Servlet响应httpServletResponse过程详解
目录一、核心方法1.setStatus2.setHeader(Stringname,Stringvalue)3.addHeader(Stringname,Stringvalue)4.setContentType(Stringtype)二、响应一个网页三、返回一个文件四、返回json数据
一、核心方法
1.setStatus
设置响应状态码 如果没有调用这个方法,默认返回200状态码(前提:正常执行,没有异常) 如果出现异常,返回500
前端代码:
function setStatus(){
//js中发送请求:(1)ajax(2)直接修改url
let status = document.querySelector("#status");
//后端会设置文本框输入的值为响应状态码:严格来做需要验证(省略)
window.location.href = "response?status="+status.value;
}
后端代码:
@WebServlet("/response")
public class ResponseStudyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求发送的queryString数据:status=xxx
String status = req.getParameter("status");
resp.setStatus((Integer.parseInt(status)));
resp.getWriter().write("设置响应状态码成功");
}
}
前端显示:
提交后fiddler抓包:
2.setHeader(String name,String value)
设置响应头
响应头name键已有,会覆盖原有的键值对
前端代码:
后端代码:
//设置响应头的键值对,键可以是标准的http响应头的键,也可以是自定义的
//响应状态码是301,302,307,响应头有Location字段,才是重定向
resp.setHeader("Location","http://baidu.com");
resp.setHeader("username","张三");
fiddler抓包结果:
3.addHeader(String name,String value)
设置响应头
响应头name键已有,不会影响,添加一个新的
这两个了解即可
4.setContentType(String type)
设置响应头Content-Type的值,等同于setHeader(“Content-Type”,String type) 因为Content-Type是标识body的数据格式,所以还需要设置body的内容
1.响应一个网页
//响应html:设置响应的Content-Type
resp.setContentType("text/html; charset=utf-8");
可以返回静态和动态网页
两种方式展示:
前端代码:
function toWelcome(){
let username = document.querySelector("#username");
window.location.href = "html?type=2&username="+username.value;
}
后端代码:
@WebServlet("/html")
public class HTMLTypeServlet extends HttpServlet {
//html?type=...
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//响应html:设置响应的Content-Type
resp.setContentType("text/html; charset=utf-8");
PrintWriter pw = resp.getWriter();
//获取queryString中,type的值
String type = req.getParameter("type");
if("1".equals(type)){//返回简单的html
pw.println("
}else if("2".equals(type)){//返回复杂的动态html
//html?type=2&username=xxx
String username = req.getParameter("username");
pw.println("
");
pw.println("欢迎你,"+username);
pw.println("
}
}
}
简单:
前端显示:
点击“查看”:
动态:
前端显式:
点击“跳转”:
关于动态网页:在java的代码中,写很多html的代码
耦合性太强(两个完全不同的编程语言,放在一起来开发)、维护性、扩展性很差
解决方式:
模板技术这种方式还存在一些问题,进一步发展就有了ajax技术的产生
二、响应一个网页
返回已有的一个网页
(1)重定向:
特点:url地址栏会变,发起两次请求
原理:
第一次返回301/302/307响应状态码,及响应头Location:网页的地址
第二次:浏览器自动的跳转到Location设置的地址
还是比较常用的:比如登录成功(其实也可以在js代码中跳转)后,跳转到某个首页
(2)转发:
特点:url地址栏不变,只有一次请求
原理:当次请求Servlet时,由Servlet获取到转发路径的html,把这个路径的内容设置到响应正文
前端代码:
后端代码:
@WebServlet("/goto")
public class GoToServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//goto?type=xxx
String type = req.getParameter("type");
if("1".equals(type)){//重定向
// resp.setStatus(301);
// resp.setHeader("Location","hello.html");
//以上代码可以简化为sendRedirect
resp.sendRedirect("hello.html");
}else if(ZKYuCkvn"2".equals(type)){//转发
req.getRequestDispatcher("hello.html")
.forward(req,resp);
}
}
}
三、返回一个文件
设置一下Content-Type,然后把文件的二进制数据放在响应正文就可以
前端代码:
后端代码:
@WebServlet("/file")
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//
//获取响应对象的字节输出流
OutputStream os = resp.getOutputStream();
//返回的文件类型:1.图片 2.音乐
String type = req.getParameter("type");
//返回时的操作:1.渲染 2.下载
String show = req.getParameter("show");
File file = null;
byte[] data = null;
//
if("photo".equals(type)){//返回图片
if("1".equals(show)){
resp.setContentType("image/jpeg");//jpg格式
}else{
//这样只是没有设置下载的文件名,有兴趣可以自行扩展完成
resp.setContentType("application/octet-stream");
}
file =new File("D:\\java\\servlet-study\\src\\main\\resources\\cui.jpg");
//
}else if("music".equals(type)){//返回音乐
if("1".equals(show)){
resp.setContentType("audio/mp3");//mp3格式
}else{
resp.setContentType("application/octet-stream");
}
file = new File("D:\\java\\servlet-study\\src\\main\\resources\\这世界有那么多人.mp3");
}//其他格式可以自行扩展完成
//返回一个文件类型:Content-Length,body
data = Files.readAllBytes(file.toPath());
resp.setContentLength(data.length);//setHeader("Content-Length",xxx)
os.write(data);
}
}
问题:图片、音乐、视频是静态文件,直接放在web应用webapp下,就可以直接访问,那还需要Servlet来返回么?是否多此一举?
如果文件总的大小非常大,放在web应用的webapp下就不合适了:打包就比较费劲,使用Servlet去读取本地其他地方的文件,来返回,就比较适合
四、返回json数据
常用于ajax请求,返回一些数据,用于动态的填充网页
前端代码:
function gen(){
let content = document.querySelector("#content");
ajax({
url: "ajax-response",
method: "get",
callback: function(status,resp){
console.log(resp);//resp是一个字符串
//转换为json对象
let array = JSON.parse(resp);
for(json of array){//遍历
//每一个json对象,创建一个dom来保存信息
let p = document.createElement("p");
p.innerHTML = json.from+" 对 "+json.to+" 说:"+json.info;
content.appendChild(p);
}
}
});
}
function ajax(args){//var ajax = function(){}
let xhr = new XMLHttpRequest();
//设置回调函数
xhr.onreadystatechange = function(){
//4:客户端接收到响应后回调
if(xhr.readyState == 4){
// 回调函数可能需要使用响应的内容,作为传入参数
args.callback(xhr.status,xhr.responseText);
}
}
xhr.open(args.method,args.url);
// 如果args中,Content-Type属性有内容,就设置Content-Type请求头
if(args.contentType){//js中,除了判断boolean值,还可以判断字符串,对象等,有值就为true
xhr.setRequestHeader("Content-Type",args.contentType);
}
//如果args中,设置了body请求正文,调用send(body)
if(args.body){
xhr.send(args.body);
}else{//如果没有设置,调用send()
xhr.send();
}
}
后端代码:
@WebServlet("/ajax-response")
public class AjaxJsonServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List
Message m1 = new Message("汪汪","喵喵","我喜欢你");
Message m2 = new Message("喵喵","汪汪","我喜欢你");
messages.add(m1);
messages.add(m2);
ObjectMapper mapper = new ObjectMapper();
//把Java对象,转换为一个json字符串,list和数组会转换为[],一个对象{成员变量名:值}
String json = mapper.writeValueAsString(messages);
//[{"from":"汪汪","to":"喵喵","info":"我喜欢你"},{"from":"喵喵","to":"汪汪","info":"我喜欢你"}]
System.out.println("转换的json字符串"+json);
//设置json可以不设置Content-Length,tomcat会设置
resp.setContentType("application/json; charset=utf-8");
resp.getWriter().println(json);
}
static class Message{
private String from;//谁
private String to;//对谁
private String info;//说了什么
public Message(String from, String to, String info) {
this.from = from;
this.to = to;
this.info = info;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
}
点击“试试”:
具体过程:
对应可以使用的数据格式:
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~