Why Struts1 ajax ActionForm values all null - ajax

In Struts1 project I'm trying to send ajax,
the chrome request payload is fine{"account":"abcd","pwd":"1234"}
but in debugMode the actionForm's values all null.
the ajax area:
function loging() {
alert(getFormData());
$.ajax({
url : '${pageContext.request.contextPath}/hello.do?method=jsonHi',
type : 'POST',
data : getFormData(),
contentType : 'application/json',
dataType : 'json',
async:false,
success : function(data) {
alert("success");
},
error : function() {
alert("error!");
}
});
}
function getFormData() {
return JSON.stringify({
'account' : $("#account").val(),
'pwd' : $("#pwd").val()
});
};
the struts-config area:
<struts-config>
<form-beans>
<form-bean name="formClass" type="com.pete.form.AccountForm" />
</form-beans>
<action-mappings>
<action name="formClass" path="/hello" parameter="method" type="com.pete.action.HelloAction" scope="request" validate="false">
<forward name="helloUser" path="/WEB-INF/pages/hello.jsp" />
<forward name="jsonHi" path="/WEB-INF/pages/afterAjax.jsp"/>
</action>
</action-mappings>
the form area:
public class AccountForm extends ActionForm{
private static final long serialVersionUID = -7462505002509046403L;
private String account = null;
private String pwd= null;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
teh Action area:
public class HelloAction extends DispatchAction {
public ActionForward jsonHi(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
AccountForm reqForm = (AccountForm) form;
System.out.println(reqForm.getAccount());//console is null
System.out.println(reqForm.getPwd());// console is null
return null;
}
}
I don't know what happen the form's values is null

I found the question is My ajax is not a form submit,If I want get value
I have to use HttpServletRequest getReader()

Related

springmvc converter doesnot work

I need convert string to enum. I wish I could post a String parameter ,and receive as an enum, but I got a 415 error.Here is my code
Email.java
public class Email {
private String address;
private String subject;
private String content;
private ServiceType service;
public enum ServiceType {
Feedback, PrivatePolicy, TermsOfUse, MotionDetection;
public static ServiceType get(String type) {
for (ServiceType servicetype : values()) {
if (servicetype.toString().equals(type)) {
return servicetype;
}
}
return null;
}
}
}
StringToEnumConverter uesed to convert string to enum
#SuppressWarnings("rawtypes")
public class StringToEnumConverter implements ConverterFactory<String, Enum> {
#SuppressWarnings({ "unchecked" })
#Override
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
// TODO Auto-generated method stub
return new StringToEnum(targetType);
}
private class StringToEnum<T extends Enum> implements Converter<String, T> {
private final Class<T> enumType;
public StringToEnum(Class<T> enumType) {
this.enumType = enumType;
}
#SuppressWarnings("unchecked")
public T convert(String source) {
if (source.length() == 0) {
return null;
}
return (T) Enum.valueOf(this.enumType, source.trim());
}
}
}
xml inject the converter
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService"class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.xxx.xxx.utils.StringToEnumConverter" />
</set>
</property>
</bean>
front-end code
$(".test").click(function(){
$(".response-text").html("please wait....");
var postData = {
"address" : $(".email").val(),
"subject" : $(".subject").val(),
"content" : $(".content").val(),
"service" : $(".service").val()
}
var args = {
url: "XXX/emailService_v1.0",
contentType : "application/x-www-form-urlencoded;charset=UTF-8",
type: "post",
data: postData,
success : function(response, currentAjaxOptions){
var str = JSON.stringify(response);
$(".response-text").html(str);
}
}
$.xAjax(args);
});
controller
#RequestMapping(value = "/emailService_v1.0", method = RequestMethod.POST)
#ResponseBody
public JSONObject emailService(#Valid #RequestBody Email email,
BindingResult result) throws Exception {
System.out.println("come in....");
if (result.hasErrors()) {
return genResJsonFromError(result);
} else {
System.out.println(email.getAddress());
JSONObject resJson = emailService.sendEmail(email);
System.out.println(email.getService().toString());
return resJson;
}
}
I just found the StringToEnumConverter.java wan't invoked.
so it give me 415 Unsupported Media Type error.
Wish anyone can help me
Then I add
#Resource(name = "conversionService")
private ConversionService conversionService;
#InitBinder
public void initBinder(DataBinder binder) {
binder.setConversionService(conversionService);
}
in my controller, but it does not work either.

