SpringMVC框架笔记
SpringMVC框架
一、SpringMVC简介
SpringWebMVC利用MVC架构思想,帮找我们简化Web层开发
1、Model:模型
客户端传递给后台的数据,可以用模型进行接收
数据库查询出来的数据可以封装到模型当中传递给前台
2、View:视图
模型数据渲染成视图,视图最终是展现给用户的
客户端发送登陆请求,传递用户名和密码到后台,后台将用户名和密码交给数据库进行 查询,数据库返回user对象,登陆成功
我们需要将user对象的用户名或者角色等等信息显示到前台页面当中,那么这个过程就是渲染视图的过程
3、Controller:控制
类似于Servlet,主要负责请求和响应,接受客户端请求,响应结果给客户端
二、SpringMVC入门案例
1、导入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javaee</groupId>
<artifactId>javaee-api</artifactId>
<version>5</version>
</dependency>
2、 新建一个控制器
/**
* 控制器
*/
public class FirstController implements Controller {
/**
* 控制器方法
* @param request 请求
* @param response 响应
* @return ModelAndView 承载数据和返回页面视图
* @throws Exception
*/
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv=new ModelAndView();
//1.接受客户端数据
String name=request.getParameter("name");
//2.将数据保存到ModelAndView对象当中
mv.addObject("username",name);
//3.跳转页面
mv.setViewName("/index.jsp");
return mv;
}
}
3、将控制器注入到容器当中
<!--将控制器注入到容器当中 id就是暴露给外界访问的ID 不要忘了/-->
<bean id="/FirstController" class="com.wdksoft.controller.FirstController"/>
4、配置web.xml文件
<!--中央调度器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--初始化-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!--初始化时机-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
5、注解方式使用Controller
3.1 依赖不变
3.2 web.xml不变
3.3 新建一个类,将它变为控制器,并且注入到容器当中
@Controller //代表当前类是一个控制器 同时将控制器注入到容器当中 可以给访问地址,也可以不给访问地址,因为控制方法必须要给访问地址
//RestController 是Controller注解和ResponseBody注解的结合体,如果使用这个注解,那么所有控制方法的返回结果将变为字符串或者对象,或者JSON
@RequestMapping("/SecondController") //给控制器访问地址
public class SecondController{
/**
* 控制器处理方法自定义
* 方法返回值自定义,可以为String Object void ModelAndView
* 方法参数自定义
*/
@RequestMapping("/firstReuqest")
public ModelAndView firstReuqest(String name){
ModelAndView mv=new ModelAndView();
System.out.println("客户端传递过来的name参数数据:"+name);
mv.addObject("username",name);
mv.setViewName("/index.jsp");
return mv;
}
}
3.4 开启注解扫描以及MVC注解支持
<!--开启包扫描器-->
<context:component-scan base-package="com.wdksoft"/>
<!--开启MVC注解支持-->
<mvc:annotation-driven/>
6、 登陆案例实现
4.1 login.jsp页面构建
<form method="post" action="/user/login">
用户名:<input type="text" name="username"/>
密码:<input type="text" name="password"/>
<input type="submit" value="提交"/>
</form>
4.2 创建控制器和控制方法处理用户请求
@Controller
@RequestMapping("/user")
public class UserController {
/**
* 登陆处理方法
*/
@RequestMapping("/login")
public ModelAndView login(String username, String password, HttpSession session){
ModelAndView mv=new ModelAndView();
if(username.equals("admin")&&password.equals("admin")){
session.setAttribute("user",username);
mv.setViewName("/welcome.jsp");
}else{
mv.setViewName("/login.jsp");
}
return mv;
}
}
4.3 配置大配置文件,开启注解扫描和MVC注解支持
<!--开启包扫描器-->
<context:component-scan base-package="com.wdksoft"/>
<!--开启MVC注解支持-->
<mvc:annotation-driven/>
4.4 配置web.xml加入中央调度器
<!--中央调度器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--初始化-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!--初始化时机-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
4.5 退出
/**
* 退出
*/
@RequestMapping("/logOut")
public ModelAndView logOut(HttpSession session){
ModelAndView mv=new ModelAndView();
session.removeAttribute("user");
mv.setViewName("/login.jsp");
return mv;
}
三、视图解析器
1、匹配前后缀
控制器返回视图名称即可,那么我们在视图名称的前面加上xxx 后面加上xxx
如果没有配置视图解析器的情况下,那么默认的视图解析器将什么都不会做,只寻址
视图解析器配置方案:
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--配置前缀-->
<property name="prefix" value="/jsp/"/>
<!--配置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
Controller方法:
@RequestMapping("/indexmethod2")
public ModelAndView index2(){
System.out.println("第二个方法");
ModelAndView mv=new ModelAndView();
//从控制器转发或者重定向到页面
mv.setViewName("news/news");
return mv;
}
2、ModelAndView工作替换
将方法返回值改为String ,那么返回值就是视图逻辑名称,如果需要携带数据给视图,那么可以采用request或者session,还可以使用Model和ModelMap
原始:
@RequestMapping("/indexmethod3")
public ModelAndView index3(){
ModelAndView mv=new ModelAndView();
System.out.println("第三个方法,执行逻辑");
mv.addObject("username","李四");
mv.setViewName("index");
return mv;
}
更改:
@RequestMapping("/indexmethod3")
public String index3(Model model){
System.out.println("第三个方法,执行逻辑");
model.addAttribute("username","李四");
return "index";
}
@RequestMapping("/indexmethod3")
public String index3(HttpServletRequest request){
System.out.println("第三个方法,执行逻辑");
request.setAttribute("username","张三");
return "index";
}
3、@ResponseBody使用
1.如果方法返回值类型为String类型那么,将以String类型字符串结果返回
2.如果方法返回值为Object类型,那么首先会自动将Object类型转换为JSON格式字符串,但是需要依赖于JACKSON
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.1</version>
</dependency>
@RequestMapping("/indexmethod4")
@ResponseBody //将返回值内容当成响应体响应给页面 会将返回值自动转换为JSON格式 但是需要依赖于Jackson
public Object index4(HttpServletRequest request) throws IOException {
System.out.println("第四个方法,执行逻辑");
request.setAttribute("username","张三");
User user=new User(1,"柴英杰");
return user;
}
3.方法返回值如果为ModelAndView则按照正常返回,匹配视图
4.方法返回值如果为void时,没有结果
四、如何解决静态资源拦截问题
一般我们的css,js,img,html等都是今天资源,那么如果我们使用到MVC时,我们用到了中央调度器,那么中央调度器获取到请求地址,匹配处理器映射器,将静态资源访问地址当做处理器地址
1、 web.xml配置
在我们匹配路径的时候加上静态资源放行 web.xml配置
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.gif</url-pattern>
</servlet-mapping>
2、 开启默认Servlet进行处理
DefaultServletHttpRequestHandler
首先所有的访问中央调度器的请求先经过DefaultServletHttpRequestHandler进行筛选,如果发现当前请求是今天资源请求,那么就找到静态资源,不是静态资源请求再
交给中央调度器处理。
在大配置文件中开启:
<!--开启默认Servlet-->
<mvc:default-servlet-handler/>
3、<!--配置资源目录和访问映射地址-->
<mvc:resources mapping="/**" location="/img"/>
五、.处理方法路径通配符
1、 请求路径前缀映射
@RequestMapping("/*indexmethod3")
2、请求路径后缀映射
@RequestMapping("/indexmethod3*")
3、 要求路径必须包含一层
@RequestMapping("/*/indexmethod3")
4、请求路径前必须包含0-N级
@RequestMapping("/**/indexmethod3")
六、控制方法返回值
控制方法常用返回值:void,String,ModelAndView,Object
1、方法返回值为void时
/**
* 方法返回值为void
* 1.能够接受客户端传递过来的数据
* 2.如果需要返回一个数据给客户端应该如何去实现
* response.getWriter().write("success");
* 3.如何向作用域当中保存数据
* 在方法参数当中,植入特定作用域对象,然后通过该对象保存数据
* 4.如何跳转页面:不会执行视图解析器
* 转发 request.getRequestDispatcher("/index.jsp").forward(request,response);
* 重定向 response.sendRedirect("/day03/index.jsp");
* 总结:如果控制方法返回值为Void的情况下,那么需要传递数据或者保存数据以及跳转页面时,采用以往Servlet形式
*/
@RequestMapping("/void")
public void voidMethod(HttpServletResponse response, HttpServletRequest request) throws IOException, ServletException {
System.out.println("=================方法返回值为void ================");
request.setAttribute("username","张三");
//转发
/*request.getRequestDispatcher("/index.jsp").forward(request,response);*/
//重定向
/*response.sendRedirect("index");*/
}
2、方法返回值为String
/**
* 方法返回值为String,默认匹配视图地址
* 1.如果方法返回值为null,那么默认将请求路径当做视图地址返回
* 2.如果方法返回值为null,那么如何向客户端携带数据
* 2.1 response:response.getWriter().write("success");
* 3.如果方法返回值为String类型字符串时,那么他会将返回值作为视图的逻辑名称,然后通过视图解析器进行视图查找,返回视图
* 4.如果方法返回值为String类型字符串时,如何去向客户端携带数据
* 4.1将数据保存到作用域当中,request作用于可以 session也可以
* 4.2使用Model对象或者是ModelMap对象
* model.addAttribute("username","王五");
* 5.使用String类型作为方法返回值,默认返回值为逻辑视图名称,匹配视图解析器,采用转发进行页面跳转
* 5.1 将返回值显示改为转发 ,试图解析器将不生效
* return "forward:/index.jsp";
* 5.2 将返回值显示改为重定向,试图解析器将不生效
* 6.如果需要要返回一个JSON格式字符串,可以采用如下方式
* 6.1 通过response对象和fastJSON连用,返回一个JSON格式字符串,那么返回值为null
* 6.2 可以采用@ResponseBody注解,该注解会自动将返回值改为JSON格式字符串,但是需要导入jackson依赖
*/
@RequestMapping("/string")
public String stringMethod(ModelMap mp) throws IOException {
mp.addAttribute("username","赵云");
/*return "forward:/index.jsp";*/
return "redirect:/index.jsp";
}
3、方法返回值为ModelAndView
Model和View 返回视图,携带数据
4、方法返回值为Object
4.1方法返回值如果为null,那么默认将请求路径当做视图地址返回
4.2方法返回值为一个字符串,则会将该字符串当做逻辑视图名称返回
4.3方法返回值如果为一个对象或者集合的时候,那么默认还是将请求路径当做视图地址返回
4.3.1 同步请求场景,可以采用request,model,modelAndView,response
4.3.2 异步请求场景,可以采用两种方式:
方式一:通过response对象和fastJSON连用,返回一个JSON格式字符串,那么返回值为null
方式二:可以采用@ResponseBody注解,该注解会自动将返回值改为JSON格式字符串,但是需要导入jackson依赖
5、应用场景
什么时候该用什么方法返回值,根据特定场景来:
场景一:需要返回视图,和携带数据情况,采用String
场景二:需要返回对象或者集合可以采用Object和@ResponseBody注解连用,前提得有Jackson
@RequestMapping("/obj")
@ResponseBody
public Object objectMethod() throws IOException {
User user=new User(1,"赵耀");
List<User> userList=new ArrayList<>();
userList.add(0,user);
System.out.println(user.getUname());
return userList;
}
七、控制方法参数
1、自动装配
客户端传递数据给控制方法,只要保证客户端传递的数据参数名称和方法的参数名称保持一致即可
1.1 零散参数装配
/**
* 自动装配
*/
@RequestMapping("/first")
public String firstRequest(String username, String password, Model model){
System.out.println("用户名:"+username+"\t密码:"+password);
model.addAttribute("username",username);
return "index";
}
1.2 对象数据装配:保证页面传递的参数和对象内的参数保持一致即可,对象属性必须包含Get和Set
实体:
public class User {
private String uname;
private String upwd;
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
}
页面:
<form method="post" action="/second/second">
用户名:<input type="text" name="uname"/>
密码:<input type="password" name="upwd"/>
<input type="submit" value="提交"/>
</form>
/**
* 自动装配:对象装配,保证客户端传递的数据的参数和对象的参数保持一致即可
*/
@RequestMapping("/second")
public String firstRequest(User user, Model model){
System.out.println("用户名:"+user.getUname()+"\t密码:"+user.getUpwd());
model.addAttribute("user",user);
return "index";
}
1.3 域属性自动装配问题,保证客户端传递的数据的参数和域属性对象的属性保持一致即可,包含get和set
1.4 集合装配
2、手动装配,当客户端传递的数据和控制方法的参数不一致
/**
* 手动装配:使用@RequestParam
* 在不一致参数前加上此注解,然后指定页面提交的参数名字
* name代表客户端提交过来的参数名
* Required代表是否允许页面不传递此数据,默认值为true,代表页面必须传递 false代表页面可以不传递
* defaultValue代表如果页面不传递时的默认值(如果指定了defaultVlaue的情况下那么Required自动改为false)
*/
@RequestMapping("/fivth")
public String fivthRequest(@RequestParam(name = "username",defaultValue = "张三") String uname, String upwd, Model model){
System.out.println("用户名:"+uname+"\t密码:"+upwd);
model.addAttribute("user",uname);
return "index";
}
3、RestFul风格API
体现在地址栏当中,之前我们使用get请求的时候,携带数据是通过?username=xxx&password=yyy
使用RestFul风格API传递时直接采用/方式即可 举例:/xxx/yyy
/**
* RestFul和@PathVariable
* @PathVariable获取地址栏当中的数据
*/
@RequestMapping("/six/{uname}/{upwd}")
public String sixRequest(@PathVariable("uname") String uname,@PathVariable("upwd") String upwd, Model model){
System.out.println("用户名:"+uname+"\t密码:"+upwd);
model.addAttribute("user",uname);
return "index";
}
八、如何解决数据乱码的问题
1、客户端传递数据给服务器发生数据乱码web.xml配置
<!--编码过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、服务器传递给客户端时如何解决数据乱码问题
如果使用的是@ResponseBody 则在@RquestMapping当中指定处理乱码方案:@RequestMapping(value = "/obj",produces = "text/json;charset=UTF-8")
如果使用的是response对象,则:resp.setContentType("text/html;charset=utf-8");
九、异常处理方案
1、系统异常处理器
控制方法如果发生异常,则会执行异常处理器:
自定义一个异常页面,如果发生报错,则会执行到异常页面
<!--系统异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--定制异常页面:服务器报错就会执行该页面-->
<property name="defaultErrorView" value="error"/>
<!--定制异常信息 向作用域当中存放了一个ex值,ex代表的就是所报异常-->
<property name="exceptionAttribute" value="ex"/>
</bean>
2、自定义异常处理类
自定义一个异常处理的类,如果发生次异常报错则执行特定异常规则的页面
控制器方法:
/**
* 要求用户提交的用户名必须为Admin 否则就报错
* 要求用户提交的年龄必须为小于80 否则就报错
* @return
*/
@RequestMapping("/myException")
public String myException(String uname,Integer uage) throws NameException, AgeException {
if(!uname.equals("admin")){
throw new NameException("用户名异常处理~");
}
if(uage>80){
throw new AgeException("年龄异常处理~");
}
return "index";
}
大配置文件:
<!--系统异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--定制异常页面:服务器报错就会执行该页面-->
<property name="defaultErrorView" value="error"/>
<!--定制异常信息 向作用域当中存放了一个ex值,ex代表的就是所报异常-->
<property name="exceptionAttribute" value="ex"/>
<!--自定义异常处理页面-->
<property name="exceptionMappings">
<props>
<prop key="com.wdksoft.exception.NameException">nameerror</prop>
<prop key="com.wdksoft.exception.AgeException">ageerror</prop>
</props>
</property>
</bean>
3、自定义异常处理器
/**
* 自定义异常处理器
*/
public class MyException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mv=new ModelAndView();
mv.addObject("ex",ex);
//定义一个默认的异常
mv.setViewName("error");
//自定义异常处理
if(ex instanceof NameException){
mv.setViewName("nameerror");
}
if(ex instanceof AgeException){
mv.setViewName("ageerror");
}
return mv;
}
}
applicationContext.xml配置
<bean class="com.wdksoft.exception.MyException"/>
4、异常注解
局部异常解决方案:该异常处理方法在哪个Controller就能够解决那个Controller异常
自定义异常处理方法,然后通过@ExceptionHandel指定处理异常的方法,以及可以捕获到的异常类型
@ExceptionHandler
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mv=new ModelAndView();
mv.addObject("ex",ex);
//定义一个默认的异常
mv.setViewName("error");
//自定义异常处理
if(ex instanceof NameException){
mv.setViewName("nameerror");
}
if(ex instanceof AgeException){
mv.setViewName("ageerror");
}
return mv;
}
5、全局异常注解处理方案
利用AOP思想,给所以的Controller进行增强
@ControllerAdvice //利用AOP思想,给所有的Controller都进行捕获
public class ThrowsControllerAdvice {
@ExceptionHandler
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
ModelAndView mv=new ModelAndView();
mv.addObject("ex",ex);
//定义一个默认的异常
mv.setViewName("error");
//自定义异常处理
if(ex instanceof NameException){
mv.setViewName("nameerror");
}
if(ex instanceof AgeException){
mv.setViewName("ageerror");
}
return mv;
}
}
全局异常处理和局部异常处理同时存在时,根据就近原则,如果内部能够解决该异常就内部自行解决,如果解决不了就执行全局的
十、文件上传
1、SpringMVC的单文件上传
JSP/Servlet时文件上传解决方案:
1.构建文件上传表单
enctype="multipart/form-data"
2.导入依赖:commons-io,commons-fileupload
3.判断是否是文件上传表单
如果是文件上传表单,则获取到上传的所有数据
循环获取到上传的每一个数据
文件数据和普通表单数据的解析方式不一致的
if(item.isFormField){
item.getFiledName.eq('title"){
item.getString("UTF-8");
}
}
String fileName=item.getName();
获取到要上传的地址
构建一个内存的文件
item.write(file);
SpringMVC文件上传
1.导入依赖commons-io,commons-fileupload
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
2.构建文件上传页面 enctype="multipart/form-data"
<form action="/file/fileUpload" method="post" enctype="multipart/form-data">
文件:<input type="file" name="file">
发布者:<input type="text" name="author"/>
<input type="submit" value="提交"/>
</form>
3.文件上传表单提交方式必须为post
说明:用户在页面提交数据到后台时,我们通过控制器中的控制方法获取用户提交的数据
文件数据:MultpartFile 普通表单数据获取方式与之前相同 name="author" String author
4.构建控制方法获取表单数据并且文件上传
@Controller
@RequestMapping("/file")
public class FileUploadController {
/**
* 如何获取到页面提交的文件上传数据
* MultipartFile file
* @return
*/
@RequestMapping("/fileUpload")
public String fileUpload(MultipartFile file, String author, HttpSession session) throws IOException {
System.out.println("作者:"+author);
/**
* 文件上传
*/
if(!file.isEmpty()){
//获取文件名称
String filename = file.getOriginalFilename();
//获取文件上传地址 获取服务器文件地址
String realPath = session.getServletContext().getRealPath("/WEB-INF/upload");
//构建文件对象
File fileUpload=new File(realPath+"\\"+filename);
//上传文件
file.transferTo(fileUpload);
}
return "index";
}
}
5.配置文件上传解析器
<!--构建文件解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--编码-->
<property name="defaultEncoding" value="UTF-8"/>
<!--最多上传字节大小-->
<property name="maxUploadSize" value="100000000000"/>
<!--限制单文件上传大小-->
<property name="maxUploadSizePerFile" value="5000000"/>
</bean>
2、SpringMVC多文件上传
<form action="/file/filesUpload" method="post" enctype="multipart/form-data">
文件1:<input type="file" name="files">
文件2:<input type="file" name="files">
文件3:<input type="file" name="files">
发布者:<input type="text" name="author"/>
<input type="submit" value="提交"/>
</form>
控制方法:
@RequestMapping("/filesUpload")
public String filesUpload(MultipartFile [] files,String author, HttpSession session) throws IOException {
System.out.println("提交文件作者:"+author);
for(MultipartFile file:files){
if(!file.isEmpty()){
//获取文件名称
String filename = file.getOriginalFilename();
//获取上传路径
String realPath = session.getServletContext().getRealPath("/WEB-INF/upload");
//构建文件对象
File fileUpload=new File(realPath+"\\"+filename);
//上传文件
file.transferTo(fileUpload);
}
}
return "index";
}
文件上传解析器
<!--构建文件解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--编码-->
<property name="defaultEncoding" value="UTF-8"/>
<!--最多上传字节大小-->
<property name="maxUploadSize" value="100000000000"/>
<!--限制单文件上传大小-->
<property name="maxUploadSizePerFile" value="5000000"/>
</bean>
3、SpringMVC文件下载
<a href="/file/download?fileName=kgc.jpg">文件下载</a>
@RequestMapping("/download")
public void downLoad(HttpServletRequest request, HttpServletResponse response,String fileName) throws IOException {
//构建文件下载路径
String realPath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
//构建文件对象
File file=new File(realPath,fileName);
//设置响应类型
response.setContentType("application/x-msdownload");
//设置文件下载时文件的显示
response.setHeader("Content-Disposition","attachment;fileName="+fileName);
//下载文件
Files.copy(file.toPath(),response.getOutputStream());
}
十一、拦截器
1、拦截器阐述
SpringMVC拦截器是干什么用的?
拦截器(Interceptor)就是用来拦截客户端发送的请求,可以在请求前后加入处理操作,而且是否放行也是拦截器进行操作的
2、拦截器案例
步骤:
1.创建一个自定义拦截器的类
public class MyInterceptor implements HandlerInterceptor {
/**
* 执行处理器之前执行得方法
* @param request 请求
* @param response 响应
* @param handler 处理器执行对象
* @return 返回值为True代表放行,false代表不放行
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("===========拦截器拦截到了目标请求============");
return true;
}
/**
* 执行完处理器之后,解析视图之前执行
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("¥¥¥¥¥¥¥执行完处理器之后,解析视图之前执行¥¥¥¥¥¥¥¥¥");
}
/**
* 执行完处理器之后,解析视图之后执行
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("car car car car执行完处理器之后,解析视图之后执行 car car car car");
}
}
2配置大配置文件,指定拦截器所拦截地址
<!--配置拦截器 代表可以有多个拦截器,按照顺序执行-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截路径-->
<mvc:mapping path="/file/**"/>
<!--自定义拦截类-->
<bean class="com.wdksoft.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
3、拦截器和过滤器的区别
拦截器:Interceptor
1.拦截器运行依赖于web框架
2.底层基于Java反射机制,属于面向切面编程的一种运用
3.一个控制器可以执行多次拦截器,但是拦截器只能拦截到控制请求,没有办法拦截静态资源请求
过滤器:Filter
1.过滤器运行依赖于Servlet容器,如果单纯的通过Servlet框架,那么是没有拦截器的,如果想要实现拦截功能则可以使用过滤器
2.过滤器主要为了过滤,比如敏感字符,字符编码等等
3.过滤器可以过滤所有请求,包括静态资源访问等,一个过滤器只能在容器初始化时调用一次
4、拦截器执行流程如下
1.客户端发送请求,请求到服务器
2.先会执行Filter的doFilter方法,进行请求过滤
3.如果请求过滤放行,则执行过滤器的service方法
4.请求流转到中央调度器
5.中央调度器将请求地址交给处理器映射器
6.处理器映射器将处理器执行链返回(处理器,拦截器)
7.执行拦截器的preHandler
8.拦截器如果放行,则请求到处理器适配器
9.处理器适配器执行处理器
10.处理器将MV返回结果交给处理器适配器
11.处理器适配器将结果返回给中央调度器
12.执行拦截器的postHandler(解析视图之前执行)
13.中央调度器调度视图解析器进行视图解析
14.试图解析器将返回结果交给中央调度器
15.执行拦截器的after方法
16.执行Filter过滤后的方法after
17.渲染视图
18.返回结果
十二、数据校验
1、数据校验
保证数据的安全性,传统方式:我们在前台进行Jquery或者JS验证,如果验证通过则提交数据到后台,减轻服务器压力
2、数据校验的实现方式
2.1 导入依赖
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
2.2 在Bean当中加入注解进行验证
public class UserInfo {
@NotNull(message = "用户名不能为空") //代表数据不允许为null
@Length(min = 5,max = 8,message = "用户名不能少于5位或大于8位")
private String username;
@NotNull(message = "年龄不能为空")
@Range(min = 16,max = 60,message = "年龄范围不合法")
private Integer userage;
@Email(message = "邮箱格式不合法")
private String useremail;
@Pattern(regexp = "/^1[3456789]\\d{9}$/",message = "手机号格式不合法")
private String phone;
@Pattern(regexp = "",message = "身份证号格式不合法")
private String usercard;
}
2.3 编写控制器进行控制
@RequestMapping("/register")
public String register(@Valid UserInfo info, BindingResult bindingResult){
//获取异常信息
List<ObjectError> allErrors = bindingResult.getAllErrors();
//JDK1.8新特性
/*allErrors.stream().forEach(item-> System.out.println(item));*/
for (ObjectError item:allErrors) {
System.out.println(item.getDefaultMessage());
}
System.out.println(info.toString());
//伪代码:把数据显示到前台页面
/* if(allErrors.size()>0){
String errorStr = JSON.toJSONString(allErrors);
response.getWriter.write(errorStr);
}else{
System.out.println(info.toString());
}*/
return "success";
}
十三、基于XML版本的SSM整合
1、步骤一:导入需要的依赖
mybatis,mysql,log4j,ehcache,pageHelper
spring-core,spring-beans,spring-context,spring-jdbc,spring-aop,c3p0/dbcp/durid
spring-web,spring-webmvc,javaee-api,jackson,commons-io,commons-fileupload,jstl
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<!--引入需要的ehcache插件-->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>1.2.3</version>
</dependency>
<!--mybatis整合ehcache的jar-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javaee</groupId>
<artifactId>javaee-api</artifactId>
<version>5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
2、创建配置文件
mybatis-config.xml
applicationContext.xml
datasource.properties
log4j.properties
-----------------------------------
ehcache.xml
generator.xml
3、 搭建实体层
User,Role,Bill,Provider,Address
4、新建Mapper层接口,新建业务方法
public interface Smbms_UserMapper {
//登陆
public Smbms_User userLogin(String username,String password);
}
5、 创建Mapper接口的配置文件
<!--登陆SQL-->
<select id="userLogin" resultType="com.wdksoft.entity.Smbms_User">
select * from smbms_user where userCode=#{userCode} and userPassword=#{userPassword}
</select>
6、 配置Mybatis大配置文件
1.6.1 开启别名
1.6.2 开启日志
1.6.3 加载小配置文件
1.6.4 如果需要用到分页pageHelper插件,则在Myabtis配置文件中开启插件
<!--根节点-->
<configuration>
<!--开启日志-->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!--别名配置-->
<typeAliases>
<package name="com.wdksoft.entity"/>
</typeAliases>
<!--开启插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper"></plugin>
</plugins>
<!--关联小配置文件-->
<mappers>
<package name="com.wdksoft.mapper"/>
</mappers>
</configuration>
7、 在Spring大配置文件中配置Mybaits环境
<!--加载数据源配置文件-->
<context:property-placeholder location="classpath:datasource.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--SqlSessionFactory工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!--开启Mapper层扫描-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.wdksoft.mapper"/>
</bean>
8、 新建Service层接口
public interface Smbms_UserService {
//登陆
public Smbms_User userLogin(String userCode,String userPassword);
}
9、新建Service层接口的实现类,调用Mapper层对象
public class Smbms_UserServiceImpl implements Smbms_UserService {
//植入Mapper层对象
private Smbms_UserMapper smbms_userMapper;
@Override
public Smbms_User userLogin(String userCode, String userPassword) {
return smbms_userMapper.userLogin(userCode,userPassword);
}
public Smbms_UserMapper getSmbms_userMapper() {
return smbms_userMapper;
}
public void setSmbms_userMapper(Smbms_UserMapper smbms_userMapper) {
this.smbms_userMapper = smbms_userMapper;
}
}
10、配置Spring大配置文件,将Mapper层和Service层注入到容器当中
<!--Mapper层代理工厂生成Mapper对象-->
<bean id="smbms_UserMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--生成该接口的代理对象-->
<property name="mapperInterface" value="com.wdksoft.mapper.Smbms_UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!--注入Service层-->
<bean id="smbms_UserService" class="com.wdksoft.service.impl.Smbms_UserServiceImpl">
<property name="smbms_userMapper" ref="smbms_UserMapper"/>
</bean>
11、测试,使用spring-test
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
要求junit版本必须不能低于4.12版本
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class SpringTest {
@Resource
private Smbms_UserService smbms_userService;
@Test
public void loginTest(){
Smbms_User smbms_user = smbms_userService.userLogin("admin", "admin");
System.out.println(smbms_user);
}
}
12、新建一个Controller控制器
public class SmbmsUserController implements Controller {
//植入Service层对象
private Smbms_UserService smbms_userService;
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView modelAndView=new ModelAndView();
String userCode = request.getParameter("userCode");
String userPassword = request.getParameter("userPassword");
Smbms_User smbms_user = smbms_userService.userLogin(userCode, userPassword);
if(smbms_user!=null){
request.getSession().setAttribute("user",smbms_user);
modelAndView.setViewName("success");
}else{
modelAndView.setViewName("login");
}
return modelAndView;
}
public Smbms_UserService getSmbms_userService() {
return smbms_userService;
}
public void setSmbms_userService(Smbms_UserService smbms_userService) {
this.smbms_userService = smbms_userService;
}
}
13、将控制器注入到容器当中,配置视图解析器,释放静态资源
<!--注入Controller-->
<bean id="/user" class="com.wdksoft.controller.SmbmsUserController">
<property name="smbms_userService" ref="smbms_UserService"/>
</bean>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--释放静态资源-->
<mvc:default-servlet-handler/>
14、配置web.xml
<!--编码过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--中央调度器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--初始化-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!--初始化时机-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
十四、基于SSM注解版本的SSM整合
1、导入依赖
将上方XML版本整合时所用依赖导入到工程当中
2、创建配置文件
mybatis-config.xml
applicationContext.xml
datasource.properties
log4j.properties
1、 创建对应的实体entity
4、创建Mapper层接口以及Mybatis小配置文件
/**
* 用户管理接口
*/
@Repository
public interface SmbmsUserMapper {
//登录方法
public Smbms_User userLogin(@Param("userCode") String userCode, @Param("userPassword") String userPassword);
}
<mapper namespace="com.smbms.mapper.SmbmsUserMapper" >
<!--登陆SQL-->
<select id="userLogin" resultType="Smbms_User">
select * from smbms_user where userCode=#{userCode} and userPassword=#{userPassword}
</select>
</mapper>
注意问题:默认程序不会编译java文件夹下的xml文件的,需要在pom.xml单中加入如下配置:
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
5、配置Mybatis-config.xml大配置文件
<!--根节点-->
<configuration>
<!--开启日志-->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!--配置别名-->
<typeAliases>
<package name="com.smbms.entity"/>
</typeAliases>
<!--加载小配置文件-->
<mappers>
<package name="com.smbms.mapper"/>
</mappers>
</configuration>
6、配置Spring核心大配置文件
<!--开启注解扫描-->
<context:component-scan base-package="com.smbms"/>
<!--加载数据源配置文件-->
<context:property-placeholder location="classpath:datasource.properties"/>
<!--配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--建立SqlSessionFactory工厂-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!--扫描Mapper层-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.smbms.mapper"/>
</bean>
7、创建Service层接口,以及接口的实现类
public interface SmbmsUserService {
//登录方法
public Smbms_User userLogin(String userCode,String userPassword);
}
@Service("smbmsUserService")
public class SmbmsUserServiceImpl implements SmbmsUserService {
//植入Mapper层对象
@Resource
private SmbmsUserMapper smbmsUserMapper;
@Override
public Smbms_User userLogin(String userCode, String userPassword) {
return smbmsUserMapper.userLogin(userCode,userPassword);
}
}
8、创建Controller层
@Controller
@RequestMapping("/user")
public class SmbmsUserController {
//植入Service层对象
@Resource
private SmbmsUserService smbmsUserService;
/**
* 登录的方法
*/
@RequestMapping("/login")
public String userLogin(String userCode, String userPassword, HttpSession session){
Smbms_User smbms_user = smbmsUserService.userLogin(userCode, userPassword);
if(smbms_user!=null){
//保存数据到Session
session.setAttribute("user",smbms_user);
return "welcome";
}else{
return "login";
}
}
}
9、配置Spring大配置文件
支持MVC注解,配置视图解析器,释放静态资源
<!--开启MVC注解-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--释放静态资源 -->
10、配置中央调度器
登录功能缺陷:点击登录时需要进行非空验证,登录失败时要响应信息给客户端
11、退出功能
/**
* 退出方法
*/
@RequestMapping("/logOut")
public String userLogOut(HttpSession session){
//清空session信息
session.removeAttribute("user");
return "login";
}
12、密码修改
1.1 验证旧密码
//用来判断旧密码是否正确
var flag=true;
//验证旧密码,获取旧密码文本框的焦点
$("#oldPassword").blur(function () {
//获取旧密码的值
var oldPass=$(this).val();
$.ajax({
url:"/user/checkPassword",
data:{"oldPass":oldPass},
type:"POST",
success:function (result) {
if(result=="success"){
$("#checkPassWordResult").text("*原密码正确~");
flag=true;
}else{
$("#checkPassWordResult").text("*原密码错误~");
flag=false;
}
}
})
});
@RequestMapping("/checkPassword")
@ResponseBody
public String checkPassword(String oldPass,HttpSession session){
Smbms_User user = (Smbms_User)session.getAttribute("user");
if(user.getUserpassword().equals(oldPass)){
return "success";
}else{
return "failure";
}
}
1.2 表单校验
/**
* 表单提交验证
*/
$("#myForm").submit(function () {
//验证旧密码是否正确
if(flag==false){
alert('旧密码不正确,请验证后提交~');
return false;
}else if($("#newPassword").val()!=$("#reNewPassword").val()){
alert('新密码和确认密码不正确,请校验后重试~');
return false;
}
});
1.3 更新密码
更新成功要清空session并且跳转回login.jsp页面
Mapper层:
//修改密码方法
public int updatePassword(@Param("id")Integer id,@Param("newPassword") String newPassword);
Mapper小配置i文件
<!--修改密码的方法-->
<update id="updatePassword">
update Smbms_User set userpassword=#{newPassword} where id=#{id}
</update>
Service层:
//修改密码方法
public int updatePassword(Integer id,String newPassword);
ServiceImpl层:
@Override
public int updatePassword(Integer id, String newPassword) {
return smbmsUserMapper.updatePassword(id,newPassword);
}
Controller层:
/**
* 修改密码
*/
@RequestMapping("/updatePassowrd")
public String updatePassowrd(String newPassword,HttpSession session){
Smbms_User user = (Smbms_User)session.getAttribute("user");
int count = smbmsUserService.updatePassword(user.getId(), newPassword);
if(count>0){
//清空session
session.removeAttribute("user");
//跳转页面
return "login";
}else{
return "welcome";
}
}
十五、过滤器实现
1、创建过滤器
@WebFilter(urlPatterns = {"/welcome.jsp"})
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器执行初始化方法------------------");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("过滤器拦截非法请求------------");
HttpServletRequest httpServletRequest=(HttpServletRequest)request;
Object user = httpServletRequest.getSession().getAttribute("user");
if (user == null ) {
request.getRequestDispatcher("/login.jsp").forward(request,response);
}else{
chain.doFilter(request,response);
}
}
@Override
public void destroy() {
System.out.println("销毁方法--------------");
}
}
2、在xml中配置过滤器
<!-- 使用filter实现登录控制 -->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.smbms.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<!-- 所有的管理页面需要登录后才能访问 -->
<url-pattern>/welcome.jsp</url-pattern>
</filter-mapping>

浙公网安备 33010602011771号