Spring mvc
Model
在Model1中,View层和Controller层合二为一了,也就是JSP,JavaBean则作为Model层单独存在。这样的话,JSP既要做显示,又要处理一定的业务逻辑,对于单一职责的原则来说,这显然不符合。JSP的职责太重,就显得中间部分有些臃肿。
<%@ page import="club.banyuan.service.UserService" %>
<%@ page import="club.banyuan.service.impl.UserServiceImpl" %>
<%@ page import="club.banyuan.model.User" %><%--
Created by IntelliJ IDEA.
User: 19641
Date: 2021/3/16
Time: 19:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%@page isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
UserService userService=new UserServiceImpl();
User user =userService.getUser();
request.setAttribute("user",user);//此处双引号要一样里面的值
%>
<div>
<div>
Username: ${user.username}
</div>
<div>
Nickname: ${user.nickname}
</div>
</div>
</body>
</html>
MODel2 真正的mvc
@WebServlet(name = "UserServlet", value = "/user")
public class UserServlet extends HttpServlet {
private UserService userService;
@Override
public void init() throws ServletException {
super.init();
userService=new UserServiceImpl();
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取model
User user=userService.getUser();
//设置model供view使用
request.setAttribute("user",user);
//跳转到view
request.getRequestDispatcher("user1.jsp").forward(request,response);
在view里面进行显示
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
//在web。xml进行配置 spring的配置
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
<!-- 下面都是springmvc的配置--> //在web。xml中
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 指定springmvc配置文件-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
//这个是spring的配置 applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描范围-->
<context:component-scan base-package="club.banyuan.mvc">
<!-- 需要排除的 Controller-->
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
</beans>
Controller
@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
@RequestMapping("/user") //RequestMapping是路由
public String user(){
return "user1";
}
}
RestfulAPI
资源
我们把网络上的一个实体,或者网络上的一个具体信息,称为资源
表现层
我们把资源呈现出来的表现形式称为表现层
比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。
JSON
前后端分离时代
后端部署后端,提供接口和数据
前端负责渲染后端的数据
json是一种数据交换的格式
<script type="text/javascript">
let user={
name:"wyp",
sex:"nan"
};
//将js对象转化为json对象
var json = JSON.stringify(user);
console.log(json);
//将json对象转化为js对象
var object = JSON.parse(json);
console.log(object)
</script>
json解析工具
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
Restful风格
- 为了安全 隐藏了参数
@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
@RequestMapping("/user/{a}/{b}") //访问时加上/user/1/2才可以访问到jsp
public String user(@PathVariable int a, @PathVariable int b, Model model){
int res=a+b;
model.addAttribute("msg","结果为"+res);
return "user1";
}
}
路由RequestMapping
@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
@RequestMapping("/demo")
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
//@RequestMapping("/user") //这样写的话必须/demo/user才能访问
//指定方法
public String user(){
return "user1";
}
}
确定请求访问的方式
@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
@RequestMapping("/demo")
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
@RequestMapping(value = "/user",method = RequestMethod.GET) //Request.GET确定get
public String user(){
return "user1"; //访问的时user1.jsp页面
}
}
更简便的写法
@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
@RequestMapping("/demo")
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
// @RequestMapping(value = "/user",method = RequestMethod.GET)
@GetMapping("/user") //跟上行代码一样
public String user(){
return "user1";
}
@PostMapping("")
public String users(){
}
@PutMapping()
@DeleteMapping
}
关于ResponseBody加了之后返回的是字符串 不是jsp
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
// @RequestMapping(value = "/user",method = RequestMethod.GET)
@GetMapping("/user")
@ResponseBody
public String user(){
return "user1";
}
@RestController
//@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
@RequestMapping("/demo")
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
// @RequestMapping(value = "/user",method = RequestMethod.GET)
@GetMapping("/user")
// @ResponseBody
public String user(){
return "user1";
}
上面的是为了省略ResponsBody写法返回字符串写了该注解就不会走视图解析器
- 如果是jsp页面,会出现波浪号idea
路径变量
@RestController
//@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
@RequestMapping("/demo")
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
// @RequestMapping(value = "/user",method = RequestMethod.GET)
@GetMapping("/user/{userId}")
@ResponseBody
public String user(@PathVariable Integer userId){
return userId.toString();
}
多个路径变量
@RestController
//@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
@RequestMapping("/demo")
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
// @RequestMapping(value = "/user",method = RequestMethod.GET)
@GetMapping("/user/{userId}/{userId2}")
@ResponseBody
public String user(@PathVariable Integer userId, @PathVariable Integer userId2){
return userId.toString()+userId2.toString();
}
正则表达式
@RestController
//@Controller //springmvc扫描controller 扫码到Controller 再扫描 !RequestMapping
@RequestMapping("/demo")
public class UserController {
public UserController(){
System.out.println("sss调用了");
}
// @RequestMapping(value = "/user",method = RequestMethod.GET)
@GetMapping("/user/{userId}/{userId2: [0-9a-zA-Z]+}") //[0-9a-zA-Z]+正则表达式匹配路径变量
@ResponseBody
public String user(@PathVariable Integer userId, @PathVariable Integer userId2){
return userId.toString()+userId2.toString();
}
不配置视图解析器
不建议
@GetMapping("/m1/t1")
public String user(){
return "forward:/index.jsp";
}
@GetMapping("/e2")
public String user1(){
return "redirect: /index.jsp";
}
有视图解析器
<!-- 配置jsp视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="jspViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/Jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
@GetMapping("/m1/t1")
public String user(){
return "test";//转发
}
@GetMapping("/e2")
public String user1(){
return "redirect: /index.jsp";//重定向不需要视图解析器,本身就是重新到一个地方
}
WEB-INF下面的内容都是只能由服务器级别才能访问,客户端并不能访问。什么是客户端级别?什么是服务器级别呢?
转发就是服务器级别,浏览器的地址不会变,因为,客户端发送一个请求,服务器受理之后,发现要请求内容还要再去别的请求,那么转发就是服务器自己去处理完成。不麻烦客户端(浏览器)了,所以客户端上面的地址栏不会改变。
重定向:就是客户端级别的。服务器收到请求后,发现还要去请求别的内容,但是服务器自己不想处理,那么就告诉客户端,你自己去处理吧,那么客户端就去请求那个别的内容了。所以客户端(浏览器)地址栏就会改变了。
偷懒神器
@Data
@AllArgsConstructor
@NoArgsConstructor//加入lombok这几个注解get set 方法无参有参构造全部写完
public class User1 {
private int id;
private String name;
private int age;
}
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
model modelMap
model精简版
modelmap 拥有linkedhashmap得所有方法
model.addAtribute("属性名view中显示得如果是jsp要开启el",前端的参数)
springmvc
<!-- spring mvc 编码过滤器-->
<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>
//在web.xml
ModelAndView
@Controller
public class ViewController {
@GetMapping("/t4")
public ModelAndView user3(User user){
ModelMap modelMap = new ModelMap();
modelMap.put("user",user);
final ModelAndView modelAndView = new ModelAndView("user1",modelMap);
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.setViewName("user1");
return modelAndView;
}
}
设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 .
跟Model一样,将返回值结果传递给前端并显示
返回值
@RestController //返回值得各种类型 加这个注解
public class RetValueController {
@GetMapping("/Integer")
public Integer getInteger(){
return 100;
}
@GetMapping("/obj")
public User gertUser(){
User user = new User();
user.setUsername("wyp");
user.setNickname("tom");
return user;
}
@GetMapping("/List")
public List getList(){
return Arrays.asList(gertUser());
}
@GetMapping("/map")
public Map getMap(){
Map map=new HashMap();
map.put( "code",0);
map.put("msg","pk");
map.put("data",getList());
return map;
}
}
json在mvc
解决json乱码问题
@Controller
public class JsonTestController {
@GetMapping(value = "/j1",produces = "application/json;charset=utf-8")//解决json乱码问题
@ResponseBody
public String json1() throws JsonProcessingException {
//jackson ObjectMapper
ObjectMapper mapper=new ObjectMapper();
//创建一个对象
User1 user1 = new User1(22, "汪", 22);
String s = mapper.writeValueAsString(user1);
return s;//返回值为json格式
}
}
**上一种比较麻烦 ** 在spring-mvc .xml中加入统一解决乱码问题
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
@GetMapping("/j2")
public String json2() throws JsonProcessingException {
//jackson ObjectMapper
ObjectMapper mapper=new ObjectMapper();
//创建一个对象
User1 user1 = new User1(22, "汪", 22);
User1 user2 = new User1(23, "汪", 22);
User1 user3 = new User1(24, "汪", 22);
User1 user4 = new User1(25, "汪", 22);
List<User1> list=new ArrayList<>();
list.add(user1);
list.add(user2);
list.add(user4);
list.add(user3);
String s = mapper.writeValueAsString(list);
return s;//返回值为json格式
}
@GetMapping("/j3") //json解析字符串
public String json3() throws JsonProcessingException {
ObjectMapper mapper=new ObjectMapper();
Date date = new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return mapper.writeValueAsString(sdf.format(date));
}s
编写json工具类
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 dateFormat) {
ObjectMapper mapper = new ObjectMapper();
//不使用时间差的方式
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//自定义日期格式对象
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
//指定日期格式
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
fastjson
用于json对象跟javaBean相互转换fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。实现json的转换方法很多,最后的实现结果都是一样的。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
System.out.println("*******Java对象 转 JSON字符串*******");
String str1 = JSON.toJSONString(list);
System.out.println("JSON.toJSONString(list)==>"+str1);
String str2 = JSON.toJSONString(user1);
System.out.println("JSON.toJSONString(user1)==>"+str2);
System.out.println("\n****** JSON字符串 转 Java对象*******");
User1 jp_user1=JSON.parseObject(str2, User1.class);
System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);
System.out.println("\n****** Java对象 转 JSON对象 ******");
JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));
System.out.println("\n****** JSON对象 转 Java对象 ******");
User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);