Call Servlet doPost method from Managed bean - json

I have a servlet method where i need to pass a json object. This json object will be created in one of the managed bean(JSF). I just tried injecting the bean into the servlet to get the json object, but i am getting runtime exception, may be it is not possible that way. So i want to call the servlet from JSF bean. Any ideas how to call from the bean?
Servlet
private static final long serialVersionUID = 1L;
TopicController topicController;
TopicBean topicBean;
List<JsonTopicObj> jsonTopicList;
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException {
// here code for subscription
Meteor mateor = Meteor.build(req).addListener(
new MyAtmosphereResourceEventListener());
boolean isLongPolling = true;
if (mateor.transport() == LONG_POLLING) {
isLongPolling = true;
} else {
isLongPolling = false;
}
System.out.println(" Now in the Get method of Atmosphere");
// create the broadcaster for the particular topic
String topicId = "default"; // for all users right now
Broadcaster broadcaster = BroadcasterFactory.getDefault().lookup(
topicId, true);
//set that broeadcaster
mateor.setBroadcaster(broadcaster);
mateor = mateor.resumeOnBroadcast(isLongPolling);
mateor.suspend(-1);
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws IOException {}
JSF BEAN
#ManagedBean(name = "testController")
#RequestScoped
public void listAllTopics() {
JsonTopicObj jsonTopicObj;
StringWriter out = new StringWriter();
JsonFactory jfactory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper();
jsonTopicList = new ArrayList<JsonTopicObj>();
for (int i = 0; i < topicBean.getTopicVOArray().length; i++) {
jsonTopicObj = new JsonTopicObj();
......................
}
mapper.writeValue(out, jsonTopicList);
now i need to call the servlet dopost method and send "out.toString()"

Where is your first control? Does it go to managed bean and then servlet
and this bean is responsible for forwarding to the servlet? If it is so,
you can create the JSON object, get your request and response from FacesContext
and dispatch the request to the servlet.
FacesContext give your request and response and from that you can dispatch your
request.

Related

Extracting url parameters in java servlet from a request placed by action script code

I am having trouble passing data to my servlet code from a request placed from action script
Here is how my actionscript code looks
var variables:URLVariables = new URLVariables();
variables.sessionId = sessionId;
variables.userName = userName;
variables.allExtensions = allExtensions;
variables.redirectPath = redirectPath;
var urlRoute:URLRequest = new URLRequest(endPointUrl +"-standalone");
urlRoute.data = variables;
urlRoute.method = URLRequestMethod.POST;
navigateToURL(urlRoute, "_blank");
Java servlet code looks like this
public class StandaloneRedirectServlet extends HttpServlet {
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
//All of these are null
String sessionId = req.getParameter("sessionId");
String userName = req.getParameter("userName");
String allExtensions = req.getParameter("allExtensions");
String redirectPath = req.getParameter("redirectPath");
//Set cookie
//Redirect
resp.sendRedirect("http://www.google.com"); //This would redirect to redirectPath eventually. For testing, I am using google.com
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
I know for a fact that the URLVariables (sessionId, userName etc) are set to valid values from the action script side. But on the java side, I get all nulls when I extract the parameters. I am clearly not understanding the right way to pass parameters to my server end point and any help is appreciated.
Thank you

Spring MVC REST Handing Bad Url (404) by returning JSON

I am developing a REST service using SpringMVC, where I have #RequestMapping at class and method level.
This application is currently configured to return error-page jsp configured in web.xml.
<error-page>
<error-code>404</error-code>
<location>/resourceNotFound</location>
</error-page>
I however want to return custom JSON instead of this error page.
I am able to handle exception and return json for other exceptions, by writing this in controller, but not sure how and where to write the logic to return JSON when the url does not exist at all.
#ExceptionHandler(TypeMismatchException.class)
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ResponseBody
public ResponseEntity<String> handleTypeMismatchException(HttpServletRequest req, TypeMismatchException ex) {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8");
Locale locale = LocaleContextHolder.getLocale();
String errorMessage = messageSource.getMessage("error.patient.bad.request", null, locale);
errorMessage += ex.getValue();
String errorURL = req.getRequestURL().toString();
ErrorInfo errorInfo = new ErrorInfo(errorURL, errorMessage);
return new ResponseEntity<String>(errorInfo.toJson(), headers, HttpStatus.BAD_REQUEST);
}
I tried #ControllerAdvice, it works for other exception scenarios, but not when mapping is not avaialble,
#ControllerAdvice
public class RestExceptionProcessor {
#Autowired
private MessageSource messageSource;
#ExceptionHandler(HttpRequestMethodNotSupportedException.class)
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ResponseBody
public ResponseEntity<String> requestMethodNotSupported(HttpServletRequest req, HttpRequestMethodNotSupportedException ex) {
Locale locale = LocaleContextHolder.getLocale();
String errorMessage = messageSource.getMessage("error.patient.bad.id", null, locale);
String errorURL = req.getRequestURL().toString();
ErrorInfo errorInfo = new ErrorInfo(errorURL, errorMessage);
return new ResponseEntity<String>(errorInfo.toJson(), HttpStatus.BAD_REQUEST);
}
#ExceptionHandler(NoSuchRequestHandlingMethodException.class)
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ResponseBody
public ResponseEntity<String> requestHandlingMethodNotSupported(HttpServletRequest req, NoSuchRequestHandlingMethodException ex) {
Locale locale = LocaleContextHolder.getLocale();
String errorMessage = messageSource.getMessage("error.patient.bad.id", null, locale);
String errorURL = req.getRequestURL().toString();
ErrorInfo errorInfo = new ErrorInfo(errorURL, errorMessage);
return new ResponseEntity<String>(errorInfo.toJson(), HttpStatus.BAD_REQUEST);
}
}
After digging around DispatcherServlet and HttpServletBean.init() in SpringFramework I see that its possible in Spring 4.
org.springframework.web.servlet.DispatcherServlet
/** Throw a NoHandlerFoundException if no Handler was found to process this request? **/
private boolean throwExceptionIfNoHandlerFound = false;
protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (pageNotFoundLogger.isWarnEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + requestUri +
"] in DispatcherServlet with name '" + getServletName() + "'");
}
if(throwExceptionIfNoHandlerFound) {
ServletServerHttpRequest req = new ServletServerHttpRequest(request);
throw new NoHandlerFoundException(req.getMethod().name(),
req.getServletRequest().getRequestURI(),req.getHeaders());
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
throwExceptionIfNoHandlerFound is false by default and we should enable that in web.xml
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
And then you can catch it in a class annotated with #ControllerAdvice using this method.
#ExceptionHandler(NoHandlerFoundException.class)
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ResponseBody
public ResponseEntity<String> requestHandlingNoHandlerFound(HttpServletRequest req, NoHandlerFoundException ex) {
Locale locale = LocaleContextHolder.getLocale();
String errorMessage = messageSource.getMessage("error.bad.url", null, locale);
String errorURL = req.getRequestURL().toString();
ErrorInfo errorInfo = new ErrorInfo(errorURL, errorMessage);
return new ResponseEntity<String>(errorInfo.toJson(), HttpStatus.BAD_REQUEST);
}
Which allows me to return JSON response for bad URLs for which no mapping exist, instead of redirecting to a JSP page :)
{"message":"URL does not exist","url":"http://localhost:8080/service/patientssd"}
If you are using Spring Boot, set BOTH of these two properties:
spring.resources.add-mappings=false
spring.mvc.throw-exception-if-no-handler-found=true
Now your #ControllerAdvice annotated class can handle the "NoHandlerFoundException", as below.
#ControllerAdvice
#RequestMapping(produces = "application/json")
#ResponseBody
public class RestControllerAdvice {
#ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<Map<String, Object>> unhandledPath(final NoHandlerFoundException e) {
Map<String, Object> errorInfo = new LinkedHashMap<>();
errorInfo.put("timestamp", new Date());
errorInfo.put("httpCode", HttpStatus.NOT_FOUND.value());
errorInfo.put("httpStatus", HttpStatus.NOT_FOUND.getReasonPhrase());
errorInfo.put("errorMessage", e.getMessage());
return new ResponseEntity<Map<String, Object>>(errorInfo, HttpStatus.NOT_FOUND);
}
}
note it is not sufficient to only specify this property:
spring.mvc.throw-exception-if-no-handler-found=true
, as by default Spring maps unknown urls to /**, so there really never is "no handler found".
To disable the unknown url mapping to /**, you need
spring.resources.add-mappings=false ,
which is why the two properties together produce the desired behavior.
If you're using spring 3.2 or later you can use a controller advice (#ControllerAdvice) to deal with, amongst other things, mapping errors (404's). You can find documentation here. Take a look at section 17.11. You can use this, for example, to provide more detailed logging on why your request bindings aren't being matched for specific urls, or to simply return a more specific response than a generic 404.
you can return json in the location below,that /handle/404.
<error-page>
<error-code>404</error-code>
<location>/handle/404</location>
</error-page>
after you config this in web.xml,a 404 error will redirect to /handle/404,and you can create a controller with this mapping and return a json result. for example.
#RestController
#RequestMapping(value = "handle")
public class HttpErrorController {
#RequestMapping(value = "404")
public String handle404() {
return "404 error";
}
}

How to return JSON object in resolveException method of HandlerExceptionResolver in Spring MVC?

While implementing a File Uploader controller in Spring MVC I stucked with one problem. My code snap is given below.
#Controller
public class FileUploader extends AbstractBaseController implements HandlerExceptionResolver
{
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
#ResponseBody
public JSONObject handleFileUpload(#RequestParam("file") MultipartFile file)
{
JSONObject returnObj = new JSONObject();
if (file.isEmpty())
{
returnObj.put("success", "false");
returnObj.put("message", "File is empty");
}
else
{
try
{
//my file upload logic goes here
}
catch (Exception e)
{
returnObj.put("success", "false");
returnObj.put("message", "File not uploaded.");
}
}
return returnObj;
}
#Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object obj, Exception exception)
{
ModelAndView model = new ModelAndView();
Map map = new HashMap();
if (exception instanceof MaxUploadSizeExceededException)
{
// I want to return JSONObject from here like given below.
/**
* { "message":"File size exceeded", "success":"false" }
* */
map.put("message", "File size exceeded");
map.put("success", "false");
model.addObject(map);
}
return model;
}
}
and my spring configuration look likes
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
<property name="maxUploadSize" value="300000"/>
</bean>
now In my controller I want to return JSONObject instead of ModelAndView in resolveException method in my controller as given in code snap because I am developing some like REST method to upload file.
any ideas?
Thanks
If you use the Spring 3.2 above, I recommend this way.
At first, declare the ControllerAdvice.
#Controller
#ControllerAdvice
public class JAttachfileApi extends BaseApi
And make the Exception Handler to response JSON Object as following.
#ExceptionHandler(MaxUploadSizeExceededException.class)
public #ResponseBody Map<String,Object> handleMaxUploadSizeExceededException(
MaxUploadSizeExceededException ex)
{
Map<String,Object> result = getResult();
JFileUploadJsonResponse errorResult = new JFileUploadJsonResponse();
errorResult.setError("Maximum upload size of "+ex.getMaxUploadSize()+" bytes exceeded.");
List<JFileUploadJsonResponse> resultData = new ArrayList<JFileUploadJsonResponse>();
resultData.add(errorResult);
result.put("files", resultData);
return result;
}
You simply can annotate the method resolveException as #ExceptionHandler() and then you can have its signature like any other controller method. So placing #ResponseBody before the return type should work.
"Much like standard controller methods annotated with a #RequestMapping annotation, the method arguments and return values of #ExceptionHandler methods can be flexible. For example, the HttpServletRequest can be accessed in Servlet environments and the PortletRequest in Portlet environments. The return type can be a String, which is interpreted as a view name, a ModelAndView object, a ResponseEntity, or you can also add the #ResponseBody to have the method return value converted with message converters and written to the response stream."

