SpringMVC + json
文章目錄
1. 導包及初始化配置
1.1 導包
spring-mvc需要的包:
spring核心包
spring-web
spring-webmvc
json需要的包:
jackson-core
jackson-databind
jackson-annotations
1.2 mavne依賴
<!--springmvc框架-->
<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>
<!--json包(Springmvc默認使用jackson)-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.8</version>
</dependency>
1.3 配置前端(核心)控制器
- web.xml中配置前端控制器。
<!--配置springmvc核心控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--
contextConfigLocation配置springmvc加載的配置文件(配置處理器、映射器、適配器等等)
如果不配置contextConfigLocation,默認加載WEB-INF/servlet名稱-servlet.xml(springmvc-servlet.xml)
-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!--在tomcat啓動的時候就創建核心控制器-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
url-pattern:
第一種:*.action,訪問以.action結尾由DispatcherServlet進行解析。
第三種:/,所有訪問的地址都由DispatcherServlet進行解析,但對於靜態文件的解析需要配置不讓DispatcherServlet進行解析。
第三種:/*,錯誤的配置方法,運行結果報錯。
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
1.4 配置靜態資源放行
- applicationContext.xml中配置靜態資源放行。
<!--靜態資源放行-->
<mvc:default-servlet-handler/>
2. 實現控制器的三種方式
2.1 實現Controller接口
- 實現Controller接口
public class ControllerOne implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
return null;
}
}
- applicationContext.xml配置controller對應的bean
<!-- name:配置controller的訪問路徑 -->
<bean name="/my1.do" class="com.yogie.controller.ControllerOne"></bean>
2.2 實現HttpRequestHandler接口
public class ControllerTwo implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
- 配置bean
<bean name="/my2" class="com.yogie.controller.ControllerTwo"></bean>
2.3 全註解的方式
2.3.1 開啓註解支持和註解掃描
- applicationContext.xml中配置開啓註解
<!--開啓註解支持-->
<mvc:annotation-driven/>
<!--開啓註解掃描-->
<context:component-scan base-package="com.yogie.controller"/>
@Controller
@RequestMapping("/my3")
public class ControllerThree {
@RequestMapping("/test")
public String test(){
return null;
}
}
2.3.2 springmvc註解大全
1、@Component 表示一個組件(類),把當前組件加入IOC容器,加入容器的組件的名稱默認是類名且第一個字母小寫。@Component("userDao")//相當於:<bean id="userDao" class=...> 可簡化爲:@Component
2、@Repository 表示是一個持久層的組件
3、@Service 表示是一個業務邏輯層的組件
4、@Controller 表示是一個控制層的組件
5、@Scope("prototype")指定對象單例還是多例
6、@Resource 默認根據修飾的字段名稱會去IOC容器找對象自動注入,如果名稱沒有找到,在根據類型查找。如果該類型在IOC容器有多個對象,報錯!根據類型沒有找到對象,報錯!
7、Resource(name="") 會根據指定的名稱去容器找對象自動注入。
3. 獲取參數的四種形式
3.1 直接獲取
@RequestMapping("/param1")
//前臺地址:localhost/param1?password=123&name=tom
public ModelAndView param1(String name,String password){
//前臺傳遞過來的參數名與方法的參數名必須一致,順序可以不一致
return null;
}
@RequestMapping("/param2")
//前臺地址:localhost/param2?password=123&username=tom
//解決前臺後臺參數名字不一致的情況
public ModelAndView param2(@RequestParam("username")String name, String password){
return null;
}
3.2 封裝到Javabean對象
@RequestMapping("/param3")
//前臺地址:localhost/param3?pwd=123&name=tom
public ModelAndView param3(User user){
return null;
}
3.3 通過HttpServletRequest對象
@RequestMapping("/param4")
//前臺地址:localhost/param4?password=123&name=tom
public ModelAndView param4(HttpServletRequest request){
//通過request對象的getParameter()方法獲取值
String name = request.getParameter("name");
return null;
}
3.4 Restful風格傳遞參數
@RequestMapping("/param5/GET/{name}/{pwd}")
//前臺地址:localhost/param5/GET/tom/123
//注意:使用restful風格傳遞多個參數時,前臺的參數順序與方法的形參要一致。
public ModelAndView param5(@PathVariable("name")String name,@PathVariable("pwd")String password){
return null;
}
4. 返回數據及視圖的五種方式
- 配置視圖解析器
<!--配置視圖解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前端-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--後綴-->
<property name="suffix" value=".jsp"/>
</bean>
4.1 Model方式
public String returnData1(Model model){
//實際上將數據放入到了request域中
model.addAttribute("name","tom");
User user = new User("tom","123");
//前臺通過user來獲取User對象的數據
model.addAttribute(user);
//返回視圖名稱:配置了視圖解析器,會自動添加前綴後後綴
return "list";
}
4.2 ModelAndView方式
public ModelAndView returnData2(){
ModelAndView mv = new ModelAndView();
mv.addObject("name","tom");
//設置視圖
mv.setViewName("list");
return mv;
}
4.3 HttpServletRequest方式
public void returnData3(HttpServletRequest request,HttpServletResponse response){
request.setAttribute("name","tom");
//轉發的方式,不會走視圖解析器
request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request,response);
}
4.4 直接返回對象
@RequestMapping("/data")
//這種情況返回的是默認視圖,即:data.jsp
//data.jsp中可以獲取到user對象的數據
public User returnData4(){
User user = new User("adf","123");
return user;
}
4.5 返回json數據
@RequestMapping("/data5")
@ResponseBody//添加這個註解後,數據將會以json的格式返回到前臺,不會返回視圖
public List<User> returnData5(){
List<User> list = Arrays.asList(...);
return list;
}
//注意:如果User對象中有日期類型的字段,需要給對應的get、set方法添加屬性。
public class User{
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
public Date getDate() {
return date;
}
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public void setDate(Date date) {
this.date = date;
}
}
5. 請求轉發與重定向
控制器中的視圖設置,以下這兩種情況都不會進入視圖解析器的配置中加前綴後綴。但是區別於不加forward和redirect關鍵字的情況:如果不加這兩個關鍵字,一定會進入視圖解析器加前綴後綴。
5.1 轉發
@RequestMapping("/forward")
public String forwordPage(){
return "forward:WEB-INF/jsp/hello.jsp";
}
5.2 重定向
@RequestMapping("/redirect")
public String redirectPage(){
return "redirect:index.html";
}
6. 解決Springmvc中文亂碼問題
<!--springmvc亂碼過濾器-->
<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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
6. 文件上傳與下載
6.1 配置文件上傳解析器
<!--文件上傳解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--配置文件上傳的最大尺寸爲:100kb-->
<property name="maxUploadSize" value="102400"/>
</bean>
6.1 文件上傳
@RequestMapping(path = "/upload",method = RequestMethod.POST)
public String upload(String name, MultipartFile upload, HttpServletRequest request) throws IOException {
System.out.println("post方法");
System.out.println("其他屬性name::" + name);
System.out.println("上傳文件的類型:" + upload.getContentType());
System.out.println("上傳文件名稱:" + upload.getName());
System.out.println("上傳文件文件名:" + upload.getOriginalFilename());
// 上傳的流
InputStream inputStream = upload.getInputStream();
// 獲取webapp路徑
String webapp = request.getServletContext().getRealPath("/uploads/");
System.out.println(webapp);
/*File file = new File(webapp, upload.getOriginalFilename());
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
// 如果upload文件夾不存在,就創建
parentFile.mkdirs();
}
// 拷貝到webapp一個目錄裏面
IOUtils.copy(inputStream, new FileOutputStream(file));*/
return "upload";
}
6.2 文件下載
@RequestMapping("/download")
public void download(HttpServletRequest req, HttpServletResponse resp) throws IOException {
//解決文件名中文亂碼,對文件名進行utf-8編碼
String encode = URLEncoder.encode("springmvc執行流程.jpg", "UTF-8");
resp.setCharacterEncoding("utf-8");
//設置建議的下載文件名
resp.setHeader("Content-Disposition", "filename=springmvc執行流程.jpg");
//設置文件名的類型,查w3cschool中HTTP content-type對照表
resp.setHeader("Content-Type", "application/x-img");
// 準備文件
String webapp = req.getServletContext().getRealPath("/uploads/");
File file = new File(webapp, "springmvc執行流程.jpg");
FileInputStream inputStream = new FileInputStream(file);
IOUtils.copy(inputStream, resp.getOutputStream());
}
7. SpringMVC的執行流程
7.1 springmvc工作流程圖解
7.2 springmvc工作流程詳解
首先應清楚:控制器Controller = 處理器Handler
- 用戶發送請求至前端控制器DispatcherServlet。
- DispatcherServlet收到請求調用HandlerMapping處理器映射器。
- 處理器映射器找到具體的處理器(可以根據xml配置、註解進行查找),生成處理器對象及處理器攔截器(如果有則生成)一併返回給DispatcherServlet。
- DispatcherServlet調用HandlerAdapter處理器適配器(附註:如果成功獲得HandlerAdapter後,此時將開始執行攔截器的preHandler(…)方法)。
- HandlerAdapter經過適配調用具體的處理器(Controller)。調用之前有一個入參的過程,在Handler的入參過程中,如果有配置,spring還會做一些額外的工作:
HttpMessageConveter:將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息
數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等
數據格式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等
數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中
- Controller執行完成返回ModelAndView。
- HandlerAdapter將controller執行結果ModelAndView返回給DispatcherServlet。
- DispatcherServlet將ModelAndView傳給ViewReslover視圖解析器。
- ViewReslover解析後返回具體View,這個view僅僅是一個頁面(視圖)名字,且沒有後綴名。
- DispatcherServlet根據View進行渲染視圖(即將模型數據填充至視圖中)。
- DispatcherServlet響應用戶。