添加图片异常
package com.imooc.o2o.service.impl;
import com.imooc.o2o.dao.ShopDao;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.enums.ShopStateEnum;
import com.imooc.o2o.exceptions.ShopOperationException;
import com.imooc.o2o.service.ShopService;
import com.imooc.o2o.util.ImageUtil;
import com.imooc.o2o.util.PathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.Date;
@Service
public class ShopServiceImpl implements ShopService {
@Autowired
private ShopDao shopDao;
//添加店铺
@Override
public ShopExecution addShop(Shop shop, File shopImg) {
if(shop==null){
return new ShopExecution(ShopStateEnum.NULL_SHOP);
}
try{
//设置店铺信息
shop.setEnableStatus(0);
shop.setCreateTime(new Date());
shop.setLastEditTime(new Date());
int effectNum=shopDao.insertShop(shop);
if(effectNum<=0){
throw new ShopOperationException("店铺添加失败");
}else{
if(shopImg!=null){
//存储图片
try{
addShopImg(shop,shopImg);
}catch (Exception e){
throw new RuntimeException("shopImg error:"+e.getMessage());
}
//更新图片信息---因为在添加店铺的时候没有店铺的图片信息
effectNum=shopDao.updateShop(shop);
if(effectNum<=0){
throw new ShopOperationException("店铺更新失败");
}
}
}
}catch (Exception e){
throw new ShopOperationException("addShop error:"+e.getMessage());
}
return new ShopExecution(ShopStateEnum.CHECK,shop);
}
private void addShopImg(Shop shop, File shopImg) {
//获取相对值路径
String desk= PathUtil.getShopImagePath(shop.getShopId());
//获取绝对路径
String shopImgAddr=ImageUtil.generateThumbnail(shopImg,desk);
//设置图片路径
shop.setShopImg(shopImgAddr);
}
}package com.imooc.o2o.service;
import com.imooc.o2o.BaseTest;
import com.imooc.o2o.dao.ShopDao;
import com.imooc.o2o.dto.ShopExecution;
import com.imooc.o2o.entity.Area;
import com.imooc.o2o.entity.PersonInfo;
import com.imooc.o2o.entity.Shop;
import com.imooc.o2o.entity.ShopCategory;
import com.imooc.o2o.enums.ShopStateEnum;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
import java.util.Date;
import static org.junit.Assert.assertEquals;
public class ShopServiceTest extends BaseTest {
@Autowired
private ShopService shopService;
@Test
public void testInsertShop(){
Area area=new Area();
PersonInfo owner=new PersonInfo();
ShopCategory shopCategory=new ShopCategory();
area.setAreaId(2);
owner.setUserId(1l);
shopCategory.setShopCategoryId(10l);
Shop shop=new Shop();
shop.setOwner(owner);
shop.setShopCategory(shopCategory);
shop.setArea(area);
shop.setCreateTime(new Date());
shop.setLastEditTime(new Date());
shop.setAdvice("测试--非常好");
shop.setShopName("测试店铺2");
shop.setEnableStatus(ShopStateEnum.CHECK.getState());
shop.setPhone("3319358");
shop.setShopAddr("城南路");
shop.setPriority(1);
File file=new File("/Users/swabc/Desktop/images/xiaohuangren.jpg");
ShopExecution se=shopService.addShop(shop,file);
assertEquals(ShopStateEnum.CHECK.getState(),se.getState());
}
}这里我的Exception类在idea intellij中我不知道怎么序列化,他没报错我就直接写了
package com.imooc.o2o.exceptions;
public class ShopOperationException extends RuntimeException {
public ShopOperationException(String msg){
super(msg);
}
}报错内容
/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/bin/java -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=65294:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/junit/lib/junit5-rt.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/junit/lib/junit-rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_212.jdk/Contents/Home/lib/tools.jar:/Users/swabc/Desktop/javaWeb/o2o/target/test-classes:/Users/swabc/Desktop/javaWeb/o2o/target/classes:/Users/swabc/Desktop/one/junit/junit/4.12/junit-4.12.jar:/Users/swabc/Desktop/one/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/swabc/Desktop/one/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/Users/swabc/Desktop/one/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/Users/swabc/Desktop/one/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/Users/swabc/Desktop/one/org/springframework/spring-core/4.3.7.RELEASE/spring-core-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/Users/swabc/Desktop/one/org/springframework/spring-beans/4.3.7.RELEASE/spring-beans-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/org/springframework/spring-context/4.3.7.RELEASE/spring-context-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/org/springframework/spring-aop/4.3.7.RELEASE/spring-aop-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/org/springframework/spring-expression/4.3.7.RELEASE/spring-expression-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/org/springframework/spring-jdbc/4.3.7.RELEASE/spring-jdbc-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/org/springframework/spring-tx/4.3.7.RELEASE/spring-tx-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/org/springframework/spring-web/4.3.7.RELEASE/spring-web-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/org/springframework/spring-webmvc/4.3.7.RELEASE/spring-webmvc-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/org/springframework/spring-test/4.3.7.RELEASE/spring-test-4.3.7.RELEASE.jar:/Users/swabc/Desktop/one/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar:/Users/swabc/Desktop/one/com/fasterxml/jackson/core/jackson-databind/2.8.7/jackson-databind-2.8.7.jar:/Users/swabc/Desktop/one/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0.jar:/Users/swabc/Desktop/one/com/fasterxml/jackson/core/jackson-core/2.8.7/jackson-core-2.8.7.jar:/Users/swabc/Desktop/one/commons-collections/commons-collections/3.2/commons-collections-3.2.jar:/Users/swabc/Desktop/one/org/mybatis/mybatis/3.4.2/mybatis-3.4.2.jar:/Users/swabc/Desktop/one/org/mybatis/mybatis-spring/1.3.1/mybatis-spring-1.3.1.jar:/Users/swabc/Desktop/one/mysql/mysql-connector-java/8.0.16/mysql-connector-java-8.0.16.jar:/Users/swabc/Desktop/one/com/google/protobuf/protobuf-java/3.6.1/protobuf-java-3.6.1.jar:/Users/swabc/Desktop/one/c3p0/c3p0/0.9.1.2/c3p0-0.9.1.2.jar:/Users/swabc/Desktop/one/net/coobird/thumbnailator/0.4.8/thumbnailator-0.4.8.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.imooc.o2o.service.ShopServiceTest,testInsertShop
九月 10, 2020 4:48:33 下午 org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
信息: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
九月 10, 2020 4:48:33 下午 org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
信息: Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@4157f54e, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@90f6bfd, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@47f6473, org.springframework.test.context.support.DirtiesContextTestExecutionListener@15975490, org.springframework.test.context.transaction.TransactionalTestExecutionListener@6b143ee9, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@1936f0f5]
九月 10, 2020 4:48:33 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring/spring-dao.xml]
九月 10, 2020 4:48:33 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring/spring-service.xml]
九月 10, 2020 4:48:33 下午 org.springframework.context.support.GenericApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@39aeed2f: startup date [Thu Sep 10 16:48:33 CST 2020]; root of context hierarchy
九月 10, 2020 4:48:34 下午 com.mchange.v2.log.MLog <clinit>
信息: MLog clients using java 1.4+ standard logging.
九月 10, 2020 4:48:34 下午 com.mchange.v2.c3p0.C3P0Registry banner
信息: Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
九月 10, 2020 4:48:35 下午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 2, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 10000, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> z8kfltacx2odgp1r0hr2i|245b4bdc, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> z8kfltacx2odgp1r0hr2i|245b4bdc, idleConnectionTestPeriod -> 0, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/o2o?useUnicode=true&characterEncoding=utf8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 40, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 10, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
2020-09-10 16:48:36.692 [main] DEBUG com.imooc.o2o.dao.ShopDao.insertShop - ==> Preparing: insert into tb_shop(owner_id,area_id,shop_category_id,shop_name,shop_desc, shop_addr,phone,shop_img,priority,create_time,last_edit_time,enable_status,advice) values(?,?,?,?,?,?,?,?, ?,?,?,?,?)
2020-09-10 16:48:36.784 [main] DEBUG com.imooc.o2o.dao.ShopDao.insertShop - ==> Parameters: 1(Long), 2(Integer), 10(Long), 测试店铺2(String), null, 城南路(String), 3319358(String), null, 1(Integer), 2020-09-10 16:48:35.68(Timestamp), 2020-09-10 16:48:35.68(Timestamp), 0(Integer), 测试--非常好(String)
2020-09-10 16:48:36.798 [main] DEBUG com.imooc.o2o.dao.ShopDao.insertShop - <== Updates: 1
com.imooc.o2o.exceptions.ShopOperationException: addShop error:shopImg error:null
at com.imooc.o2o.service.impl.ShopServiceImpl.addShop(ShopServiceImpl.java:57)
at com.imooc.o2o.service.ShopServiceTest.testInsertShop(ShopServiceTest.java:46)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)40
收起
正在回答 回答被采纳积分+1
4回答
慕标0359786
2020-09-10 17:05:43
package com.imooc.o2o.util;
public class PathUtil {
/**
* getImgBasePath()方法:会根据不同的操作系统,返回不同的路径
* 而getShopImagePath(long shopId)方法是用来获取店铺图片的存储路径。而shopId是用来标识具体是哪一个店铺的图片。
*/
private static String seperator=System.getProperty("file.seperator");
//图片存放的位置----跟路径
public static String getImgBasePath(){
String os=System.getProperty("os.name");
String basePath="";
if(basePath.toLowerCase().startsWith("win")){
basePath="D:/project/image/";
}else{
basePath="/Users/swabc/Desktop/images/";
}
basePath=basePath.replace("/",seperator);
return basePath;
}
//相对路径,相对于getImgBasePath()的路径
public static String getShopImagePath(Long shopId){
String imagePath="/upload/item/shop/"+shopId+"/";
return imagePath.replace("/",seperator);
}
}package com.imooc.o2o.util;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
public class ImageUtil {
private static String basePath=Thread.currentThread().getContextClassLoader().getResource("").getPath();
private static final SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddHHmmss");
private static final Random r=new Random();
private static Logger logger= LoggerFactory.getLogger(ImageUtil.class);
//将CommonsMultipartFile转换成File
public static File transferCommonsMultipartFileToFile(CommonsMultipartFile cFile){
File newFile=new File(cFile.getOriginalFilename());
try {
cFile.transferTo(newFile);
}catch(IllegalStateException e){
logger.error(e.toString());
e.printStackTrace();
}
catch (IOException e) {
logger.error(e.toString());
e.printStackTrace();
}
return newFile;
}
//处理缩略图,并返回新生成图片的绝对值路径
public static String generateThumbnail(File thumbnail,String targetAddr){
String realFileName=getRandomFileName();
String extension=getFileExtension(thumbnail);
makeDirath(targetAddr);
String relativeAddr=targetAddr+realFileName+extension;
logger.debug("current relative addr:"+relativeAddr);
File desk=new File(PathUtil.getImgBasePath()+relativeAddr);
logger.debug("current complete addr:"+PathUtil.getImgBasePath()+relativeAddr);
try{
Thumbnails.of(thumbnail).size(200,200)
.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath+"/watermark.jpg")),0.25f)
.outputQuality(0.8f).toFile(desk);
}catch(IOException e){
logger.error(e.toString());
e.printStackTrace();
}
return relativeAddr;
}
///Users,swabc,Desktop,images这四个文件夹都会自动创建
private static void makeDirath(String targetAddr) {
String realFileParentPath=PathUtil.getImgBasePath()+targetAddr;
File dirPath=new File(realFileParentPath);
if(!dirPath.exists()){
dirPath.mkdirs();
}
}
private static String getFileExtension(File thumbnail) {
String originalFileName=thumbnail.getName();
return originalFileName.substring(originalFileName.lastIndexOf("."));
}
//生成随机文件名,当前年月日小时分钟秒+五位随机数
private static String getRandomFileName() {
int rannum=r.nextInt(89999)+10000;
String nowTimeStr=simpleDateFormat.format(new Date());
return nowTimeStr+rannum;
}
public static void main(String[] args) throws IOException {
String basePath=Thread.currentThread().getContextClassLoader().getResource("").getPath();
Thumbnails.of(new File("/Users/swabc/Desktop/images/xiaohuangren.jpg")).size(200,200)
.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(basePath+"/watermark.jpg")),0.25f)
.outputQuality(0.8f).toFile("/Users/swabc/Desktop/images/xiaohuangren_new.jpg");
}
}是不是我的图片处理的类有问题?
4. SSM到Spring Boot入门与综合实战
- 参与学习 人
- 提交作业 323 份
- 解答问题 8263 个
本阶段将带你学习主流框架SSM,以及SpringBoot ,打通成为Java工程师的最后一公里!
了解课程





恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星