文章目录
- 前言
- 创建Servlet项目
- 处理请求并响应
- 处理请求
- text/plain,纯文本
- text/html,html代码
- application/json,JSON格式字符串
- Servlet 生命周期
- Servlet在整个生命周期中被调用的方法
- Servlet运行原理
- CORS跨域设置
前言
提示:这里可以添加本文要记录的大概内容:
在写 javaweb项目之前先下载好Tomcat与JavaWeb工具
下图展示的是某个JavaWeb工具的代码提示,可以看看自己的有没有
创建Servlet项目
提示:以下是本篇文章正文内容,下面案例可供参考
第一次生成JavaWeb项目:
往后生成JavaWeb项目:
第一步: 继承HttpServlet
第二步: 增加@WebServlet注解,配置地址
第三步: 重写doXXX方法(共7种),处理请求并响应
代码具体操作:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//第二步:增加@WebServlet注解,配置地址
@WebServlet("/hello")
//第一步:继承HttpServlet
public class HelloServlet extends HttpServlet{
//第三步:重写doXXX方法,处理请求并响应
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
处理请求并响应
处理请求
//处理请求
//1.获取请求中的数据
//调用HttpServletRequest中的方法getParameter("数据名")
String name = req.getParameter("name");
//2.具体处理
System.out.println("前端发送的数据是"+name);
以下是三种相应类型
text/plain,纯文本
//生成纯文本格式的响应
//1.调用HttpServletResponse中的setContentType方法设置内容类型
resp.setContentType("text/plain;charset=utf-8");
//2.调用HttpServletResponse中的getWriter方法输出响应内容
PrintWriter writer = resp.getWriter();
writer.print("Hello, world!");
writer.flush();
上面的代码设置了响应的内容类型为 text/plain,然后输出了一个字符串“Hello, world!”。注意,要在输出内容后调用 flush()
方法,将内容刷入输出流中。
输出效果:
text/html,html代码
//生成 HTML 代码格式的响应
//1.调用HttpServletResponse中的setContentType方法设置内容类型
resp.setContentType("text/html;charset=utf-8");
//2.调用HttpServletResponse中的getWriter方法输出响应内容
PrintWriter writer = resp.getWriter();
writer.print("<html><head><title>Hello, world!</title></head><body><h1>Hello, world!</h1></body></html>");
writer.flush();
输出效果:
application/json,JSON格式字符串
Student 类:
public class Student {
private String name;
private String sex;
public Student() {
super();
// TODO 自动生成的构造函数存根
}
public Student(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
servlet 类:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
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 com.google.gson.Gson;
import po.Student;
@WebServlet("/hello")
public class HelloServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理请求
//1.获取请求中的数据
//调用HttpServletRequest中的方法getParameter("数据名")
String name = req.getParameter("name");
//2.具体处理
System.out.println("前端发送的数据是"+name);
//生成响应
//1.调用HttpServletResponse中的setContentType 设置内容类型
resp.setContentType("application/json;charset=utf-8");
//2.调用HttpServletResponse中的getWriter 输出流
PrintWriter writer = resp.getWriter();
Student s1 = new Student("张三","男");
Student s2 = new Student("李四","女");
ArrayList<Student> list = new ArrayList<>();
list.add(s1);
list.add(s2);
Gson gson = new Gson();
writer.print( gson.toJson(list));
}
}
输出效果:
Servlet 生命周期
- 加载阶段:调用构造方法
- 初始化阶段:调用 init 方法
当支持Servlet运行的Web容器接收到客户端的请求时,会先判断用户所请求的Servlet对象是否存在;如果不存在,则需要加载Servlet类,创建 Servlet的对象,然后调用Servlet的init()
方法进行初始化。 - 服务阶段:调用 service方法处理发送回来的请求
容器针对本次客户端请求创建ServletRequest
和ServletResponse
对象,并且创建一个线程,调用Servlet对象的service( )
方法,service()
方法再根据客户端的请求方式间接调用doGet()
方法或者doPost()
方法。
service()方法运行结束后产生响应,容器将响应发回客户端。 - 销毁阶段:调用 destroy方法销毁
当Web应用被卸载或者服务器被关闭的时候,容器会销毁为本次客户端请求创建的ServletRequest
和ServletResponse
对象以及相应的线程。此时会调用destroy()
方法释放资源。
需要注意的是,加载 Servlet 类,创建 Servlet 对象、调用初始化方法 init() 和销毁方法 destroy() 在Servlet的整个生命周期中都只有一次。
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = "/life",loadOnStartup = 5)
public class LifeCycleServlet extends HttpServlet{
public LifeCycleServlet() {
System.out.println("构造方法调用了");
}
@Override
public void init() throws ServletException {
// TODO init自动生成的
System.out.println("init方法调用了");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service方法调用了");
}
@Override
public void destroy() {
// TODO 自动生成的方法存根
System.out.println("destroy方法调用了");
}
}
运行项目后控制台输出:
那第四阶段的:销毁阶段,调用 destroy方法销毁
在Servers内,选择Tomcat右键停止
回到控制台:
Servlet在整个生命周期中被调用的方法
Servlet在整个生命周期中会有一些方法被服务器自动调用,其中的主要方法有:
init( )
方法:用于初始化
Destro( )
方法:用于释放资源
service( )
方法:服务类方法,对用户的请求进行处理,并对用户进行响应,几乎所有处理功能都在这里完成。service( )
方法通常会激活doGet( )或 doPost( ) 方法。
doGet( )
方法可以响应get方式的请求,doPost( ) 方法可以响应 post方式的请求。
一般不推荐直接重写 service( )方法,而是应该重写doGet( )或者 doPost( )方法。通常,表单提交常使用post方式,超链接使用 get 方式。
Servlet运行原理
CORS跨域设置
CORS是一种机制,允许Web应用程序从不同的域名或端口请求资源,解除了同源策略的限制。通过添加自定义的请求头和响应头来实现,在Web服务器提供的访问策略中,允许或拒绝来自不同域的请求访问资源。CORS促进了Web应用程序的开发,并使得跨域请求更加方便。
先做一个JavaWeb中的Servlet,实现了一个简单的用户登录功能。
登录时需要传入用户名和密码,当用户名为admin,密码为111时,登录成功,返回结果为“成功”;否则返回结果为“失败”。
同时在响应中添加了允许跨域异步请求的请求头。最后将结果通过PrintWriter写回响应中,供前端页面使用。
后端代码:
// 前后端分离项目
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/login")
public class LoginServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
String result = null;
// ==判断的是内容
if (name.equals("user") && pwd.equals("123456")) {
result = "成功";
} else {
result = "失败";
}
//允许跨域 异步请求 * 代表所有
resp.setHeader("Access-Control-Allow-Origin", "*");
//我的响应类型 纯文本
resp.setContentType("text/plain;charset=utf8");
//得到字符输出流
PrintWriter writer = resp.getWriter();
//将变量result的值输出到控制台或文件中
writer.print(result);
}
}
启动Tomcat运行,在原本链接后用问号加上名字和密码的值:?name=user&pwd=123456
接下来写前端代码:
在选择功能的时候要把Router
加上,因为有跳转
在项目成功后安装axios框架:npm i axios
进到项目后打开router文件夹下的 index.js 文件
另外除根组件外其他子组件全部删掉
在根组件中删掉 Home 和 About 以及所有样式,只留一个路由出口
删完后的显示:
然后新建两个子视图LoginView和IndexView
首页视图内加个h1标签,只需要表明这个视图是干嘛的就行
<h1>欢迎访问首页视图</h1>
也在登录视图内加个h1标签,只需要表明这个视图是干嘛的就行
<h1>登录视图</h1>
视图写完后配置路由:index.js
- 导入视图
import LoginView from '@/views/LoginView'
- 配置视图的路由,三个配置项
{
path: '/',
name: 'login',
component: LoginView
},
{
path: '/index',
name: 'index',
component: () => import('@/views/IndexView')
}
]
回到终端启动:
接下来到login视图内加一些内容(两个输入框、一个按钮、一个错误提示)
<template>
<div>
<h1>登录视图</h1>
名: <input type="text" v-model="name"><br>
密: <input type="text" v-model="pwd">
<p v-show="isError">用户名或密码输入错误</p><br>
<button @click="login">登录</button>
</div>
</template>
接下来在data中配置 name、pwd、isError 的数据
data () {
return {
name: '',
pwd: '',
isError: false
}
},
然后在 methods 中加一个 login定义
methods: {
login(){
}
},
在这里面完成axios
请求发送,处理回来的相应数据
首先先导入:
import axios from 'axios'
其次写请求:
methods: {
login(){
// 模板字符串拼接动态数据
axios.get(`http://localhost:8888/CORS/login?name=${this.name}&pwd=${this.pwd}`)
.then((resp) =>{
// 处理服务器后端发回的响应,使用箭头函数
// 判断相应的数据成功还是失败
if ( resp.data =='成功' ) {
this.$router.push('/index')
} else {
// 失败显示错误提示
this.isError = true
}
})
}
},
最后login视图完整代码:(加了样式代码,使其内容丰富)
<template>
<div class="login-container">
<h1>用户登录</h1>
<form>
<div class="form-field">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" v-model="name">
</div>
<div class="form-field">
<label for="password">密 码:</label>
<input type="password" id="password" name="password" v-model="pwd">
</div>
<p v-show="isError" class="error-text">用户名或密码输入错误,请重新输入</p>
<button @click="login" class="login-btn">登录</button>
</form>
</div>
</template>
<script>
import axios from 'axios'
export default {
data () {
return {
name: '',
pwd: '',
isError: false
}
},
methods: {
login(){
// 使用模板字符串拼接动态数据
axios.get(`http://localhost:8888/CORS/login?name=${this.name}&pwd=${this.pwd}`)
.then((resp) =>{
// 处理服务器后端发回的响应,使用箭头函数
// 判断相应的数据成功还是失败
if (resp.data == '成功') {
this.$router.push('/index')
} else {
// 失败显示错误提示
this.isError = true
}
})
}
},
components: {},
computed: {},
watch: {},
mounted () {}
}
</script>
<style scoped>
.login-container {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
}
form {
display: flex;
flex-direction: column;
align-items: center;
background-color: #f6f6f6;
padding: 20px;
border-radius: 5px;
box-shadow: 0px 1px 5px #ccc;
}
.form-field {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 20px;
}
.form-field label {
font-size: 18px;
margin-right: 10px;
}
.form-field input {
font-size: 18px;
padding: 5px;
border-radius: 3px;
border: 1px solid #ccc;
flex: 1;
}
.error-text {
color: red;
font-size: 18px;
margin-top: 10px;
}
.login-btn {
font-size: 18px;
font-weight: bold;
color: white;
background-color: #4CAF50;
border: none;
border-radius: 5px;
padding: 10px 20px;
margin-top: 20px;
cursor: pointer;
}
.login-btn:hover {
background-color: #3E8E41;
}
</style>
输出效果: