本章会讲解:
部分注解,
SpringMvc的重定向,转发,
项目中设置中央处理器(DispatcherServlet),视图解析器(ViewResolver),
以及SpringMvc自带的文件上传设置。
一、注解
1. @RequestMapping
这部分有一博主叫Whitemeen太白基础用法写的很全,可以去看看,我只在这演示动态网站项目的用法:
@RequestMapping主要用于将任意HTTP 请求映射到控制器方法上,
说人话就是放在control层的方法上面,通过在浏览器url网址输入框直接输入,此注解@RequestMapping内部设置的值,就可以达到servlet的效果,从而达到HTTP请求映射的效果(感觉我说的也不是人话),
动态网站项目主要注意三个设置就可代替servlet的一些基操,设置如下:
(1). 设置注解内部value值
直接在注解后+一个(“xxxxxxxxx”),并在网址输入框输入xxxxxxxxx即可请求映射,如如下举例:
@RequestMapping("index")
(2). 设置method属性
method属性指只使用某种类型的请求,
但是,
注意,如果没设置该属性,@RequestMapping注解所请求类型的方法将接受所有类型的请求
具体属性设置如下:
//指只能通过get请求,映射到该方法
@RequestMapping(method = RequestMethod.GET)
//类似还有post等其他请求我就不写了
//亦可value和method联合一起写
@RequestMapping(value="xxx",method = RequestMethod.GET)
//我看每个SpringMvc版本写法不一,有时候是@RequestMapping("xxx",method = RequestMethod.GET)
(3). 设定返回值
设定返回值就是设定return的值,
如果返回的是String类型,就会转发到某个具有相同名称的前端界面,
如果想要测视图对象啥的也行,
就可以实现转发和重定向,具体相关代码我会放在第二章讲解。
(4). 示例代码
@RequestMapping("/test2.do")
public ModelAndView test2(){
ModelAndView mv=new ModelAndView("index");//index是逻辑视图
mv.addObject("username", "txc");
return mv;
}
2. @RequestParam
这个注解用法类似于request.getParameter();,说白了也就是获取前端name值的,关于这个知识点,宜春的博客写的很好,可以去看看,具体用法如下:
前端设置如下:
<form action="uploadfile" method="post" enctype="multipart/form-data">
<input type="file" name="file1">
<input type="submit" value="提交">
</form>
后端设置如下:
// @RequestParam("file1")指前端获取的name传到CommonsMultipartFile对象这进行封装
@RequestMapping("uploadfile")
public String uploadfile(@RequestParam("file1") CommonsMultipartFile file) throws Exception{
System.out.println("获取源文件名称:"+file.getOriginalFilename());
// 输入流关联源文件
InputStream inputstream = file.getInputStream();
File file2 = new File("C://aa");
// 输出流关联目标文件
OutputStream outputstream = new FileOutputStream(file2+"//"+file.getOriginalFilename());
int len = 0;
byte[] b = new byte[1024];
while((len = inputstream.read(b)) != -1){
outputstream.write(b, 0, len);
outputstream.flush();
}
outputstream.close();
inputstream.close();
return "show";
}
我这后端写的有些复杂,说到底就是通过@RequestParam获取文件名到CommonsMultipartFile这进行封装,然后通过输入输出流上传到某个文件夹中
3. @ResponseBody
此注解主要用于把集合,或者数据转换成Json字符串,在某个返回集合或者数组的方法上加上即可,具体代码如下:
// @Validated意思是启用JSR并接收命名的对象
// BindingResult而用来接收错误的信息
@RequestMapping("/validator")
// 把返回值转换成json字符串
@ResponseBody
public List<ObjectError> validator(@Validated Student stu,BindingResult result){
List<ObjectError> list = null;
// 判断结果是否有误
if(result.hasErrors()){
list=result.getAllErrors();
for (int i = 0; i < list.size(); i++) {
System.out.println("输出验证字段出现的问题"+list.get(i).getCode());
System.out.println("循环输出出错对象名:"+list.get(i).getObjectName());
System.out.println("循环输出错误:"+list.get(i).getDefaultMessage());
for (int j = 0; j < list.get(i).getArguments().length; j++) {
System.out.println(list.get(i).getArguments()[j]);
}
System.out.println();
}
}
return list;
}
二、重定向和转发
利用@RequestParam重定向,或者转发的设置一般都在我第一章提到的第三步return中,如果只传前端页面的名称,默认用转发。
1.重定向
// 重定向到前端
// return "redirect:/WEB-INF/views/index2.jsp";
2.转发
// 亦可以手动转发到前端
return "forward:/WEB-INF/views/index2.jsp";
三、设置中央处理器,视图解析器
1.设置中央处理器
中央处理器就是前面SpringMvc原理图提到的DispatcherServlet,它的设置有些特殊,需在web.xml里设置,就是在src/main/webapp/WEB-INF/里的web.xml,如下图所示:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
但要注意的是:中央处理器它会默认拦截所有静态资源,导致普通框架,图片被拦截。
这里我也会放到SpringMvc拦截器里说,
四种常用处理静态资源不被拦截方法如下:
(1). 设置自定义拦截器
在SpringMvc.xml文件里设置自定义拦截器,具体代码如下:
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截所有的请求,这个必须写在前面,也就是写在【不拦截】的上面 -->
<mvc:mapping path="/**/*"/>
<!-- 但是排除下面这些,也就是不拦截请求 -->
<mvc:exclude-mapping path="/**/*.css"/>
<mvc:exclude-mapping path="/**/*.js"/>
<mvc:exclude-mapping path="/**/*.jpg"/>
<bean> class="com.xh.activiti.commons.interceptor.LoginHandlerInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
之后便是重写HandlerIntercetor接口的三个方法,分别是:afterCompletion,postHandle,preHandle
这三个方法在springMvc执行原理流程中分别执行位置我会用上期图来讲:
afterCompletion:是在渲染视图之后处理,主要用来进行事后的资源清理(在第10到第11步之间)
postHandle:是在HandlerAdapter调度handler之后(在第5步到第6步之间)
preHandle:是在找到处理handler对象的HandlerMapping之后(在第3步到第4步之间)
具体代码如下:
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LoginIntercepter implements HandlerInterceptor{
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
// TODO Auto-generated method stub
}
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
// TODO Auto-generated method stub
}
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
// 获取当前的请求地址
String url = request.getRequestURI();
System.out.println("request.getRequestURI()->url:"+url);
// 判断请求地址是否有login,如果有直接放行
if(url.indexOf("login")>=0){
return true;
}
HttpSession session = request.getSession();
String username=(String)session.getAttribute("username");
// 输入框获取为空,直接重定向到自己
if(username==null){
response.sendRedirect("login.jsp");
}
return true;
}
}
(2). 使用默认静态资源处理Servlet
首先在配置的SpringMvc.xml启用默认的Servlet:
<mvc:default-servlet-handler/>
其次在web.xml写对资源的处理:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>/static/*"</url-pattern>
</servlet-mapping>
注意:一定要写在Dispatcher前面,不然没效果
(3). 设置拦截为*.do拦截
直接在web.xml里配置的SpringMvc后面写即可:
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
(4). 通过mvc:resource解决静态资源的拦截(推荐)
<mvc:resource/>允许资源放置在任何地方,以及可以对其资源提供优化,这也使为什么推荐使用它的原因,,具体代码如下:
<!-- mapping被称为映射地址 -->
<!-- location是指项目中真正的地址 -->
<!-- 也就是说mapping可以为假,location一定要为真 -->
<mvc:resources location="/image/" mapping="/image/**"></mvc:resources>
2.设置视图解析器
视图解析器就是前面SpringMvc原理图提到的ViewResolver,设置它就能解析视图了
<!-- 通用视图解析器 -->
<!-- /WEB-INF/views/属于安全地址,直接访问不到,只能通过特殊跳转才能访问到,但是放在WEB-INF外部就行 -->
<bean id="viewResolverCommon"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
四、Mvc异常处理的三种方式
1. 使用@ExceptionHandler注解
使用该注解要注意:进行异常处理的方法必须与出错的方法在同一个Controller里面,比如:
@ExceptionHandler(Exception.class)
public String myselfException(Exception e){
System.out.println("==========1=============");
e.printStackTrace();
return "index";
}
说实话这样写很麻烦,一千种方法就要写一千个注解,但是其优点是灵活。
2. 实现HandlerExceptionResolver接口
独创一个类实现该接口即可,实现全局异常处理。具体代码如下:
//(全局异常处理方式)方法二:实现 HandlerExceptionResolver 接口
//可用@Component实现实例化对象,因为Exception不在三层之内
@Component
public class MySelfException implements HandlerExceptionResolver{
public ModelAndView resolveException(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,
Exception arg3) {
System.out.println("HandlerExceptionResolver.ModelAndView:重写方法");
return null;
}
}
3. 使用@controlleradvice注解
感觉不是太重要,俺就先不写这个了,嘿嘿
五、采用流的方式实现文件上传
额。。。。。。为啥要将这个呢,因为这是Mvc自带文件上传,作为SpringMvc首个项目还是很可以的,Spring框架配置,以及Maven配置我就不多说了,我的第一篇就有。具体代码如下:
相关配置:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
前端设置:
<form action="uploadfile" method="post" enctype="multipart/form-data">
<input type="file" name="file1">
<input type="submit" value="提交">
</form>
control层设置:
@RequestMapping("/fileupload.do")
public String fileupload(@RequestParam("file") CommonsMultipartFile file) throws Exception{
//创建输入流关联源文件
InputStream is=file.getInputStream();
//创建输出流关联目标文件
File file1=new File("D://dd1");
if(!file1.exists()){
file1.mkdir();
}
OutputStream os=new FileOutputStream(file1+"//"+"1.jpg");
//传输
int temp=-1;
while((temp=is.read())!=-1){
os.write(temp);
}
os.flush();
os.close();
is.close();
// 亦可用file的transferTo方法,实现上面的过程
// transferTo此方法就是封装上面这个过程
// file.transferTo(new File("C://aa//"+file.getOriginalFilename()));
return "index";
}
在SpringMvc.xml配置:
注意:必须指定此id为multipartResolver,不然无法执行
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--配置上传文件的编码格式 -->
<property name="defaultEncoding" value="UTF-8"></property>
<!--配置上传文件的最大长度 -->
<property name="maxUploadSize" value="1024*1024"></property>
<!--配置读取文件到内存的最大字节数 -->
<property name="maxInMemorySize" value="10240000000"></property>
<!--判断是否要延迟解析文件 -->
<property name="resolveLazily" value="true"></property>
</bean>