Struts2注解配置Action、返回Json、上传图片转Base64
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。
Struts2的原理及特性介绍:Struts2百科
Struts2应用@Action注解写Action测试和图片转Base64显示
Struts2应用注解的同时与Spring结合会有依赖库版本冲突问题!
经测试
Spring-core 和 Spring-context 和 spring-beans 的 4.3.13.RELEASE 版本
与
Struts2-core 和 struts2-convention-plugin 的 2.5.16 版本
以及
Struts2-Spring-Plugin 2.5.18 版本
可以完美结合。
同时其它的依赖库还可以选择更高或者其它版本。
本测试使用的 gradle.build 配置。
configurations.all {
resolutionStrategy {
force 'org.springframework:spring-beans:4.3.1.RELEASE'
}
}
configurations.all {
resolutionStrategy {
force 'org.springframework:spring-core:4.3.1.RELEASE'
}
}
// 加入main/java目录下的*.hbm.xml打包 发布
sourceSets {
main {
resources {
//这里的srcDir是方法,上面的是属性
srcDir 'src/main/java' //可以将java目录下的所有非.java资源打包到classes下
}
}
}
// https://mvnrepository.com/artifact/org.springframework/spring-core
compile group: 'org.springframework', name: 'spring-core', version: '4.3.13.RELEASE'
// https://mvnrepository.com/artifact/org.springframework/spring-context
compile group: 'org.springframework', name: 'spring-context', version: '4.3.13.RELEASE'
// https://mvnrepository.com/artifact/org.springframework/spring-aop
compile group: 'org.springframework', name: 'spring-aop', version: '5.0.0.RELEASE'
// https://mvnrepository.com/artifact/org.apache.struts/struts2-convention-plugin
compile group: 'org.apache.struts', name: 'struts2-convention-plugin', version: '2.5.16'
// https://mvnrepository.com/artifact/org.apache.struts/struts2-core
compile group: 'org.apache.struts', name: 'struts2-core', version: '2.5.16'
// https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
compile group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.0'
// https://mvnrepository.com/artifact/org.apache.struts/struts2-spring-plugin
compile group: 'org.apache.struts', name: 'struts2-spring-plugin', version: '2.5.18'
// https://mvnrepository.com/artifact/org.springframework/spring-beans
compile group: 'org.springframework', name: 'spring-beans', version: '4.3.13.RELEASE'
// https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl
compile group: 'javax.servlet.jsp.jstl', name: 'jstl', version: '1.2'
web.xml里的struts过滤器spring-context web监听器还是要配置
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
结合Spring注解还是要在applicationContext.xml里开启一些配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<context:annotation-config></context:annotation-config>
<context:component-scan base-package="actions"></context:component-scan>
<context:component-scan base-package="Repositories"></context:component-scan>
<aop:aspectj-autoproxy proxy-target-class="true" />
</beans>
处理图片Action
开启struts2的action注解类的所在包的名字默认为 actions 。放在其它包中无法识别,对类名没有限定。
@Controller
public class IndexController extends ActionSupport {
private File pictureFile ;
private String pictureBase64;
public File getPictureFile() {
return pictureFile;
}
public void setPictureFile(File pictureFile) {
this.pictureFile = pictureFile;
}
public String getPictureBase64() {
return pictureBase64;
}
public void setPictureBase64(String pictureBase64) {
this.pictureBase64 = pictureBase64;
}
@Action(value="/pb",results = {@Result(name="success",location = "/Views/Test/Test.jsp")})
public String pb(){
return "success";
}
@Action(value="/ConvertPicture",results = {@Result(name="success",location = "/Views/Test/Test.jsp")})
public String convertToBase64() throws IOException {
if (this.pictureFile.exists()) {
String serverpath = "E:/Picture";
File uploadDir = new File(serverpath);
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
InputStream inputStream1 = new FileInputStream(this.pictureFile);
byte[] data = new byte[inputStream1.available()];
inputStream1.read(data);
BASE64Encoder base64Encoder = new BASE64Encoder();
String base64str = base64Encoder.encode(data);
System.out.println(base64str);
StringBuffer stringBuffer = new StringBuffer(base64str);
stringBuffer.insert(0, "data:img/jpg;base64,");
System.out.println(stringBuffer);
this.pictureBase64 = stringBuffer.toString();
}
return "success";
}
}
上传和显示图片视图页面
Test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<img src="<s:property value="pictureBase64" />" width="200px" height="150px">
<s:form action="ConvertPicture" method="POST" enctype="multipart/form-data">
<input type="file" name="pictureFile">
<input type="submit" value="submit">
</s:form>
</body>
</html>
使用效果
进入 http://localhost:8080/BBS/pb
选择文件——>点击submit
Struts2返回Json对象和Json数组的方案
方案一:使用 struts-json-plugin 库
只需要添加依赖然后在Action类里使用相应注解就可以实现restful api 风格的数据了。
gradle添加依赖
compile group: 'org.apache.struts', name: 'struts2-json-plugin', version: '2.5.16'
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.56'
action配置
struts2-json-plugin 可以返回单个对象或者是集合;比如
JSONObject、JSONArray
在使用时主要有三个点:
在action类前加 @ParentPackage(value=“json-default”)
在@Action注解里results参数里 type = “json”, params = {“root”, “resultJsonObj”}) 无论是单个对象还是集合数组都用 type = “json” 。而params需要指定为 {“root”,“类字段”} 后面的参数为类字段必须有get set 方法。
@ParentPackage(value="json-default")
public class CommonController extends ActionSupport {
// 要返回的Json对象,params参数与变量名一致
private JSONObject resultJsonObj = new JSONObject();
private JSONArray resultJsonArray = new JSONArray();
public JSONArray getResultJsonArray() {
return resultJsonArray;
}
public void setResultJsonArray(JSONArray resultJsonArray) {
this.resultJsonArray = resultJsonArray;
}
public JSONObject getResultJsonObj() {
return resultJsonObj;
}
public void setResultJsonObj(JSONObject resultJsonObj) {
this.resultJsonObj = resultJsonObj;
}
@Action(value="GetLocalHostIp" , results = {@Result(name = "success" , type = "json", params = {"root", "resultJsonObj"})})
public String getLocalHostIpProc(){
String url = null;
try {
url = Inet4Address.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
url = "http://" + url + ":8080";
resultJsonObj.put("text", url);
return "success";
}
@Action(value="listAllDirs" , results = {@Result(name="success" , type = "json" , params = {"root" , "resultJsonArray"})})
public String listAllDirsProc(){
List<RootDir> rootDirList= ... ;
List<SecondDir> secondDirList= ...;
List<ThirdDir> thirdDirList= ...;
JSONArray rootdirjsons=new JSONArray();
JSONArray seconddirjsons=new JSONArray();
JSONArray thirddirjsons=new JSONArray();
rootDirList.forEach((i)->{
JSONObject resultOne=new JSONObject();
resultOne.put("rootDirId",i.getRootDirId().toString());
resultOne.put("rootDirName", i.getRootDirName().toString());
rootdirjsons.add(resultOne);
});
secondDirList.forEach((i)->{
JSONObject resultOne=new JSONObject();
resultOne.put("rootDirId",i.getRootDirId().toString());
resultOne.put("secondDirId",i.getSecondDirId().toString());
resultOne.put("secondDirName", i.getSecondDirName().toString());
seconddirjsons.add(resultOne);
});
thirdDirList.forEach((i)->{
JSONObject resultOne=new JSONObject();
resultOne.put("secondDirId",i.getSecondDirId().toString());
resultOne.put("thirdDirId",i.getThirdDirId().toString());
resultOne.put("thirdDirName", i.getThirdDirName().toString());
thirddirjsons.add(resultOne);
});
resultJsonArray.add(rootdirjsons);
resultJsonArray.add(seconddirjsons);
resultJsonArray.add(thirddirjsons);
return "success";
}
}
测试结果OK
单个Json
Json数组
第二种方案,借助输出流,来向请求响应一个json格式的数据。
Object out = new String();
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("application/json;charset=utf-8");
writer = response.getWriter();
response.setDateHeader("Expires", 0);
JSONObject.toJSON(out);
writer.write(object.toString());
writer.flush();
建议:在restful需求比较少的情况下使用第二种方案,有一定量的restful需要还是用struts-json-plugin方便。