二.SpringMVC
1.新建一个Moudle ,添加web支持
2.确定带入SpringMVC的依赖
junit
junit
4.12
org.springframework
spring-webmvc
5.1.9.RELEASE
javax.servlet
servlet-api
2.5
javax.servlet.jsp
jsp-api
2.2
javax.servlet
jstl
1.2
src/main/resources
**/*.properties
**/*.xml
false
src/main/java
**/*.properties
**/*.xml
false
3.配置web.xml,注册DispatcherServlet
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-servlet.xml
1
springmvc
/
4.编写SpringMVC的配置文件!名称:springmvc-servlet.xml:[servletname]-servlet.xml (名字是官方规定的)
5.添加处理映射器
6.添加处理器适配器
7.添加视图解析器
8.编写我们要操作业务Controller,要么实现Controller接口,要么增加注解;需要返回一个ModelAndView,装数据,封视图。
package com.jiuqi;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//ModelAndView 模式和视图
ModelAndView mv = new ModelAndView();
//封装对象,放在ModelAndView
mv.addObject("msg","HelloSpringMVC!");
//封装要跳转的视图,放在ModelAndView中
mv.setViewName("hello"); // /WEB-INF/jsp/hello.jsp
return mv;
}
}
9.将自己的类交给SpringIOC容器,注册bean
10.写要跳转的jsp页面,显示ModelAndView存放的数据,以及我们的正常页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
${msg}
11.配置Tomcat启动测试
12.遇到的问题
我们正确的代码可能会出现404,这是可能是我们idea环境出现问题,查看是否有lib文件夹,没有就新建lib文件夹把库文件添加上去。
1.更改SpringMVC-servlet.xml
在以后开发中我们只需要更改我们包的位置,其他是固定的。
2.更改Java控制类Controller
package com.jiu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller //让Soring IOC容器初始化自动扫描
public class HelloController {
@RequestMapping("/hello") //URL请求路径
public String hello(Model model) {
model.addAttribute("msg","Hello,SpringMVCAnnotation");
return "hello"; //会被视图解析器处理
}
}
如果在类写上RequestMapping()会与方法上的RequestMapping()形成父子关系,访问的路径会变成 //localhost:8080/类路径/方法路径,但我们一般不会在类上写
1.原来的:
@Controller
public class RestFulController {
@RequestMapping("/r1")
public String test(int a, int b, Model model) {
int c = a + b;
model.addAttribute("msg","结果为:"+c);
return "test";
}
}
URL://localhost:8080/springmvc_04_controller_war_exploded2/r1?a=1&b=3
2.RestFul风格:
@Controller
public class RestFulController {
@RequestMapping("/r1/{a}/{b}")
public String test(@PathVariable int a, @PathVariable int b, Model model) {
int c = a + b;
model.addAttribute("msg","结果为:"+c);
return "test";
}
}
URL: //localhost:8080/springmvc_04_controller_war_exploded2/r1/1/3
3.如果我们想使用指定的方法实现 方式一
@Controller
public class RestFulController {
@RequestMapping(value = "/r1/{a}/{b}",method = {RequestMethod.DELETE})
public String test(@PathVariable int a, @PathVariable int b, Model model) {
int c = a + b;
model.addAttribute("msg","结果为:"+c);
return "test";
}
}
4.方式二
public class RestFulController {
/*
@GetMapping
@PostMapping
@putMapping
@DeleteMapping
@PatchMapping
地址栏相同但我们可以通过不同方式实现不同的效果
*/
@GetMapping("/r1/{a}/{b}")
public String test(@PathVariable int a, @PathVariable int b, Model model) {
int c = a + b;
model.addAttribute("msg","结果为:"+c);
return "test";
}
@PostMapping("/r1/{a}/{b}")
public String test(@PathVariable int a, @PathVariable int b, Model model) {
int c = a + b;
model.addAttribute("msg","结果为:"+c);
return "test";
}
}
@Controller
public class ModelTest1 {
@RequestMapping("/m1/t1")
public String test1(HttpServletResponse resp, HttpServletRequest req) {
HttpSession session = req.getSession();
System.out.println(session.getId());
return "test";
}
}
在没有视图解析器时我们可以用重定向和转发进行跳转页面
springmvc-servlet.xml:
@Controller
public class ModelTest1 {
@RequestMapping("/m1/t1")
public String test1(HttpServletResponse resp, HttpServletRequest req) {
HttpSession session = req.getSession();
System.out.println(session.getId());
return "redirect:/index.jsp";
}
}
1.接收一个参数
在pom.xml注入lombok:
SpringMVC
org.example
1.0-SNAPSHOT
4.0.0
springmvc-04-controller
8
8
org.projectlombok
lombok
1.18.10
user实体类:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private int age;
}
UserController:
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/u1")
public String test(String name, Model model) {
//1.获取前端的数据,数据会直接获取不用再去请求或者重定向
System.out.println("前端传递的参数为:"+name); //验证传递的参数
//2。将返回的结果传递给前端
model.addAttribute("msg",name);
//3.试图跳转
return "test";
}
}
当参数名和域名称不一样时使用RequestParam("")
UserController:
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/u1")
//@RequestParam("username"),username是前端域名称与参数名name不同,加上RequestParam("")就可以是name获取username的值
public String test(@RequestParam("username") String name, Model model) {
//1.获取前端的数据,数据会直接获取不用再去请求或者重定向
System.out.println("前端传递的参数为:"+name); //验证传递的参数
//2。将返回的结果传递给前端
model.addAttribute("msg",name);
//3.试图跳转
return "test";
}
}
2.接收一个对象
@Controller
@RequestMapping("/user")
public class UserController {
//一.接收为一个参数
@GetMapping("/u1")
//@RequestParam("username"),username是前端域名称与参数名name不同,加上RequestParam("")就可以是name获取username的值
public String test(@RequestParam("username") String name, Model model) {
//1.获取前端的数据,数据会直接获取不用再去请求或者重定向
System.out.println("前端传递的参数为:"+name); //验证传递的参数
//2.将返回的结果传递给前端
model.addAttribute("msg",name);
//3.试图跳转
return "test";
}
//二.接收为一个对象
@GetMapping("/u2")
public String test2(User user) {
System.out.println(user);
return "test";
}
}
找到自己tomcat存放的位置打开conf找到servlet.xml打开后在指定位置加上URIEncoding="UTF-8"
form.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
EncodingController.java:
@Controller
public class EncodingController {
@PostMapping("/e/t1")
public String test1(String name, Model model) {
model.addAttribute("msg",name);
return "test";
}
}
1.在web.xml上配置SpringMVC的乱码过滤
encoding
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
encoding
/*
2.解决不了去配置tomcat
3.你复制大神写的过滤器
1.js转化为json,json转化为js
jsontest.html:
Title
2.在我们前后端分离时,就不用视图解析器了
在pom.xml加上:
com.fasterxml.jackson.core
jackson-databind
2.10.0
springmvc-servlet.xml: 处理json乱码问题
方法一: @ResponseBody 当前方法不走视图解析
@Controller
public class UserController {
@RequestMapping("/j1")
@ResponseBody //加上这个注解就不会走视图解析器,直接返回一个字符串
public String json1() throws JsonProcessingException {
//jackson下ObjectMapping
ObjectMapper mapper = new ObjectMapper();
User user = new User("九七",2,"男");
String s = mapper.writeValueAsString(user);
return s;
}
}
方法二:@RestController后面所有方法都不走视图解析
@RestController
public class UserController {
@RequestMapping("/j2")
//@ResponseBody //加上这个注解就不会走视图解析器,直接返回一个字符串
public String json2() throws JsonProcessingException {
//jackson下ObjectMapping
ObjectMapper mapper = new ObjectMapper();
List userList = new ArrayList();
User user1 = new User("九七1",2,"男");
User user2 = new User("九七2",2,"男");
User user3 = new User("九七3",2,"男");
User user4 = new User("九七4",2,"男");
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
String s = mapper.writeValueAsString(userList);
return s;
}
}
解决时间戳问题:
方法一:
@RequestMapping("/j3")
public String test3() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");
String format = simpleDateFormat.format(date);
String s = objectMapper.writeValueAsString(format);
return s;
}
方法二:
@RequestMapping("/j4")
public String test4() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
//不使用时间戳
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");
objectMapper.setDateFormat(simpleDateFormat);
Date date = new Date();
String s = objectMapper.writeValueAsString(date);
return s;
}
3.把方法二代码提取实现复用
JsonUtil:
public class JsonUtils {
public static String getJson(Object object,String dataFormat) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dataFormat);
ObjectMapper objectMapper1 = objectMapper.setDateFormat(simpleDateFormat);
String s = null;
try {
s = objectMapper1.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return s;
}
}
controller :
@RequestMapping("/j5")
public String test5(){
Date date = new Date();
return JsonUtils.getJson(date,"yyyy-MM-dd:HH:mm:ss");
}
当我们只有一个参数时:
在JsonUtil实现方法重载:
public class JsonUtils {
public static String getJson(Object object){
return getJson(object,"yyyy-MM-dd:HH:mm:ss");
}
public static String getJson(Object object,String dataFormat) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dataFormat);
ObjectMapper objectMapper1 = objectMapper.setDateFormat(simpleDateFormat);
String s = null;
try {
s = objectMapper1.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return s;
}
}
controller:
@RequestMapping("/j6")
public String test6(){
List userList = new ArrayList();
User user1 = new User("九七1",2,"男");
User user2 = new User("九七2",2,"男");
User user3 = new User("九七3",2,"男");
User user4 = new User("九七4",2,"男");
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
return JsonUtils.getJson(userList);
}
他是写好的开源框架不用我们写了。
pom.xml
com.alibaba
fastjson
1.2.47
这里有json和Java的相互转化:
@RequestMapping("/j7")
public String test7(){
List userList = new ArrayList();
User user1 = new User("九七1",2,"男");
User user2 = new User("九七2",2,"男");
User user3 = new User("九七3",2,"男");
userList.add(user1);
userList.add(user2);
userList.add(user3);
//java对象转Json字符串
String s = JSON.toJSONString(userList);
System.out.println("java对象转Json字符串"+s);
//java对象转Json字符串
String s1 = JSON.toJSONString(user1);
System.out.println("java对象转Json字符串"+s1);
//json字符串转Java对象
Object o1 = JSON.parseObject(s1,User.class);
System.out.println("json字符串转Java对象"+o1);
//java对象转Json对象
JSONObject jsonObject2 = (JSONObject)JSON.toJSON(user2);
System.out.println("java对象转Json对象"+jsonObject2);
//json对象转Java对象
User user = JSON.toJavaObject(jsonObject2, User.class);
System.out.println("json对象转Java对象"+user);
return s;
}
1.建立一个新的项目
2.添加web支持
3.配置父项目添加过支持所以直接配置web文件就行,和前面一样
4.配置web上classpath下的文件applicationContext.xml
5.添加jquery,可以直接在jQuery官网下载
6.ajax初体验
编写pojo层user
@Data
@AllArgsConstructor
@NoArgsConstructor
public class user {
private String name;
private int age;
private String sex;
}
在controller层编写AjaxController.java
package com.jiu.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class AjaxController {
@RequestMapping("/a1")
public void a1(String name, HttpServletResponse response) throws IOException {
System.out.println("a1:param=>name"+name);
if("jiuqi".equals(name)){
response.getWriter().print("true");
}else {
response.getWriter().print("flase");
}
}
@RequestMapping("/a2")
@ResponseBody
public List a2(){
List userList = new ArrayList<>();
userList.add(new user("九七",20,"男"));
userList.add(new user("六七",18,"男"));
userList.add(new user("珊珊",21,"女"));
return userList;
}
@RequestMapping("/a3")
@ResponseBody
public String a3(String name, String pwd) {
String msg = "";
if (name!=null){
if("admin".equals(name)){
msg = "ok";
}else {
msg = "名字有误";
}
}
if (pwd!=null){
if("123456".equals(pwd)){
msg = "ok";
}else {
msg = "密码有误";
}
}
return msg;
}
}
编写index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
<%--失去焦点的时候发去一个请求--%>
用户名:
编写test2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
姓名
年龄
性别
<%--数据:后台--%>
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
用户名:
密码:
7.因为a2/a3没有走视图解析器所以我们为避免乱码需要把applicationContext.xml里的
1.建立一个新的项目
2.添加web支持
3.配置父项目添加过支持所以直接配置web文件就行,和前面一样
4.配置web上classpath下的文件applicationContext.xml
5.编写拦截器
拦截器需要在applicationContext.xml注册,我们继承的接口HandlerInterceptor可以实现一下方法preHandle(拦截前),postHandle(拦截后),afterCompletion(清理),但我们一般只写第一个。
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
//判断什么时候登陆了
//第一次登录没有session会被拦截
if(session.getAttribute("userLoginInfo") != null) {
return true;
}
//解决第一次没有session的拦截
if (request.getRequestURI().contains("login")){
return true;
}
if (request.getRequestURI().contains("goLogin")){
return true;
}
//判断什么时候没有登录
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
}
6.controller下的LoginController
@Controller
@RequestMapping("/user")
public class LoginController {
@RequestMapping("/main")
public String main() {
return "main";
}
@RequestMapping("/goLogin")
public String goLogin() {
return "login";
}
@RequestMapping("/login")
public String login(HttpSession session, String username, String password, Model model) {
//把信息存在session上
session.setAttribute("userLoginInfo",username);
model.addAttribute("username",username);
return "main";
}
@RequestMapping("/goOut")
public String goOut(HttpSession session) {
session.removeAttribute("userLoginInfo");
return "login";
}
7.index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
登录页面
首页
8.login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
登录页面
9.main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
首页
${username}
1.建立一个新的项目
2.添加web支持
3.添加支持
commons-fileupload
commons-fileupload
1.3.3
javax.servlet
javax.servlet-api
4.0.1
4.配置web上classpath下的文件applicationContext.xml
6.index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
$Title$
7.controller层
package com.jiu.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
@RestController
public class FileController {
//@RequestParam("file")将name=file控件得到的文件封装成commonsMultipartFile对象
//批量上传CommonsMultipartFile则为数组即可
@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";
}
//采用file.Transto来保存上传的文件
@RequestMapping("/upload2")
public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
//上传路径保存设置
String path = request.getServletContext().getRealPath("upload");
File realPath = new File(path);
if (!realPath.exists()) {
realPath.mkdir();
}
//上传文件地址
System.out.println("上传文件保存地址:" + realPath);
file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));
return "redirect:/index.jsp";
}
@RequestMapping(value = "/download")
public String downloads(HttpServletResponse response, HttpServletRequest request) throws IOException {
//要下载的图片地址
String path = request.getServletContext().getRealPath("/upload");
String fileName = "1.png";
//设置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);
//读取文件-输入流
InputStream input = new FileInputStream(file);
//写出文件-输出流
OutputStream out = response.getOutputStream();
byte[] buff = new byte[1024];
int index = 0;
while ((index = input.read(buff)) != -1) {
out.write(buff, 0, index);
out.flush();
}
out.close();
input.close();
return null;
}
}