项目地址:https://github.com/Jonekaka/javaweb-springMVC-55
54上篇已经讲述
springmvc_day02_01_response
java
jsp
修改后,指定要去调用哪个界面,产生强关联. 重定向两次请求,请求转发,一次请求,而且需要自己写完整路径,软件不猜了
jsp
用关键字转发和重定向,用不了视图解析器,要写正确的路径
重定向需要写项目路径,这个底层已经加了,不用写 java
假如ajax异步请求,如何接受后台的json数据 前端控制器拦截 DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而 不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置 位置,文件路径(xx下不拦截谁)
按键发送json请求 jsp 接受到后弹窗收到的内容 那么是否存在一种可能,将数据组自动json相互转化 导入jar包
java 获得请求体的内容,@RequestBody 这里已经自动将收到的json数据打包进user了 如果返回对象,前端默认的也是json,这里自动转化 以前还需要response写输出流,现在不必
springmvc_day02_02_fileupload 导入文件上传的jar包
A form 表单的 enctype 取值必须是:multipart/form-data (默认值是:application/x-www-form-urlencoded) (—解释—:)【将整个表单分成几个部分,可能有的是文本框,有的是文件的内容等等】 enctype:是表单请求正文的类型 B method 属性取值必须是 Post (—解释—:)【如果是get,会把内容弄到地址栏上,有限制。】 C 提供一个文件选择域
使用分隔符分成了若干部分 —————————–7de1a433602ac 分界符 Content-Disposition: form-data; name=“userName” 协议头 aaa 协议的正文 —————————–7de1a433602ac Content-Disposition: form-data; name=“file”; filename=“C:\Users\zhy\Desktop\fileupload_demofile\b.txt” Content-Type: text/plain 协议的类型(MIME 类型) bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb —————————–7de1a433602ac– 然后取得内容写入就得到了文件
使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload 和 commons-io。commons-io 不属于文件上传组件的开发 jar 文件,但Commons-fileupload 组件从 1.1 版本开始,它 工作时需要 commons-io 包的支持。
创建工程时如果提示副工程,不需要关闭即可
导入坐标依赖
jsp
java 之所以删除临时文件,是因为上传文件>10k,就会生成临时文件,否则在内存中直接搞定 对于名字设定唯一值
@RequestMapping("/fileupload1")
public String fileuoload1(HttpServletRequest request) throws Exception {
System.out.println("文件上传...");
// 使用fileupload组件完成文件上传
// 上传的位置
String path = request.getSession().getServletContext().getRealPath("/uploads/");
// 判断,该路径是否存在
File file = new File(path);
if(!file.exists()){
// 创建该文件夹
file.mkdirs();
}
// 解析request对象,获取上传文件项
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// 解析request
List<FileItem> items = upload.parseRequest(request);
// 遍历
for(FileItem item:items){
// 进行判断,当前item对象是否是上传文件项
if(item.isFormField()){
// 说明普通表单向
}else{
// 说明上传文件项
// 获取上传文件的名称
String filename = item.getName();
// 把文件的名称设置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid+"_"+filename;
// 完成文件上传
item.write(new File(path,filename));
// 删除临时文件
item.delete();
}
}
return "success";
}
原理分析 解析request请求,交给文件解析器拿到上传的文件项信息,返回一个上传文件对象 自带的一个解析对象,通过参数绑定数据传送 解析器在spring.xml中配置
SpringMVC框架提供了MultipartFile对象,该对象表示上传的文件,要求变量名称必须和表单file标签的 name属性名称相同。 spring.xml
<!--配置文件解析器对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760" />
</bean>
jsp
<h3>Springmvc文件上传</h3>
<form action="/user/fileupload2" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload" /><br/>
<input type="submit" value="上传" />
</form>
java
/**
* SpringMVC文件上传
* @return
*/
@RequestMapping("/fileupload2")
//上传对象自带
public String fileuoload2(HttpServletRequest request, MultipartFile upload) throws Exception {
System.out.println("springmvc文件上传...");
// 使用fileupload组件完成文件上传
// 上传的位置
String path = request.getSession().getServletContext().getRealPath("/uploads/");
// 判断,该路径是否存在
File file = new File(path);
if(!file.exists()){
// 创建该文件夹
file.mkdirs();
}
// 说明上传文件项,文件已经不需要自己解析了
// 获取上传文件的名称
String filename = upload.getOriginalFilename();
// 把文件的名称设置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid+"_"+filename;
// 完成文件上传
upload.transferTo(new File(path,filename));
return "success";
}
在实际开发中,我们会有很多处理不同功能的服务器。例如: 应用服务器:负责部署我们的应用 数据库服务器:运行我们的数据库 缓存和消息服务器:负责处理大并发访问的缓存和消息 文件服务器:负责存储用户上传文件的服务器。 提高我们项目 的运行效率
注意端口不要重复
java
/**
* 跨服务器文件上传
* @return
*/
@RequestMapping("/fileupload3")
public String fileuoload3(MultipartFile upload) throws Exception {
System.out.println("跨服务器文件上传...");
// 定义上传文件服务器路径
String path = "http://localhost:9090/uploads/";
// 说明上传文件项
// 获取上传文件的名称
String filename = upload.getOriginalFilename();
// 把文件的名称设置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid+"_"+filename;
// 创建客户端的对象
Client client = Client.create();
// 和图片服务器进行连接
WebResource webResource = client.resource(path + filename);
// 上传文件
webResource.put(upload.getBytes());
return "success";
}
jsp
<h3>跨服务器文件上传</h3>
<form action="/user/fileupload3" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="upload" /><br/>
<input type="submit" value="上传" />
</form>
springmvc_day02_03_exception
出现异常查看具体信息是开发者的事情,使用者不需要这么详细的信息
异常处理器调度异常界面,展示友好的异常信息 异常信息类,java,接受异常信息
/**
* 自定义异常类
*/
public class SysException extends Exception{
// 存储提示信息的
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public SysException(String message) {
this.message = message;
}
}
ctrl alt T快速选择代码,然后环绕代码生成if else,try catch等 异常处理类
@RequestMapping("/testException")
public String testException() throws SysException{
System.out.println("testException执行了...");
try {
// 模拟异常
int a = 10/0;
} catch (Exception e) {
// 打印异常信息
e.printStackTrace();
// 抛出自定义异常信息
throw new SysException("查询所有用户出现错误了...");//就是刚才写的错误信息类,构造方法
}
return "success";
}
继承接口,当有异常时检测到有处理器就交给处理器执行
/**
* 异常处理器
*/
public class SysExceptionResolver implements HandlerExceptionResolver{
/**
* 处理异常业务逻辑
* @param request
* @param response
* @param handler
* @param ex
* @return
*/
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 获取到异常对象,判断类型是否符合,不符合就强转
SysException e = null;
if(ex instanceof SysException){
e = (SysException)ex;
}else{
e = new SysException("系统正在维护....");
}
// 创建ModelAndView对象,这个是返回值,可以跳转页面
ModelAndView mv = new ModelAndView();
//存键值对
mv.addObject("errorMsg",e.getMessage());
//跳转页面,error.jsp
mv.setViewName("error");
return mv;
}
<!--配置异常处理器-->
<bean id="sysExceptionResolver" class="cn.Learn_Java.exception.SysExceptionResolver"/>
springmvc_day02_04_interceptor
jsp
<a href="user/testInterceptor" >拦截器</a>
java类
@RequestMapping("/testInterceptor")
public String testInterceptor(){
System.out.println("testInterceptor执行了...");
return "success";
}
继承接口后发现没有方法报错,那是因为他内部默认的方法已经默认实现了,如果不使用预制的可以重写 spring.xml
先执行拦截器然后放行,否则
<!--配置拦截器-->
<mvc:interceptors>
<!--配置拦截器-->
<mvc:interceptor>
<!--要拦截的具体的方法-->
<mvc:mapping path="/user/*"/>
<!--不要拦截的方法,写一个就行,既然这个拦截了,其他的肯定不拦截,反之亦然
<mvc:exclude-mapping path=""/>
-->
<!--配置拦截器对象-->
<bean class="cn.Learn_Java.controller.cn.Learn_Java.interceptor.MyInterceptor1" />
</mvc:interceptor>
<!--配置第二个拦截器-->
<mvc:interceptor>
<!--要拦截的具体的方法-->
<mvc:mapping path="/**"/>
<!--不要拦截的方法,
<mvc:exclude-mapping path=""/>
-->
<!--配置拦截器对象-->
<bean class="cn.Learn_Java.controller.cn.Learn_Java.interceptor.MyInterceptor2" />
</mvc:interceptor>
</mvc:interceptors>
拦截器1,内部有三个方法,说明白,可以有多个拦截器 在这些类中,能够调用界面已经是最终的步骤,因此无返回拦截效果
不要奇怪,他们不是一起执行的,而是第一个拦截器确实已经执行完了,进入下一个,然后返回时发现条件又满足了继续一个个的拦截
/**
* 自定义拦截器
*/
public class MyInterceptor1 implements HandlerInterceptor{
/**
* 预处理,controller方法执行前
* return true 放行,执行下一个拦截器,如果没有,执行controller中的方法
* return false不放行
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor1执行了...前1111");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
return true;
}
/**
* 后处理方法,controller方法执行后,只会拦截方法,success.jsp执行之前
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor1执行了...后1111");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
}
/**
* success.jsp页面执行后,该方法会执行,优先级更低
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor1执行了...最后1111");
}
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100238.html原文链接: