登录注册案例优化
登录
这里就是要使得登陆成功页面跳转,登陆失败页面不变,且提示错误信息的优化
1.Dao
接口:
public interface UserMapper {
@Select("SELECT * FROM tb_user WHERE username=#{username} AND password=#{password}")
User select(@Param("username") String username, @Param("password") String password);
@Insert("INSERT INTO tb_user(username, password) VALUES (#{username},#{password})")
void insert(@Param("username") String username,@Param("password") String password);
}
SERVICE
public class UserService {
SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
public User select(String usernaem, String password){
SqlSession sqlSession = factory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user=mapper.select(usernaem,password);
sqlSession.close();
return user;
}
public void insert(String username,String password){
SqlSession sqlSession = factory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.insert(username,password);
sqlSession.commit();
sqlSession.close();
}
}
SERVLET
@WebServlet(name = "LoginServlet", value = "/loginServlet")
public class LoginServlet extends HttpServlet {
private UserService service=new UserService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取用户名密码
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
username=new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
User user = service.select(username, password);
if(user!=null){
// 登陆成功,跳转到查询所有的BrandServlet
// 将登陆成功后的user对象存储到session中
HttpSession session = request.getSession();
session.setAttribute("user",user);
// 动态虚拟目录
String contextPath=request.getContextPath();
// 重定向
response.sendRedirect(contextPath+"/selectAllServlet");
}else{
// 登陆失败
// 存储错误信息到request里面
request.setAttribute("login_msg","用户名或密码错误");
// 跳转到登陆界面index.jsp使用转发的方式
request.getRequestDispatcher("/index.jsp").forward(request,response);
}
}
将原来的静态页面复制到新的jsp文件中(动态页面)
并添加错误提示
且在登录成功跳转的页面jsp中加上动态代码
这里其实还有个记住用户的功能添加,但是现在大部分网页不自带这个功能,且浏览器现在负责记住没密码功能,这里就不写笔记不实现了
注册:
这里就是添加验证码显示,以及验证码对比的功能(如果验证码填写不正确则注册失败)
这里就要使用到一个工具类(已经保存博客园了,很多工程都需要使用)
验证码的作用:防止机器自动注册,攻击服务器
工具类导入过后
在页面中添加一行
<tr>
<td>验证码</td>
<td class="inputs">
<input name="checkCode" type="text" id="checkCode">
<img src="/webJsp/checkCodeServlet">
<a href="#" id="changeImg">看不清?</a>
</td>
</tr>
在完成对应的servlet来获取工具类生成的图片流
@WebServlet(name = "CheckCodeServlet", value = "/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 生成验证码
ServletOutputStream os = response.getOutputStream();
String checkCode = CheckCodeUtil.outputVerifyImage(100, 50, os, 4);
// 存入session
HttpSession session = request.getSession();
session.setAttribute("checkCodeGen",checkCode);
}
这里应为我们要比对用户输入的和系统生成的验证码是否一样所以将验证码存入了session中
随后在注册对应的servlet中进行比对,比对成功才调用方法,失败则直接返回
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 获取用用户输入的验证码
String checkCode = request.getParameter("checkCode");
// 获取程序生成的验证码。从session中获取
HttpSession session = request.getSession();
String checkCodeGen=(String)session.getAttribute("checkCodeGen");
// 比对
if (!checkCodeGen.equalsIgnoreCase(checkCode)){
// 不允许注册
request.setAttribute("register_msg","验证码错误");
request.getRequestDispatcher("/register.jsp").forward(request,response);
return;
}
最后给看不清添加点击事件使其能够点击更新验证码
<script>
document.getElementById("changeImg").onclick=function (){
//new Date().getMilliseconds();是获取当前毫秒值,使得每次点击都能更新路径
document.getElementById("checkCodeImg").src="/webJsp/checkCodeServlet?"+new Date().getMilliseconds();
}
</script>
Filter过滤器
快速入门
写类使用接口,重写方法,定义要拦截的路径
@WebFilter("/*")
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FilterDemo....");
// 放行(如果不放行就不会跳转)
filterChain.doFilter(servletRequest,servletResponse);
}
Filter拦截路径配置&过滤器链
用注解配置的Filter,优先级按照过滤器类名(字符串)的自然顺序
登录验证案例
先前我们写的登录注册案例没有使用到过滤器,导致我们不登陆直接输入要跳转的网址也是可以访问到数据的,现在我们做一个过滤器案例,使得要访问服务器资源时,需要先进行登录,如果没有登陆则自动跳转到登陆界面
/*登陆验证的过滤器*/
@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest req=(HttpServletRequest) request;
//.判断访问资源路径是否和登录注册相关
String[] urls={"/img/","/index.jsp","/register.jsp","/loginServlet","/addUserServlet","/index.css","/register.css"};
//.获取当前访问的资源路径
String url = req.getRequestURL().toString();
//.循环遍历
for (String u: urls) {
if(url.contains(u)){
//.放行那些要用的资源路径
chain.doFilter(request, response);
return;
}
}
//1.判断session中是否有成功登录的用户信息
HttpSession session = req.getSession();
Object user = session.getAttribute("user");
//2.判断user是否为null如果是null跳转到登陆页面并给出提示信息,如果不为null则可以访问资源
if(user!=null){
// 放行
chain.doFilter(request, response);
}else{
//没有登陆,存储提示信息,跳转到登陆界面
req.setAttribute("login_msg","请先登录!");
//.转发到登录界面
req.getRequestDispatcher("/index.jsp").forward(request,response);
}
}
}
Listener监听器
基本使用就是创建类实现接口,重写接口方法加上注解@WebListener
@WebListener
public class ContextLoaderListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
// 加载资源
System.out.println("ContextLoaderListener.....");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//释放资源
}
}
这里用其中一个接口来举例其他的都是类似的
AJAX
前面我们使用jsp里面又要写java代码又要写前端代码,使得前后端不能很好地分离,也不好后期维护,所以现在可以使用html+ajax的方式来代替jsp使前后端分离,java工程师就只需要负责servlet开始后面部分的内容了
同步和异步的区别
其实就是异步请求浏览器页面不会发生跳转,但是可以获取资源,再获取资源期间还可以在当前页面执行其他请求,而同步一旦发出请求,则会跳转即使需要等待
快速入门
对应的AJAX代码不用去记在官网是有的(w3school)
进去后我们点击到服务器相关,如上依次点几下一页就可以看到相关代码案例直接复制就好了
下面是一个简单的快速入门
首先我们创建要访问的servlet
@WebServlet(name = "ajaxServlet", value = "/ajaxServlet")
public class ajaxServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.响应数据
response.getWriter().write("hello,ajax");
}
再完成ajax的书写,是在html页面的script里面书写,直接到w3school里面挨个复制更改下代码就好了
<script>
//.创建核心对象
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//.发送请求
xhttp.open("GET", "http://localhost:8080/cookie-demo/ajaxServlet");
xhttp.send();
//.获取响应
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText) ;
}
};
</script>
小案例-注册使用AJAX验证用户名是否存在
先写好servlet
@WebServlet(name = "ajaxServlet", value = "/ajaxServlet")
public class ajaxServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.响应数据
response.getWriter().write("hello,ajax");
}
再到对应的html里面写ajax
<script>
//.给用户名输入框绑定失去焦点的事件
document.getElementById("username").onblur=function (){
//.发送ajax请求
//.获取用户名的值
let username = this.value;
//.2.1创建核心对象
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//.2.2发送请求
xhttp.open("GET", "http://localhost:8080/cookie-demo/selectUserServlet?username="+username);
xhttp.send();
//.2.3获取响应
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//.判断
if(this.responseText=="true"){
//用户存在,显示提示信息
document.getElementById("username_err").style.display='';
}else{
//用户不存在,清除提示信息
document.getElementById("username_err").style.display='none';
}
}
};
}
</script>
Axios
就是封装ajax代码
基本使用
发送请求以及接收数据
以下案例是实用axios完成上面的验证用户是否存在的案例(修改了其ajax部分的代码)
<script src="js/axios-0.18.0.js"></script>
<script>
//.给用户名输入框绑定失去焦点的事件
document.getElementById("username").onblur=function (){
//.发送ajax请求
//.获取用户名的值
let username = this.value;
//.2.1创建核心对象
var xhttp;
if (window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//.2.2发送请求接收数据
axios.get("http://localhost:8080/cookie-demo/selectUserServlet?username="+username).then(function (resp){
if(resp.data==true){
document.getElementById("username_err").style.display='';
}else{
document.getElementById("username_err").style.display='none';
}
})
}
</script>
JSON
基础语法
写法和js很相似只是键必须用双引号引起来
<script>
//.定义json
var json={
"name":"zhangsan" ,
"age":23,
"addr":["北京","上海","成都"]
};
//.获取值
alert(json.name);
</script>
这些只是前端人员要掌握的,我们了解就好
JSON数据和JAVA对象转换
这里我们直接使用一个api就可以完成对应的功能
以下是一个例子
public class FastJsonDemo {
public static void main(String[] args) {
//.将java对象转为json的字符串
User user=new User();
user.setId(1);
user.setUsername("zhangsan");
user.setPassword("123456");
String jsonString = JSON.toJSONString(user);
System.out.println(jsonString);
//.将json字符串转为java对象
User u = JSON.parseObject(jsonString, User.class);
// JSON.parseObject("{\"id\":1,\"password\":\"123456\",\"username\":\"zhangsan\"}",User.class);
System.out.println(u);
}
}
案例(使用axios+json)
完成品牌列表数据查询和添加
先写好dao层
public interface BrandMapper {
/**
* 查询所有
* @return
*/
@Select("SELECT * FROM tb_brand")
@ResultMap("brandResultMap")
List<Brand> selectAll();
}
service层
public class BrandService {
SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
/*查询所有*/
public List<Brand> selectAll(){
//调用BrandMapper.selectAll()
//2. 获取SqlSession
SqlSession sqlSession = factory.openSession();
//3. 获取BrandMapper
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4. 调用方法
List<Brand> brands = mapper.selectAll();
sqlSession.close();
return brands;
}
}
servlet层,其中就使用了json
@WebServlet(name = "SelectAllServlet", value = "/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
private BrandService service=new BrandService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Brand> brands = service.selectAll();
//.将集合转化为json,序列化数据
String string = JSON.toJSONString(brands);
//.响应数据
response.setContentType("text/json;charset=utf-8");
response.getWriter().write(string);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
最后完成axios
<script src="js/axios-0.18.0.js"></script>
<script>
//.当页面加载完成后,发送ajax请求
window.onload=function (){
axios({
method:"get",
url:"http://localhost:8080/cookie-demo/selectAllServlet"
}).then(function (resp){
//.获取数据
let brands= resp.data;
let tableData=" <tr>\n" +
" <th>序号</th>\n" +
" <th>品牌名称</th>\n" +
" <th>企业名称</th>\n" +
" <th>排序</th>\n" +
" <th>品牌介绍</th>\n" +
" <th>状态</th>\n" +
" <th>操作</th>\n" +
" </tr>";
for (let i = 0; i < brands.length; i++) {
let brand = brands[i];
tableData+="<tr align=\"center\">\n" +
" <td>"+(i+1)+"</td>\n" +
" <td>"+brand.brandName+"</td>\n" +
" <td>"+brand.companyName+"</td>\n" +
" <td>"+brand.order+"</td>\n" +
" <td>"+brand.description+"</td>\n" +
" <td>"+brand.status+"</td>\n" +
"\n" +
" <td><a href=\"#\">修改</a> <a href=\"#\">删除</a></td>\n" +
" </tr>"
// document.getElementById("brandTable").innerHTML=""
// document.getElementById("brandTable").innerHTML=tableData;
}
//.设置表格的数据
document.getElementById("brandTable").innerHTML=tableData;
})
}
</script>
新增
dao和service层的代码还是那样子写
主要看servlet层
因为我们用的是普通按钮提交json数据,所以不能直接获取到数据,要转化成java对象
@WebServlet(name = "AddServlet", value = "/addServlet")
public class AddServlet extends HttpServlet {
private BrandService service=new BrandService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//.1接收数据 request.getParameter接收不了json数据
//.1.1获取请求体对象
BufferedReader br = request.getReader();
String params = br.readLine();
Brand brand = JSON.parseObject(params, Brand.class);
service.add(brand);
//.响应成功标识
response.getWriter().write("success");
}
<script src="js/axios-0.18.0.js"></script>
<script>
//.1给提交按钮绑定单击事件
document.getElementById("btn").onclick=function (){
//.将表单的数据转为json
var formData={
brandName:"",
companyName:"",
ordered:"",
description:"",
status:""
};
//.获取表单数据
let brandName = document.getElementById("brandName").value;
formData.brandName=brandName;
let companyName = document.getElementById("companyName").value;
formData.companyName=companyName;
let ordered = document.getElementById("ordered").value;
formData.ordered=ordered;
let description = document.getElementById("description").value;
formData.description=description;
let status = document.getElementsByName("status");
for (let i = 0; i < status.length; i++) {
if(status[i].checked){
//.被选中
formData.status=status.value;
}
}
console.log(formData);
//.2发送ajax请求(这里使用的是axios)
axios({
method:"post",
url:"http://localhost:8080/cookie-demo/addServlet",
data:formData
}).then(function (resp){
//.判断响应数据是否为success
if(resp.data=="success"){
location.href="http://localhost:8080/cookie-demo/brand.html"
}
})
}
</script>
本文暂时没有评论,来添加一个吧(●'◡'●)