When using #response and #request for json, I meet with some problems

LoginController.java:
#Controller
#RequestMapping("/user")
public class LoginController {
#RequestMapping(value="receive", method=RequestMethod.POST, consumes="application/json")
#ResponseBody
public RegInfo receiveData(#RequestBody RegInfo info){//
System.out.println("come here");
System.out.println(info.getRealname());
return info;
}
}
register.xml:
$("#sub").click(function(){
var m = {
"realname": $("#real_name").val(),
"phonenumber": $("#phone_number").val()
};
$.ajax({
type:"POST",
url:"/demo/user/receive",
data:m,
dataType:"json",
contentType:"application/json; charset=utf-8",
async:false,
success:function(data){
alert("nihao");
},
erroe:function(data){
alert("保存失败 ")
}
})
});
RegInfo.java:
public class RegInfo {
private String realname;
private String phonenumber;
//private boolean sex;
public RegInfo(){
}
public void setRealname(String realname){
this.realname= realname;
}
public String getRealname(){
return realname;
}
public void setPhonenumber(String phonenumber){
this.phonenumber = phonenumber;
}
public String getPhonenumber(){
return phonenumber;
}
demo-servlet.xml:
<context:component-scan base-package="com.lhao.core"/>
<!-- 默认的注解映射的支持 -->
<mvc:annotation-driven/>
<context:annotation-config/>
I have imported jackson-annotations-2.1.4.jar, jackson-core-2.1.4.jar, jackson-databind-2.1.4.jar in the lib but I cannot see the print in the console and it shows "400 bad request" in Chrome. I have tried some ways but it does no effect.
You need to convert your javascript variable to json before sending the request to server. JSON.stringify() does the conversion. Based on the code given above, this should solve the issue. well hopefully.
$("#sub").click(function(){
var m = {
"realname": $("#real_name").val(),
"phonenumber": $("#phone_number").val()
};
$.ajax({
type:"POST",
url:"/demo/user/receive",
data:JSON.stringify(m),
dataType:"json",
contentType:"application/json; charset=utf-8",
async:false,
success:function(data){
alert("nihao");
},
erroe:function(data){
alert("保存失败 ")
}
})
});

After accepting data with #requestbody, I want to return message or realize webpage-jump

Controller:
#RequestMapping(value="receive", method=RequestMethod.POST, consumes="application/json")
#ResponseBody
public RegInfo receiveData(#RequestBody RegInfo info){
String reg_check = regInfoService.checkRegInfo(info);
......
}
RegInfo:
public class RegInfo {
private String account;
private String passwords;
private String realname;
private String phonenumber;
private String sex;
private String mailname;
.......}
register.jsp:
$("#sub").click(function(){
var m = {
"account": $("#_account").val(),
"passwords": $("#_pass").val(),
"realname": $("#real_name").val(),
"phonenumber": $("#phone_number").val(),
"sex": $("input:checked").val(),
"mailname": $("#mail_name").val()
};
$.ajax({
type:"POST",
async : false,
url:"/demo/user/receive",
dataType:"json",
contentType:"application/json; charset=utf-8",
data:JSON.stringify(m),
success:function(data){
alert("ok");
alert(data.realname);
},
erroe:function(data){
alert("保存失败 ")
}
})
});
Now I want to check RegInfo in the controller. If the result of check is legal, I want to jump to other webpage like login.jsp and if it is illegal, I want to return some message and show the message in register.jsp. How can I realize it?
complete Controller:
#Controller
#RequestMapping("/user")
public class LoginController {
#Autowired
private UserService userService;
#Autowired
private RegInfoService regInfoService;
#RequestMapping("/login")
public String homePage(){
return "user/login";
}
#RequestMapping("/loginin")
public String toLogin(#ModelAttribute("user")User user){
String u = userService.loginCheck(user);
System.out.println(u);
if(u == "success"){
return "user/success";
}
else{
return "user/login";
}
}
#RequestMapping("/register")
public String toRegister(){
return "user/register";
}
#RequestMapping("/success")
public String toSuccess(){
return "user/success";
}
#RequestMapping(value="receive", method=RequestMethod.POST, consumes="application/json")
#ResponseBody
public RegInfo receiveData(#RequestBody RegInfo info){
String reg_check = regInfoService.checkRegInfo(info);
System.out.println(reg_check);
System.out.println(info);
System.out.println(info.getRealname());
return info;
}
}
I want to jump to other webpage like login.jsp and if it is illegal, I
want to return some message and show the message in register.jsp. How
can I realize it?
Simple, in your AJAX success handler redirect with URL parameters like:
$.ajax({
type:"POST",
async : false,
url:"/demo/user/receive",
dataType:"json",
contentType:"application/json; charset=utf-8",
data:JSON.stringify(m),
success:function(data){
alert("ok");
alert(data.realname);
if (data.realname != undefined || data.realname!= null) {
window.location = '/login?realname=' + data.realname;
}
},
erroe:function(data){
alert("保存失败 ")
}
});
EDITS:
based on your comment the controller method will look like:
#Controller
#RequestMapping("/user")
public class LoginController {
#RequestMapping("/login")
public String homePage(Mode model, #RequestParam(value="realname",required=false)String realName){
if(realName!=null && (!realName.trim().isEmpty())){
model.addAttribute("regSuccessUser",realName);
}
return "user/login";
}
}
and redirect statement will look like:
window.location = '/user/login?realname=' + data.realname;
Note: URL start with contextPath to avoid 404 problems
I test as follows:
<input type="button" value="test" onClick="newpage()">
function newpage(){
window.location="/demo/user/login";}
then it jump to login.jsp successfully.In the ajax,it had run to "window.location" but didn't jump.It looks so strange.
Final solution:
error:
<input type="submit" id="sub" value="save" >
true:
<input type="button" id="sub" value="save" >
Form is submitted twice.

#ResourceMapping that accepts JSON from Ajax request

I'm searching how I can interprete a JSON parameter in my #ResourceMapping in Spring Portlet MVC. When I add #RequestBody, I got the message: #RequestBody is not supported... Really stuck on this one.
I have this:
View side:
<portlet:resourceURL var="getTest" id="ajaxTest" ></portlet:resourceURL>
<p>
<button onClick="executeAjaxTest();">Klik mij!</button>
<button onClick="$('#ajaxResponse').html('');">Klik mij!</button>
</p>
<p>
<h3>Hieronder het antwoord:</h3>
<h4 id="ajaxResponse"></h4>
</p>
<script>
function executeAjaxTest() {
var jsonObj = {
user: "Korneel",
password: "testpassword",
type: {
testParam: "test",
}
}
console.debug(JSON.stringify(jsonObj));
$.ajax({
dataType: "json",
contentType:"application/json",
mimeType: 'application/json',
url:"<%=getTest%>",
data:JSON.stringify(jsonObj),
success : function(data) {
$("#ajaxResponse").html(data['testString']);
}
});
}
</script>
Controller side:
#ResourceMapping(value="ajaxTest")
#ResponseBody
public void ajaxTestMethod(ResourceRequest request, ResourceResponse response) throws IOException, ParseException {
LOGGER.debug("ajax method");
JSONObject json = JSONFactoryUtil.createJSONObject();
json.put("testString", "Ik ben succesvol verstuurd geweest!");
response.getWriter().write(json.toString());
}
How can I use the spring magic to auto map this JSON data to my own model?
Note: It's Spring Portlet MVC, not regular Spring MVC..
#ResponseBody annotation is not supported out of the box in Spring MVC portlet framework, but you can implement #ResponseBody handling yourself.
We do it by implementing custom view type and model and view resolver.
Implement custom model and view resolver (ModelAndViewResolver), let's say JsonModelAndViewResolver.
In resolveModelAndView method, check whether controller method has #ResponseBody annotation (or more specific condition to identify JSON output - e.g. annotation + required supported mime type).
If yes, return your custom View implementation - let's say SingleObjectJson view (extending AbstractView).
Pass your to-be-serialized object to the view instance.
The view will serialize the object to JSON format and write it to the response (by using Jackson, Gson or other framework in renderMergedOutputModel method).
Register the new resolver as AnnotationMethodHandlerAdapter.customModelAndViewResolvers.
You need to build your json object like this:
var jsonObj = {
user: "Korneel",
password: "testpassword",
"type.testParam" : "test"
};
$.ajax({
dataType: "json",
contentType:"application/json",
mimeType: 'application/json',
url:"<%=getTest%>",
data:jsonObj,
success : function(data) {
$("#ajaxResponse").html(data['testString']);
}
});
In your Controller you should use the #ModelAttribute annotation:
#ModelAttribute(value = "jsonObj")
public JsonObjCommand obtenerJsonObjCommand() {
JsonObjCommand jsonObjCommand = new JsonObjCommand();
return jsonObjCommand;
}
#ResourceMapping(value = "ajaxTest")
public void ajaxTestMethod(
ResourceRequest request,
ResourceResponse response,
#ModelAttribute(value = "jsonObj") JsonObjCommand jsonObjCommand)
throws IOException, ParseException {
LOGGER.debug("USER: " + jsonObjCommand.getUser());
LOGGER.debug("Password: " + jsonObjCommand.getPassword());
LOGGER.debug("TestParam: " + jsonObjCommand.getType().getTestParam());
LOGGER.debug("ajax method");
JSONObject json = JSONFactoryUtil.createJSONObject();
json.put("testString", "Ik ben succesvol verstuurd geweest!");
response.getWriter().write(json.toString());
}
Don't forget your beans:
public class JsonObjCommand {
private String user;
private String password;
private TypeJson type;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public TypeJson getType() {
return type;
}
public void setType(TypeJson type) {
this.type = type;
}
}
public class TypeJson {
private String testParam;
public String getTestParam() {
return testParam;
}
public void setTestParam(String testParam) {
this.testParam = testParam;
}
}
According to the documentation, #RequestBody is only supported in Servlet environments, not Portlet environments (same for #ResponseBody). So it seems you can't use that functionality.

JSON Posting to Spring-MVC, Spring is not seeing the data

I am working on a project that the project is going to use Ajax to post JSON object to Springs-MVC. I been making a number of changes and I got it to the point where I dont get any more errors BUT I dont see the data that is getting POSTed to Spring in the object I need it in.
Here is my Spring Controller.
#RequestMapping(value="/AddUser.htm",method=RequestMethod.POST)
public #ResponseBody JsonResponse addUser(#ModelAttribute(value="user") User user, BindingResult result ){
JsonResponse res = new JsonResponse();
if(!result.hasErrors()){
res.setStatus("SUCCESS");
res.setResult(userList);
}else{
res.setStatus("FAIL");
res.setResult(result.getAllErrors());
}
return res;
}
I put a breakpoint in and my USER object never gets the data. next is a copy of my USER object:
public class User {
private String name = null;
private String education = null;
private List<String> nameList = null;
private List<String> educationList = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEducation() {
return education;
}
public void setEducation(String education) {
this.education = education;
}
public List<String> getNameList() {
return nameList;
}
public void setNameList(List<String> nameList) {
this.nameList = nameList;
}
public List<String> getEducationList() {
return educationList;
}
public void setEducationList(List<String> educationList) {
this.educationList = educationList;
}
and now for the javascript code that does the Ajax, JSON post:
function doAjaxPost() {
var inData = {};
inData.nameList = ['kurt','johnathan'];
inData.educationList = ['GSM','HardKnocks'];
htmlStr = JSON.stringify(inData);
alert(".ajax:" + htmlStr);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: contexPath + "/AddUser.htm",
data: inData,
dataType: "json",
error: function(data){
alert("fail");
},
success: function(data){
alert("success");
}
});
};
Please let me now if you can help?? I have to get this working ASAP... thanks
You also need to specify the header in your RequestMapping annotion found in your controller.
#RequestMapping(headers ={"Accept=application/json"}, value="/AddUser.htm", method=RequestMethod.POST)
Also, remove .htm in your URL path. htm is some kind of request type overide. Using .htm specifies the web server to handle the request as a classic html request. Using .json would specify to the webserver that the request expects to be handled as a json request.

Resources