Need help on RestTemplate postForObject() method

I have to send JSON data from one service method to the other using postForObject() method.
I saw one example on RestTemplate on this link.
postForObject() method has the following format:
User returns = rt.postForObject(uri, u, User.class, vars);
Or
User returns = rt.postForObject(uri, u, User.class);
I want to know that, after using postForObject() method, if we implement the service method to accept the User object, how it will look like?
In my project, I have code like
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
String uri = "http://testcode.com/myapp/api/launchservices";
ServiceRequest request = new ServiceRequest();
request.setId(UUID.randomUUID().toString());
....
I am getting error at this line:
ServiceRequest req = restTemplate.postForObject(uri, request, ServiceRequest.class);
while executing this, I am getting this error mesage:
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:88)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:537)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:493)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:452)
at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:302)
my implementation method is:
#RequestMapping(value = "/launchservices", method = RequestMethod.POST)
#ResponseBody
public boolean launchServices(#PathVariable ServiceRequest request) {
System.out.println("Request: "+request.toString());
return true;
}
How to get rid of this? What will be the URI?
I got solution to this problem.
In this example,method postForObject returns an object of class "ServiceRequest"
ServiceRequest req = restTemplate.postForObject(uri, request, ServiceRequest.class);
So, the method that implements this service with the above 'uri' should return an object of class ServiceRequest
All it needs is, slight modification in implementation method as below
#RequestMapping(value = "/launchservices", method = RequestMethod.POST, headers = "Accept=application/json")
#ResponseBody
public ServiceRequest launchServices(#RequestBody ServiceRequest request) {
System.out.println("Request: "+request.toString());
return request;
}

