在pom.xml
文件中增加依赖
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.11.0version>
dependency>
从依赖关系可得,spring-webmvc
jar包中存在Spring的很多依赖,注意不要重复导入依赖
web.xml
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
filter>
<filter>
<filter-name>hiddenHttpMethodFilterfilter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilterfilter-class>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<filter-mapping>
<filter-name>hiddenHttpMethodFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springMVC.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
springMVC.xml
配置文件<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.young" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
beans>
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("test")
public AjaxData test(){
System.out.println("测试成功");
AjaxData ajaxData = new AjaxData();
ajaxData.setDatas("测试成功");
return ajaxData;
}
}
AjaxData类作为返回json数据的封装类
public class AjaxData {
private boolean success=true; //默认为true,可以不用每次都使用set方法设置
private Object datas;
private Object msg; //错误原因可能很多,可能返回一个存储错误原因的集合
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Object getDatas() {
return datas;
}
public void setDatas(Object datas) {
this.datas = datas;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
一个配置文件中完成以上操作,内容比较多,不容易管理,所以我们分别编写几个文件,做不同的事情。
web.xml
(***)
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext*.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
applicationContext.xml
配置文件注意父子容器问题,避免重复扫描
<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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.young">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
beans>
IUserService
接口
public interface IUserService {
//测试方法
void test();
}
UserService
实现类
@Service
public class UserService implements IUserService {
public void test(){
System.out.println("UserServiceImpl test method invoke");
}
}
UserController
控制器
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private IUserService userService;
@GetMapping("test")
public AjaxData test(){
System.out.println("测试成功");
userService.test();
AjaxData ajaxData = new AjaxData();
ajaxData.setDatas("测试成功");
return ajaxData;
}
}
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.5version>
dependency>
applicationContext-aop.xml
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<aop:aspectj-autoproxy/>
beans>
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//将该类交给Spring容器
@Component
//声明该类为切面类
@Aspect
public class LogAspect {
@Pointcut("execution(* com.young..*.*(..))")
public void logPointCut(){}
@Around(value = "logPointCut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around start");
long stime=System.currentTimeMillis();
Object result = pjp.proceed(pjp.getArgs());
long etime=System.currentTimeMillis();
String cname = pjp.getTarget().getClass().getName();
String mname = pjp.getSignature().getName();
String logMsg = String.format("%s类%s方法执行时间为%s", cname, mname, (etime - stime));
System.out.println(logMsg);
return result;
}
}
运行程序,控制台输出日志信息。
在进行SSM整合时,出现了切面类无法运行的问题,问题如下:
配置文件内容
springMVC.xml
配置文件
<context:component-scan base-package="com.young">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
applicationContext.xml
配置文件
<context:component-scan base-package="com.young" >
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
applicationContext-aop.xml
配置文件
<aop:aspectj-autoproxy/>
原因
在springMVC.xml
配置文件开启扫描时需要配置属性:use-default-filters="false"
,不使用默认的Filter进行扫描
<context:component-scan base-package="com.young" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
SpringMVC是Spring的子容器,如果在不配置use-default-filters="false"
,那么子容器会扫描@Component
、@Service
、@Reposity
、@Controller
这四个注解标注的Bean,使Spring容器(父容器)无法扫描到@Component
、@Service
、@Reposity
注解标注的类,如果Bean不交给Spring容器是无法应用切面类的。
可以将
配置放入springMVC.xml
配置文件中,此时切面类起作用。
当在springMVC.xml
配置文件中配置use-default-filters="false"
,就不会使用默认的Filter进行扫描,在
标签中配置只扫描@Controller
注解标注的控制器。
避免方法
可以在测试时,为service层中的类提供一个构造方法
public UserService(){
System.out.println("UserService run...");
}
如果SpringMVC容器会扫描service层中的类,那么控制台会输出两次以上输出语句,这就代表着父子容器重复扫描。这是一个很好的习惯!
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.18version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.10version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.6version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.4version>
dependency>
applicationContext-mybatis.xml
配置文件
<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 https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="druidDataSource" init-method="init" destroy-method="close" class="com.alibaba.druid.pool.DruidDataSource">
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
<property name="url" value="${db.url}"/>
<property name="driverClassName" value="${db.driverClassName}"/>
bean>
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="druidDataSource"/>
<property name="typeAliasesPackage" value="com.young.model"/>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.young.mapper"/>
bean>
beans>
db.properties
配置文件db.url=jdbc:mysql://localhost:3306/mybatis_db?serverTimezone=UTC
db.username=root
db.password=123
db.driverClassName=com.mysql.jdbc.Driver
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
resources>
使用插件一键生成实体类、Mapper接口以及Mapper映射文件
在Mapper接口中提供selectAll()
方法查询所有数据,并在映射文件中提供相应的标签
在Service层中注入UserMapper类对象,并调用selectAll()
方法,将数据返回给Controller,Controller中调用Service层中的方法,将数据返回给前端。
applicationContext-tx.xml
配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="druidDataSource"/>
bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="*"/>
tx:attributes>
tx:advice>
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.young..*.*(..))"/>
aop:config>
beans>
<dependency>
<groupId>org.mybatis.cachesgroupId>
<artifactId>mybatis-memcachedartifactId>
<version>1.0.0version>
dependency>
memcached.properties
#any string identifier
org.mybatis.caches.memcached.keyprefix=_biz-cache-wk_
#space separated list of ${host}:${port}
org.mybatis.caches.memcached.servers=127.0.0.1:11211
#org.mybatis.caches.memcached.servers=192.168.0.44:12000
#Any class that implementsnet.spy.memcached.ConnectionFactory
org.mybatis.caches.memcached.connectionfactory=net.spy.memcached.DefaultConnectionFactory
#the number of seconds in 30 days the expiration time (in seconds)
org.mybatis.caches.memcached.expiration=6000
#flag to enable/disable the async get
org.mybatis.caches.memcached.asyncget=false
#the timeout when using async get
org.mybatis.caches.memcached.timeout=5
#the timeout unit when using async get
org.mybatis.caches.memcached.timeoutunit=java.util.concurrent.TimeUnit.SECONDS
#if true, objects will be GZIP compressed before putting them to
org.mybatis.caches.memcached.compression=false
#\u7f13\u5b58\u670d\u52a1\u5668\u5b95\u673a\u540e\u591a\u4e45\u4e0d\u4f7f\u7528memcached \u6beb\u79d2\u4e3a\u5355\u4f4d
#refuse time when connection refused
org.mybatis.caches.memcached.refuseperiod=1000
UserMapper.xml
映射文件中应用缓存<cache type="org.mybatis.caches.memcached.MemcachedCache"/>
mybatis-config
配置文件
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
settings>
configuration>
需要在applicationContext-mybatis.xml
配置文件中加载mybatis-config
配置文件
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.1.11version>
dependency>
mybatis-config
配置文件中配置插件<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">plugin>
plugins>
UserService
类中selectAll()
方法
@Override
public PageInfo<User> selectAll(Integer pageNum, Integer pageSize) {
//如果页码和页面大小为空,那么指定大小
if (pageNum==null){
pageNum=1;
}
if (pageSize==null){
pageSize=5;
}
PageHelper.startPage(pageNum,pageSize);
List<User> list = userMapper.selectAll();
PageInfo<User> userPageInfo = new PageInfo<>(list);
return userPageInfo;
}
UserController
类中selectAll()
方法
//提供两种映射路径,支持全查和分页查询
@GetMapping(value = {"selectAll/{pageNum}/{pageSize}","selectAll"})
//设置required = false,使参数不是必须的
public AjaxData selectAll(@PathVariable(value = "pageNum",required = false) Integer pageNum,
@PathVariable(value = "pageSize",required = false) Integer pageSize){
PageInfo<User> userPageInfo = userService.selectAll(pageNum, pageSize);
AjaxData ajaxData = new AjaxData();
ajaxData.setDatas(userPageInfo);
return ajaxData;
}
运行memcached.exe,准备测试二级缓存
运行程序,输入不同的映射路径,测试全查和分页查询
修改数据库中的数据,再次查询,发现返回结果没有发生改变,则缓存起作用
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
Console>
Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
Root>
Loggers>
Configuration>
mybatis-config.xml
文件中增加设置
<setting name="logImpl" value="LOG4J"/>
<dependency>
<groupId>org.hibernate.validatorgroupId>
<artifactId>hibernate-validatorartifactId>
<version>6.1.2.Finalversion>
dependency>
@NotNull(message = "请传递参数username",groups = {insertValidated.class, updateValidated.class})
@NotBlank(message = "请输入参数username",groups = {insertValidated.class, updateValidated.class})
private String username;
@NotNull(message = "请传递参数password",groups = {insertValidated.class, updateValidated.class})
@NotBlank(message = "请输入参数password",groups = {insertValidated.class, updateValidated.class})
@Length(min = 8,max = 16,message = "密码长度为8到16位",groups = {insertValidated.class})
private String password;
@PostMapping("user/{username}/{password}")
public AjaxData insert(@Validated(value = {insertValidated.class}) User user, BindingResult errors){
AjaxData ajaxData = new AjaxData();
if (errors.hasErrors()){
HashMap<String, String> map = new HashMap<>();
List<FieldError> fieldErrors = errors.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
String fname = fieldError.getField();
String msg = fieldError.getDefaultMessage();
map.put(fname,msg);
}
ajaxData.setSuccess(false);
ajaxData.setDatas(map);
return ajaxData;
}
ajaxData.setDatas("添加成功");
return ajaxData;
}
@PutMapping("user/{username}/{password}")
public AjaxData update(@Validated(value = {updateValidated.class}) User user, BindingResult errors){
AjaxData ajaxData = new AjaxData();
if (errors.hasErrors()){
HashMap<String, String> map = new HashMap<>();
List<FieldError> fieldErrors = errors.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
String fname = fieldError.getField();
String msg = fieldError.getDefaultMessage();
map.put(fname,msg);
}
ajaxData.setSuccess(false);
ajaxData.setMsg(map);
return ajaxData;
}
ajaxData.setDatas("更新成功");
return ajaxData;
}
将控制器改为restful风格
//一个控制器中的映射路径相同,根据参数和请求方式的不同来对应不同的方法
@RequestMapping("api")
在控制器的方法中,都需要进行异常处理,存在大量的代码冗余
import com.young.util.AjaxData;
import org.apache.log4j.Logger;
//注意BindException的包
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.List;
//标注该类为异常处理类
@ControllerAdvice
public class SpringMVCExecption {
private Logger logger=Logger.getLogger(SpringMVCExecption.class);
@ExceptionHandler(BindException.class)
//使其返回json字符串
@ResponseBody
public AjaxData handlerBindExecpion(BindException e){
AjaxData ajaxData = new AjaxData();
ajaxData.setSuccess(false);
BindingResult errors = e.getBindingResult();
HashMap<String, String> map = new HashMap<>();
List<FieldError> fieldErrors = errors.getFieldErrors();
for (FieldError fieldError : fieldErrors) {
String fname = fieldError.getField();
String msg = fieldError.getDefaultMessage();
map.put(fname,msg);
logger.error(fname+":"+msg);
}
ajaxData.setSuccess(false);
ajaxData.setMsg(map);
return ajaxData;
}
@ExceptionHandler(Exception.class)
@ResponseBody
public AjaxData handlerExecpion(Exception e){
AjaxData ajaxData = new AjaxData();
ajaxData.setSuccess(false);
ajaxData.setMsg("服务器繁忙,请稍后再试");
//将错误信息用日志记录,便于发现问题
logger.error(e.getMessage());
e.printStackTrace();
return ajaxData;
}
}
import com.github.pagehelper.PageInfo;
import com.young.model.validated.insertValidated;
import com.young.model.validated.updateValidated;
import com.young.model.User;
import com.young.service.IUserService;
import com.young.util.AjaxData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("api")
public class UserController {
@Autowired
private IUserService userService;
@DeleteMapping("user/{id}")
public AjaxData delete(@PathVariable ("id")Integer id){
userService.delete(id);
AjaxData ajaxData = new AjaxData();
ajaxData.setMsg("删除成功");
return ajaxData;
}
@GetMapping(value = {"user/{pageNum}/{pageSize}","user"})
public AjaxData selectAll(@PathVariable(value = "pageNum",required = false) Integer pageNum,
@PathVariable(value = "pageSize",required = false) Integer pageSize){
PageInfo<User> userPageInfo = userService.selectAll(pageNum, pageSize);
AjaxData ajaxData = new AjaxData();
ajaxData.setDatas(userPageInfo);
return ajaxData;
}
@PostMapping("user/{username}/{password}")
public AjaxData insert(@Validated(value = {insertValidated.class}) User user, BindingResult errors) throws BindException {
AjaxData ajaxData = new AjaxData();
if (errors.hasErrors()){
//此处抛出BindException以便于异常处理器接收
throw new BindException(errors);
}
ajaxData.setDatas("添加成功");
return ajaxData;
}
@PutMapping("user/{username}/{password}")
public AjaxData update(@Validated(value = {updateValidated.class}) User user, BindingResult errors) throws BindException {
AjaxData ajaxData = new AjaxData();
if (errors.hasErrors()){
throw new BindException(errors);
}
ajaxData.setDatas("更新成功");
return ajaxData;
}
}
SpringMVC中的拦截器用于拦截controller方法的,可以记录日志
在创建拦截器时需要使用到javax.servlet
包下的类及方法
<dependency>
<groupId>javax.servletgroupId>
<artifactId>javax.servlet-apiartifactId>
<version>4.0.1version>
<scope>providedscope>
dependency>
import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SpringMVCLogInterceptor implements HandlerInterceptor {
private Logger logger=Logger.getLogger(SpringMVCLogInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
long stime=System.currentTimeMillis();
request.setAttribute("stime",stime);
//return true表示继续执行,将请求发送到Controller层
//如果return false,那么请求就会被拦截无法到达Controller层
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
long etime = System.currentTimeMillis();
long stime = Long.parseLong(request.getAttribute("stime").toString());
long time=etime-stime;
StringBuffer requestURL = request.getRequestURL();
String msg =String.format("%s资源,处理时间%s毫秒",requestURL,time);
logger.debug(msg);
}
}
springMVC.xml
中配置拦截器<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.young.springmvc.interceptor.SpringMVCLogInterceptor"/>
mvc:interceptor>
mvc:interceptors>
UserController
类
import com.github.pagehelper.PageInfo;
import com.young.model.validated.insertValidated;
import com.young.model.validated.updateValidated;
import com.young.model.User;
import com.young.service.IUserService;
import com.young.util.AjaxData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("api")
public class UserController {
@Autowired
private IUserService userService;
//根据id删除用户
@DeleteMapping("user/{id}")
public AjaxData delete(@PathVariable ("id")Integer id){
userService.deleteByPrimaryKey(id);
AjaxData ajaxData = new AjaxData();
ajaxData.setMsg("删除成功");
return ajaxData;
}
@GetMapping(value = {"user/{pageNum}/{pageSize}","user"})
public AjaxData selectAll(@PathVariable(value = "pageNum",required = false) Integer pageNum,
@PathVariable(value = "pageSize",required = false) Integer pageSize){
PageInfo<User> userPageInfo = userService.selectAll(pageNum, pageSize);
AjaxData ajaxData = new AjaxData();
ajaxData.setDatas(userPageInfo);
return ajaxData;
}
@GetMapping(value = "user/{id}")
public AjaxData selectById(@PathVariable("id") Integer id){
User user = userService.selectByPrimaryKey(id);
AjaxData ajaxData = new AjaxData();
ajaxData.setDatas(user);
return ajaxData;
}
@PostMapping(value = "user/{username}/{password}")
public AjaxData insert(@Validated(value = {insertValidated.class}) User user, BindingResult errors) throws BindException {
AjaxData ajaxData = new AjaxData();
if (errors.hasErrors()){
throw new BindException(errors);
}
userService.insertSelective(user);
ajaxData.setDatas("添加成功");
return ajaxData;
}
@PutMapping("user/{id}/{username}/{password}")
public AjaxData update(@Validated(value = {updateValidated.class}) User user, BindingResult errors) throws BindException {
AjaxData ajaxData = new AjaxData();
if (errors.hasErrors()){
throw new BindException(errors);
}
userService.updateByPrimaryKeySelective(user);
ajaxData.setDatas("更新成功");
return ajaxData;
}
}
注意:update方法需要传入主键id,否则无法更新
IUserService
接口
import com.github.pagehelper.PageInfo;
import com.young.model.User;
public interface IUserService {
PageInfo<User> selectAll(Integer PageNum, Integer PageSize);
void deleteByPrimaryKey(Integer id);
void insertSelective(User record);
User selectByPrimaryKey(Integer id);
void updateByPrimaryKeySelective(User record);
}
UserService
类
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.young.mapper.UserMapper;
import com.young.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService implements IUserService {
@Autowired
private UserMapper userMapper;
public UserService(){
System.out.println("UserService run...");
}
@Override
public PageInfo<User> selectAll(Integer pageNum, Integer pageSize) {
if (pageNum==null){
pageNum=1;
}
if (pageSize==null){
pageSize=5;
}
PageHelper.startPage(pageNum,pageSize);
List<User> list = userMapper.selectAll();
PageInfo<User> userPageInfo = new PageInfo<>(list);
return userPageInfo;
}
@Override
public void deleteByPrimaryKey(Integer id) {
int i = userMapper.deleteByPrimaryKey(id);
if (i==0){
throw new RuntimeException("id为"+id+"的用户不存在");
}
}
@Override
public void insertSelective(User record) {
int i = userMapper.insertSelective(record);
if (i==0){
throw new RuntimeException("id为"+record.getId()+"的用户不存在");
}
}
@Override
public User selectByPrimaryKey(Integer id) {
User user = userMapper.selectByPrimaryKey(id);
if (user==null){
throw new RuntimeException("id为"+id+"的用户不存在");
}
return user;
}
@Override
public void updateByPrimaryKeySelective(User record) {
int i = userMapper.updateByPrimaryKeySelective(record);
if (i==0){
throw new RuntimeException("id为"+record.getId()+"的用户不存在");
}
}
}
在某次运行过程中出现如下错误,即找不到springMVC.xml
配置文件
IOException parsing XML document from class path resource [applicationContext.xml];nested exception is java.io.FileNotFoundException: class path resource [springMVC.xml] cannot be opened because it does not exist
首先可以确定该文件在resource目录下一定存在,我们可以先去排查web.xml
文件下是否配置
标签,如下:
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springMVC.xmlparam-value>
init-param>
如果存在标签,或者之前可以运行突然出现该问题,我们应该检查target/classes目录下是否存在配置文件,如下图所示:
如果不存在说明maven打包出现了问题,可以尝试重新打包,如果不能解决,则需要在pom.xml
文件中进行如下配置,目的是为了打包src/main/resources目录下的所有文件
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
includes>
resource>
resources>
如果对于之前的文件再次删除,但是日志显示该文件还存在,而且影响着程序的正常运行,也可以重新打包解决。
使用swagger2生成文档,swagger2也可以用于测试
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.9.2version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.9.2version>
dependency>
@Component
@Configuration
@EnableSwagger2
@EnableWebMvc
@ComponentScan("com.oracle.controller")
public class SwaggerConfig {
@Bean
public Docket createAPI() {
return new Docket(DocumentationType.SWAGGER_2).forCodeGeneration(true).select().apis(RequestHandlerSelectors.any())
//过滤生成链接
.paths(PathSelectors.any()).build().apiInfo(apiInfo());
}
private ApiInfo apiInfo() {
Contact contact = new Contact("xk", "http://www.oracle.com.cn", "[email protected]");
ApiInfo apiInfo = new ApiInfoBuilder().license("Apache License Version 2.0").title("SSM整合接口文档").description("Swagger API Teste").contact(contact).version("1.0").build();
return apiInfo;
}
}
在地址栏后输入swagger-ui.html即可进入文档在文档中可以查看控制器以及方法,也可以对方法进行测试。
可以使用swagger提供的注解使文档的信息更加详细
@Api(description = "用户信息控制器")
public class UserController {
@ApiOperation(value ="根据id查询用户信息")
@GetMapping(value = "user/{id}")
public AjaxData selectById(@PathVariable("id") Integer id){
@ApiModel("用户实体类")
public class User implements Serializable {
@ApiModelProperty(name = "用户编号")
private Integer id;