会话
HTTP协议是无状态的,那如果客户端与服务器端需要进行多次通信的时候,服务器端是怎么“记住”客户端的?答案就是会话技术,简单理解就是使用cookie让客户端记录一些数据以使服务器端能够识别并“建立状态”,使用session让服务器端能够在一次会话中共享数据。当客户端多次向服务器端通信时,需要在http中增加一个cookie头,内容是服务器端给客户端的cookie和sessionid(有的话),服务器端通过sessionid,从众多会话中得知是某一个会话,并从中获取之前存入的数据,再从cookie得到客户端发来的自己需要的数据。
Cookie
客户端会话技术,将数据保存到客户端
基于响应头set-cookie和请求头cookie实现
cookie一般用于存出少量的不太敏感的数据
在不登录的情况下,完成服务器对客户端的身份识别
Session
服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中。Session的实现是依赖于Cookie的。
在Servlet中,客户端向服务端发送请求,服务端就会为这次会话创建一个Session,并随机一个SessionID。Session将会存储在Web容器中,直至过期销毁。而服务端向客户端发送响应式,会在Header的set-cookie中加上
类似于这样的键值对JSESSIONID:43CDE826516E377D04ED934BB00D4A6A
,后即为SessionID。同时,我们也可以在服务端添加自定义的cookie。
Filter
Filter是Servlet实现的,其方法init是Tomcat启动时运行,方法destory则是Tomcat停止时运行,doFilter方法是请求进来时,在Controller处理前运行,Controller处理完后也会再经过一次过滤器。同时,他有一个过滤器链,会将请求一个个经过各过滤器,顺序为web.xml配置顺序。
public class LoginFilter implements Filter
{
@Override
public void init(FilterConfig filterConfig)
throws ServletException
{
System.out.println("LoginFilter init.");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException
{
System.out.println("LoginFilter doFilter");
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
HttpSession session = request.getSession();
String id = session.getId();
String uri = request.getRequestURI();
System.out.println("id:" + id);
User user = (User)session.getAttribute("user");
if (user == null && !uri.contains("login.do"))
{
response.sendRedirect(request.getContextPath() + "login.jsp");
}
else
{
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy()
{
System.out.println("LoginFilter destory.");
}
}
在web.xml中配置过滤器
<!-- 登录管理Filter -->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.by.zrgj.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
LoginController中在Session中添加属性user。
@RequestMapping(path = "login.do", method = RequestMethod.POST)
public String login(String name, String password, HttpSession session)
throws IOException
{
System.out.println("LoginController");
if (userService.login(name, password))
{
session.setAttribute("user",userService.selectByName(name));
return "main";
}
else
{
return "../failer";
}
}
在filterChain.doFilter(request, response);
前则是controller前,在filterChain.doFilter(request, response);
后则是controller后。
public class TestFilter1 extends Filter {
@Override
protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//在DispatcherServlet之前执行
System.out.println("############TestFilter1 doFilterInternal executed############");
filterChain.doFilter(request, response);
//在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后
System.out.println("############TestFilter1 doFilter after############");
}
}
Ajax
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
function deleteAll() {
var checkedNum=$("input[name='ids']:checked").length;
alert(checkedNum);
if(checkedNum==0){
alert("请至少选择一个进行删除!!!");
return;
}
if(confirm("确认要删除这些用户吗?")){
var userList=new Array();
$("input[name='ids']:checked").each(
function () {
userList.push($(this).val())
}
);
alert(userList);
$.ajax({
type:"post",
url: "${pageContext.request.contextPath}/user/deleteAll.do",
data:{userList:userList.toString()},
success:function () {
alert("删除成功");
location.reload();
},
error:function () {
alert("删除失败");
}
});
}
}
Role
public class Role {
private int id;
private String rolename;
private String roledesc;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRolename() {
return rolename;
}
public void setRolename(String rolename) {
this.rolename = rolename;
}
public String getRoledesc() {
return roledesc;
}
public void setRoledesc(String roledesc) {
this.roledesc = roledesc;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", rolename='" + rolename + '\'' +
", roledesc='" + roledesc + '\'' +
'}';
}
}
public interface RoleDao {
List<Integer> findRoleIdByUserId(int userId);
List<Role> findRoleByUserId(int id);
void addRole(UserRole userRole);
}
<mapper namespace="com.lin.dao.RoleDao">
<select id="findRoleIdByUserId" parameterType="int" resultType="int">
select roleId from user_role where userId = #{userId}
</select>
<select id="findRoleByUserId" parameterType="int" resultType="role">
select * from tb_role where id not in (select roleId from user_role where userId = #{id})
</select>
<insert id="addRole" parameterType="userRole">
insert into user_role (userId,roleId) values (#{userId},#{roleId});
</insert>
</mapper>
@RequestMapping("toAddRole.do")
public ModelAndView toAddRole(int id){
List<Role> roleList = roleService.findRoleByUserId(id);
ModelAndView mv = new ModelAndView();
mv.addObject("roles",roleList);
mv.addObject("id",id);
mv.setViewName("user-role-add");
return mv;
}
@RequestMapping("/addRole.do")
@ResponseBody
public String add(String roleList,String userId){
String[] strs = roleList.split(",");
List<Integer> ids = new ArrayList<>();
for(String s:strs){
ids.add(Integer.parseInt(s));
}
roleService.add(ids,userId);
return "";
}