Uncaught exception from servlet - JSON GAE deployment issue

I have created a script on browser that calls a servlet which is deployed on GAE. The servlet uses Datastore.
Everytime servlet is called I receive the following error
Uncaught exception from servlet java.lang.NoClassDefFoundError: org/json/JSONException
For development I use eclipse and Maven.
In pom.xml I have already included org.json 20090211 and javax.validation.
UPDATE
In order to better clarify my question I am posting code from servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
StringBuilder sb = new StringBuilder();
BufferedReader br = request.getReader();
String str;
while ((str = br.readLine()) != null)
{
sb.append(str);
}
String jsonResp = sb.toString();
JSONParser gparser = new JSONParser();
The problem appears on the last line, so I am posting code from JSONParser
public class JSONParser {
public ArrayList<String> ReturnGoogleJSON(String ResponseString) throws IOException {
ArrayList<String> Row = new ArrayList<String>();
try {
JSONObject rootObject = new JSONObject(ResponseString); // Parse the JSON to a JSONObject
JSONArray rows = rootObject.getJSONArray("items") ; // Get all JSONArray rows
for(int i=0; i < rows.length(); i++) { // Loop over each each row
JSONObject element = rows.getJSONObject(i); // Get the element object
Row.add(element.getString("tag"));
Row.add(element.getString("link"));
Row.add(element.getString("priority"));
}
} catch (JSONException e) {
e.printStackTrace();
}
return Row;
}
}
Could anyone help me with this kind of error?
Thank you in advance.
Check war/WEB-INF/lib directory of your project in eclipse before upload and make sure that json and other dependent files are present in this directory.
Edit:
You may want to check:
GAE - ClassNotFoundException after deployment to Appspot server
http://javanto.com/blog/2012/01/11/gae-eclipse-maven-2-0/