快速⼊门SSM框架——实现前后端数据交互
刚开始学习SSM框架,看着各式各样的书,听着⼤佬们录的视频,貌似觉得很简单。但是亲⾃实践之后,就不会这么觉得了。
从github上拉了很多个项⽬下来,⼀个个花⾥胡哨,SSM框架结构命名各式各样,⼀个jsp⽹页或者java类就有成百上千⾏代码,⽽我什么都看不懂。
其实那个时候我只想搞懂SSM环境配置的逻辑,以及前端⽹页如何读取数据库中的数据(即前端⽹页显⽰数据库数据),因为jsp⽹页⼀旦能成功显⽰数据库中的数据,其他功能就可以以此类推,都是复制粘贴的事情了。
看不懂,没⼈教,然后⾯向搜索引擎的编程,最后写总结,已经是我长期以来的常态了。接着我就像做英语阅读那样,⼀⾏⼀⾏代码的去查,最后把意思串起来,得到了我的理解。当然我的理解不⼀定准确,欢迎⼤佬指正。
总的思路:
前端⽹页显⽰数据库数据⼤概分为以下⼋个步骤:
1. 在l中,使⽤<welcome-file-list>标签,设置默认打开的⽹页/WEB-INF/views/login/test.jsp。
2. 在该前端⽹页test.jsp中增加⼀个按钮,按钮指向"<%=baPath%>/summary/test1.do"(<%=baPath%>后⾯再说)。
3. 该地址被l 中的DispatcherServlet(拦截器)所拦截,只剩下/summary/test1。
4. l 将/summary/test1 传送到l,接着l去扫描其管辖的包下有没有对应的controller类。
5. 在controller类(后端Java类)中找到@RequestMapping(value = "/summary/test1")的⽅法,执⾏这个⽅法。
6. 在⽅法中,使⽤model.addAttribute(),像前端页⾯传送从数据库读取的数据,并且返回⼀个字符串"login/test"。
7. 返回的字符串"login/test"在l的配置视图解析器(ViewResolver)中,加上前缀"/WEB-INF/views/",加上后缀".jsp",即组成了⼀个完整的⽹页地址,浏览器访
问的就是这个地址,即"/WEB-INF/views/login/test.jsp"。
8. 前端⽹页test.jsp通过${msg}来获取后端发来的数据。
完整代码放在最后⾯,先⼤概讲⼀下每⼀步的逻辑思路
第⼀步
<welcome-file-list>
<welcome-file>/WEB-INF/views/login/test.jsp</welcome-file>
</welcome-file-list>
<welcome-file-list>标签字⾯上看起来是欢迎⽂件列表的意思,实际上我猜是默认加载项⽬的⽹页的意思。配置好这个,使⽤Tomcat运⾏,就会⾸先加载这个界⾯。
第⼆步
<%@ page contentType="text/html;chart=UTF-8" language="java" %>
<%
String path = ContextPath();
String baPath = Scheme() + "://" + ServerName() + ":" + ServerPort() + path;
%>
<html>
<head>
<title></title>
</head>
<body>
<a href="<%=baPath%>/summary/test1.do">
<button>按钮</button>
</a>
<h2>${msg}</h2>
</body>
</html>
总之就是要获取到该项⽬的⽹络路径。
祈求平安接着,我们使⽤ href="<%=baPath%>/summary/test1.do" 指向这个地址。
第三步
<rvlet>
<rvlet-name>dispatcherServlet</rvlet-name>
<rvlet-class>org.springframework.web.rvlet.DispatcherServlet</rvlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:l</param-value>
</init-param>
</rvlet>
<rvlet-mapping>
<rvlet-name>dispatcherServlet</rvlet-name>
<url-pattern>*.do</url-pattern>
</rvlet-mapping>
DispatcherServlet就是传说中的拦截器,他能把第⼆步传来的 /summary/test1.do ,拦截下来,去掉后缀 .do,并且把他发送到配置⽂件spring.mvc。
第四步
<context:component-scan ba-package="ller"/>
第五、六步
package ller;
import org.springframework.web.bind.annotation.RequestMapping;
import ypc.zwz.rvice.ArticleService;
@Controller
@RequestMapping(value = "/summary")
public class ArticleController {
private ArticleService articleService;
@RequestMapping(value = "/test1")
public String te(@RequestParam(value = "pageCode", defaultValue = "1", required = fal) int pageCode, @RequestParam(value = "pageSize", defaultValue = "3", required = fal) int pageSize, HttpServletRequest request, Model model) { Summary summary = articleService.findById(23);
String str = R_content();
model.addAttribute("msg",str);
return "login/test";
}
}
在ller包的ArticleController类中,找到与之对应的⽅法t e();因为这个类@RequestMapping(value = "/summary"),类下的te⽅法@RequestMapping(value =
"/test1"),组合起来就是/summary/test1。所以执⾏这个⽅法。
先通过articleService.findById(23);即从Serive层读取数据库的信息(后⾯会给完整代码),再获取Summary类中的contnt属性,通过model.addAttribute("msg",str);⽅法发送⾄前
端页⾯,前端页⾯可以通过"msg"这个键来获取到str这个值,最后向spring.mvc返回"login/test"这个字符串。
第七步
<bean class="org.springframework.web.rvlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
正常读取打开,就正常打开。
第⼋步
代码见第⼆步,在第六步中已经说明,使⽤msg使⽤这个键来获取到str这个值,所以使⽤ ${msg} ,就获取到了后端传过来的str的值。
关于为什么要把原本的⽹址搞得这么花⾥胡哨,可能是为了保密吧,⽐如你知道主页的⽹页地址,那么你直接访问这个⽹址,就可以跳过登⼊了(可能是这样的吧,我猜的
登⼊地址XXXXX/views/login.jsp
主页地址XXXXX/views/index.jsp
那我们直接访问主页地址,就可以跳过登⼊了
相反现在:
登⼊地址XXXXX/views/login.jsp
我们需要访问XXXXXX.do这个后端⽅法,返回主页
但是浏览器的⽹页还是显⽰XXXXXX.do
我们不知道主页的真正地址
所以可能⼤概也许就起到保密的作⽤了。
议付完整代码
test.jsp 路径: WEB-INF/views/login/test.jsp
<%--
Created by IntelliJ IDEA.
Ur: zwz想念造句
Date: 2020/2/17 0016
Time: 7:39
To change this template u File | Settings | File Templates.
--%>
丁字开头的成语<%@ page contentType="text/html;chart=UTF-8" language="java" %>
<%
String path = ContextPath();
String baPath = Scheme() + "://" + ServerName() + ":" + ServerPort() + path;
%>
<html>
<head>
<title></title>
</head>
<body>
<a href="<%=baPath%>/summary/test1.do">
<button>按钮</button>
</a>
<h2>${msg}</h2>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="www.w3/2001/XMLSchema-instance"
xmlns="xmlns.jcp/xml/ns/javaee"
xsi:schemaLocation="xmlns.jcp/xml/ns/javaee
xmlns.jcp/xml/ns/javaee/web-app_3_1.xsd"
故事里的中国
version="3.1">
<welcome-file-list>
<welcome-file>/WEB-INF/views/login/test.jsp</welcome-file>
</welcome-file-list>
<!--配置spring的字符编码过滤器 -->
<filter>
<filter-name>CharacterEncoding</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>CharacterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
word公式<!-- 加载spring的过滤器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-*.xml</param-value>
</context-param>
<listener><!-- 启动web容器时,⾃动装配l-->
<listener-class>org.t.ContextLoaderListener</listener-class>
</listener>
<!-- spring 结尾-->
<!--配置springmvc的核⼼过滤器 -->
<rvlet>
<rvlet-name>dispatcherServlet</rvlet-name>
<rvlet-class>org.springframework.web.rvlet.DispatcherServlet</rvlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:l</param-value>
<!-- 容器启动⾃动加载l -->
</init-param>
</rvlet>
<rvlet-mapping>
<rvlet-name>dispatcherServlet</rvlet-name>
<url-pattern>*.do</url-pattern>
</rvlet-mapping>
</web-app>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="www.springframework/schema/beans"
xmlns:xsi="www.w3/2001/XMLSchema-instance"
xmlns:aop="www.springframework/schema/aop"
xmlns:tx="www.springframework/schema/tx"
xmlns:mvc="www.springframework/schema/mvc"
xmlns:context="www.springframework/schema/context"
xsi:schemaLocation="www.springframework/schema/beans
www.springframework/schema/beans/spring-beans.xsd
www.springframework/schema/aop
www.springframework/schema/aop/spring-aop.xsd
www.springframework/schema/context
www.springframework/schema/context/spring-context.xsd
www.springframework/schema/tx
www.springframework/schema/context/spring-tx.xsd
www.springframework/schema/mvc
www.springframework/schema/mvc/spring-mvc.xsd">
<!-- 开启注解扫描 -->
<context:component-scan ba-package="ller"/>
<!-- 配置springmvc的驱动,并开启了对JSON数据格式的⽀持 -->
<mvc:annotation-driven/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.rvlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="www.springframework/schema/beans"
xmlns:xsi="www.w3/2001/XMLSchema-instance"
xmlns:context="www.springframework/schema/context"
xsi:schemaLocation="www.springframework/schema/beans
www.springframework/schema/beans/spring-beans.xsd
www.springframework/schema/context
www.springframework/schema/context/spring-context.xsd">
<!-- 配置注解扫描 -->
<context:component-scan ba-package="ypc.zwz.rvice"/>
<!-- 加载数据库配置⽂件 -->
<context:property-placeholder location="classpath:resource/jdbc.properties"/>
<!-- 数据库连接池 -->
<bean id="dataSource" class="hange.v2.c3p0.ComboPooledDataSource">
<!-- 配置数据库连接池属性 -->
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
不懈的努力<property name="ur" value="${jdbc.urname}"/>
<property name="password" value="${jdbc.password}"/>
<!-- c3p0连接池私有属性 -->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!-- 关闭连接后不⾃动commit -->
<property name="autoCommitOnClo" value="fal"/>
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="10000"/>
<!-- 当获取连接失败后重新连接的次数 -->
<property name="acquireRetryAttempts" value="2" />
</bean>
<!-- 配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="batis.spring.SqlSessionFactoryBean">
<!-- 注⼊数据库连接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 启⽤mybatis的别名配置 -->
<property name="typeAliasPackage" value="ypc.zwz.pojo"/>
<!-- 扫描Mapper层的配置⽂件 -->
<property name="mapperLocations" value="classpath:ypc/zwz/mapper/*.xml"/>
</bean>
<!-- 启⽤mybatis的接⼝代理开发模式(接⼝和Xml配置必须同名,并且在同⼀⽬录下) -->
<bean class="batis.spring.mapper.MapperScannerConfigurer">
<property name="baPackage" value="ypc.zwz.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
ArticleController.java 路径:src/main/java/cn/ypc/controller/ArticleController.java
package ller;
import ypc.zwz.pojo.Summary;
import ypc.zwz.rvice.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.rvlet.http.HttpServletRequest;
import java.util.HashMap;苹果桌面
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping(value = "/summary")
public class ArticleController {
private ArticleService articleService;
@RequestMapping(value = "/test1")
public String te(@RequestParam(value = "pageCode", defaultValue = "1", required = fal) int pageCode,@RequestParam(value = "pageSize", defaultValue = "3", required = fal) int pageSize,HttpServletRequest request,Model model) { Summary summary = articleService.findById(23);
String str = R_content();
model.addAttribute("msg",str);
return "login/test";
}
}
其余代码和我之前做的周总结云盘代码⼀致,开源,