bul*_*ous 3 java lambda spring spring-boot
我正在https://spring.io/ Spring Boot 上进行一些练习.
做示例https://spring.io/guides/gs/uploading-files/,当我使用Java 8时它工作正常,但遗憾的是我在Web服务中包装的代码需要Java 7.我列出了所有的错误代码,有人可以帮助我将lambda转换为1.7兼容代码并替换新库(java.util.stream.Stream和java.util.stream.Collectors).
Application.java
@SpringBootApplication
@EnableConfigurationProperties(StorageProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
CommandLineRunner init(StorageService storageService) {
return (args) -> {
storageService.deleteAll();
storageService.init();
};
}
}
Run Code Online (Sandbox Code Playgroud)
return(args) - >错误说"使用source -8或更高版本来启用lambda表达式"
FileUploadController.java
import java.util.stream.Collectors
//..
@GetMapping("/")
public String listUploadedFiles(Model model) throws IOException {
model.addAttribute("files", storageService
.loadAll()
.map(path ->
MvcUriComponentsBuilder
.fromMethodName(FileUploadController.class, "serveFile", path.getFileName().toString())
.build().toString())
.collect(Collectors.toList()));
return "uploadForm";
}
Run Code Online (Sandbox Code Playgroud)
包java.util.stream不存在
type loadAll()是错误的
错误说"使用source -8或更高版本来启用lambda表达式"
FileSystemStorageService.java
@Override
public Stream<Path> loadAll() {
try {
return Files.walk(this.rootLocation, 1)
.filter(path -> !path.equals(this.rootLocation))
.map(path -> this.rootLocation.relativize(path));
} catch (IOException e) {
throw new StorageException("Failed to read stored files", e);
}
}
Run Code Online (Sandbox Code Playgroud)
找不到符号走路
错误说"使用source -8或更高版本来启用lambda表达式"
StorageService.java
import java.util.stream.Stream;
public interface StorageService {
void init();
void store(MultipartFile file);
Stream<Path> loadAll();
Path load(String filename);
Resource loadAsResource(String filename);
void deleteAll();
}
Run Code Online (Sandbox Code Playgroud)
包java.util.stream不存在
斗牛,我很抱歉你的赏金,但你真的只有很少的选择.Stream API仅在Java 8中添加,因此在Java 7中不存在.您可以通过手动编写匿名类甚至几乎自动来解决与lambda相关的问题(请参阅Retrolambda).但是使用Stream API,您只有两个选择:
更新(替换Files.walk)
如果您Files.walk是唯一使用Java-8特定API的地方,则可以相对轻松地将其替换为Java 7 API:
interface PathNameMapper
{
String mapPath(Path path);
}
List<String> loadAll(PathNameMapper mapper)
{
try
{
List<String> result = new ArrayList<>();
Files.walkFileTree(rootLocation, EnumSet.noneOf(FileVisitOption.class), 1, new SimpleFileVisitor<Path>()
{
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
{
if (!rootLocation.equals(file))
{
result.add(mapper.mapPath(rootLocation.relativize(file)));
}
return FileVisitResult.CONTINUE;
}
});
return result;
}
catch (IOException e)
{
throw new StorageException("Failed to read stored files", e);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你listUploadedFiles会变得像
@GetMapping ("/")
public String listUploadedFiles(Model model) throws IOException
{
model.addAttribute("files", storageService
.loadAll(new PathNameMapper()
{
@Override
public String mapPath(Path path)
{
return MvcUriComponentsBuilder
.fromMethodName(FileUploadController.class, "serveFile", path.getFileName().toString())
.build().toString();
}
}));
return "uploadForm";
}
Run Code Online (Sandbox Code Playgroud)
更新2(labmda - >匿名类转换)
仅仅为了完整性,一个如何手动将lambda转换为匿名类的示例:
@Bean
CommandLineRunner init(StorageService storageService)
{
return new CommandLineRunner()
{
@Override
public void run(String... args) throws Exception
{
storageService.deleteAll();
storageService.init();
}
};
}
Run Code Online (Sandbox Code Playgroud)
您可以将以下方法更新为Java 7变体.所有的测试用例都在通过.
Application.java
@SpringBootApplication
@EnableConfigurationProperties(StorageProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
CommandLineRunner init(StorageService storageService) {
return new CommandLineRunner() {
@Override
public void run(String... args) throws Exception {
storageService.deleteAll();
storageService.init();
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
FileUploadController.java
@GetMapping("/")
public String listUploadedFiles(Model model) throws IOException {
List<Path> paths = storageService.loadAll();
List<String> sPaths = new ArrayList<>(paths.size());
for (Path path : paths) {
sPaths.add(MvcUriComponentsBuilder
.fromMethodName(FileUploadController.class, "serveFile", path.getFileName().toString())
.build().toString());
}
model.addAttribute("files", sPaths);
return "uploadForm";
}
Run Code Online (Sandbox Code Playgroud)
更新了DirectoryStream用于简单列出所有文件的方法实现.
FileSystemStorageService.java
@Override
public List<Path> loadAll() {
List<Path> rPaths = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(this.rootLocation)) {
for (Path entry: stream) {
rPaths.add(rootLocation.relativize(entry));
}
} catch (IOException e) {
throw new StorageException("Failed to read stored files", e);
}
return rPaths;
}
Run Code Online (Sandbox Code Playgroud)
StorageService.java
public interface StorageService {
void init();
void store(MultipartFile file);
List<Path> loadAll();
Path load(String filename);
Resource loadAsResource(String filename);
void deleteAll();
}
Run Code Online (Sandbox Code Playgroud)
FileUploadTests
@Test
public void shouldListAllFiles() throws Exception {
given(this.storageService.loadAll())
.willReturn(Arrays.asList(Paths.get("first.txt"), Paths.get("second.txt")));
this.mvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(model().attribute("files",
Matchers.contains("http://localhost/files/first.txt", "http://localhost/files/second.txt")));
}
Run Code Online (Sandbox Code Playgroud)
FileSystemStorageServiceTest
@RunWith(SpringRunner.class)
@SpringBootTest
public class FileSystemStorageServiceTest {
@Autowired
private StorageService storageService;
@Test
public void loadAll() throws Exception {
MockMultipartFile multipartFile =
new MockMultipartFile("file", "test.txt", "text/plain", "Spring Framework".getBytes());
storageService.store(multipartFile);
List<Path> paths = storageService.loadAll();
assertThat(paths.size()).isEqualTo(1);
}
}
Run Code Online (Sandbox Code Playgroud)
更新TestCompare与rootLocation设置为FileSystems.getDefault().getPath(".")
@RunWith(SpringRunner.class)
public class TestCompare {
@Configuration
@ComponentScan(basePackages = {"hello.storage"})
@EnableConfigurationProperties(StorageProperties.class)
static class ContextConfiguration{}
@Autowired
private StorageService storageService;
@Test
public void loadAllDirectoryStreamVsloadAllWalkFileWithDepth1() throws Exception {
List<Path> paths1 = storageService.loadAllDirectoryStream();
List<Path> paths2 = storageService.loadAllWalkFileWithDepth1();
assertThat(paths1.size()).isEqualTo(paths2.size());
}
}
Run Code Online (Sandbox Code Playgroud)
我添加了两种方法仅用于测试目的.一个使用DirectoryStream和使用其他 WalkFileTree具有maxDepth为1组他们两人的工作原理相同.
@Override
public List<Path> loadAllDirectoryStream() {
List<Path> rPaths = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(this.rootLocation)) {
for (Path entry: stream) {
//if(!Files.isDirectory(entry))
rPaths.add(rootLocation.relativize(entry));
}
} catch (IOException e) {
throw new StorageException("Failed to read stored files", e);
}
return rPaths;
}
@Override
public List<Path> loadAllWalkFileWithDepth1() {
List<Path> rPaths = new ArrayList<>();
try {
Files.walkFileTree(rootLocation, EnumSet.noneOf(FileVisitOption.class), 1, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (!rootLocation.equals(file)) {
rPaths.add(rootLocation.relativize(file));
}
return FileVisitResult.CONTINUE;
}
});
return rPaths;
} catch (IOException e) {
throw new StorageException("Failed to read stored files", e);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
767 次 |
| 最近记录: |