sevlet转发和重定向
用户访问servlet后,servlet处理完自己将结果给用户叫转发(url不变),给地址让用户请求叫重定向。
HelloMVC
1.在web.xml中配置
<!--1.注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件:[servlet-name]-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.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>
2.编写HelloController
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//模型和视图
ModelAndView mv=new ModelAndView();
//封装对象
mv.addObject("msg","HelloSpringMVC");
//封装要跳转的视图
mv.setViewName("hello");
return mv;
}
}
3.关联一个springmvc配置文件
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--Handler-->
<bean id="/hello" class="com.ma.controller.HelloController"/>
4.编写jsp文件,配置tomcat
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
可能遇到的问题
- 如果jar包存在,显示无法输出,就在IDEA的项目发布中(Tomcat)添加lib依赖
- spingmvc中没配好,没有配置注解驱动等。
SpringMVC执行原理
- DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。我们假设请求的url为 : http://localhost:8080/SpringMVC/hello如上url拆分成三部分:http://localhost:8080-服务器域名、SpringMVC-部署在服务器上的web站点、hello-表示控制器通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
- HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
- HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。
- HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
- HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
- Handler让具体的Controller执行。
- Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
- HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
- DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
- 视图解析器将解析的逻辑视图名传给DispatcherServlet。
- DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
- 最终视图呈现给用户。
SpringMVC注解开发
在Spring中一般采用@RequestMapping注解来完成映射关系,要想使@RequestMapping注解生效,必须注册DefaultAnnotationHandlerMappin和一个AnnotationMethodHandlerAdapter实例,这两个实例分别在类级别和方法级别处理。而annotation-driven配置帮助我们自动完成上述两个实例的注入。
RestFul风格
- 概念Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。
- 使用方法:
- @RequestMapping(value = "/hello",method = {RequestMethod.POST})
- 快捷方式GetMapping("/add{a}/{b})
SpringMVC结果跳转
- 在没有视图解析器的时候,使用全路径。
- 转发
return "forward:/WEB-INF/index.jsp"
- 重定向
return "forward:/index.jsp"
- 有视图解析器的时候,可以在视图解析器中设置前缀、后缀拼接。
spring接受参数
- 接受一个非对象时,在参数前加注解@RequestParam,为明确这是个前端接受的参数,不管需不需要都加上。
- 接收的字段名必须类中字段名一致
- 乱码问题
加一个filter
- 编写类继承servlet包下的Filter,重写doFilter方法
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse);
}
- 在web.xml中配置filter
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.ma.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>encoding</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>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
SpringMVC使用JSON
- 导入包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
- 获取JSON字符串
User user=new User(1,"马天乐",22);
String str=new ObjectMapper().writeValueAsString(user);
乱码问题,在SpringMVC文件中配置
//JSON乱码问题配置
<!--JSON乱码问题配置-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Ajax
- Ajax是一种之刷新页面部分内容而不刷新整个页面的技术,例如百度的搜索框,每次点击或键入一些内容都会有不同的推荐。
- jQuery.ajax的主要属性
$.ajax({
url:"${pageContext.request.contextPath}/a1",
data:{"name":$("#username").val()},
success: function (data) {
alert(data);
},
error: function () {
}
})
其他属性:官方文档
拦截器
拦截器是AOP思想的一个具体实现。
使用方法:
- 编写拦截器类继承HandlerInterceptor
public class MyInterceptor implements HandlerInterceptor {
//return true;放行,执行下一个拦截器,反之拦截
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
}
- 在springmvc文件中配置
<mvc:interceptors>
<mvc:interceptor>
<!--/**拦截当前文件夹以及子文件夹,/*拦截当前文件夹,不包括子文件夹-->
<mvc:mapping path="/**"/>
<bean class="com.ma.config.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
springmvc实现文件上传
- 在springmvc配置文件中配置:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--配置编码格式,必须与pageEncoding属性一致,以便能正常读取表单内容-->
<property name="defaultEncoding" value="utf-8"/>
<!--上传文件大小限制,单位为字节,10m=10485760字节-->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
- 编写页面
<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
<input type="file" name="file">
<input type="submit" name="upload">
</form>
- 编写Controller
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file ,HttpServletRequest request) throws IOException {
//获取文件名 : file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
//如果文件名为空,直接回到首页!
if ("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
System.out.println("上传文件名 : "+uploadFileName);
//上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
//如果路径不存在,创建一个
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
System.out.println("上传文件保存地址:"+realPath);
InputStream is = file.getInputStream(); //文件输入流
OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
//读取写出
int len=0;
byte[] buffer = new byte[1024];
while ((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
os.flush();
}
os.close();
is.close();
return "redirect:/index.jsp";
}
@RequestMapping(value="/download")
public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
//要下载的图片地址
String path = request.getServletContext().getRealPath("/upload");
String fileName = "timg.jpg";
//1、设置response 响应头
response.reset(); //设置页面不缓存,清空buffer
response.setCharacterEncoding("UTF-8"); //字符编码
response.setContentType("multipart/form-data"); //二进制传输数据
//设置响应头
response.setHeader("Content-Disposition", "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));
File file = new File(path,fileName);
//2、 读取文件--输入流
InputStream input=new FileInputStream(file);
//3、 写出文件--输出流
OutputStream out = response.getOutputStream();
byte[] buff =new byte[1024];
int index=0;
//4、执行写出操作
while((index= input.read(buff))!= -1){
out.write(buff, 0, index);
out.flush();
}
out.close();
input.close();
return "ok";
}