I have a small project at my university. I would like to use a REST webserver (on GlassFish) with Jersey.
I tried replace the MOXy to Jackson but I could not do that.
I have a modell class and it is contains few variable. The output is correct JSON or XML. But I want to put Transient annotation to some variable.
The javax.xml.bind.annotation.XmlTransien annotation is not working. I see the variable in the output response.
Here is my modell class:
public class Xyz {
private String a = "value";
private int b = 3;
#XmlTransient
private List<int> list = new LinkedList<>();
// get, set ..
}
And my service class is:
#Path("myresource")
public class MyResource {
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getIt() {
return "Got it!";
}
#GET
#Produces("application/json")
#Path("/json")
public Response getJSON() {
return Response.ok(new Xyz()).build();
}
#GET
#Produces("application/xml")
#Path("/xml")
public Response getXML() {
return Response.ok(new Xyz()).build();
}
}
The web.xml:
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.example</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.moxy.json.MoxyFeature</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
Where is the problem? Or how to replace with Jackson? I want to use GlassFish.
Thank you very much!
Related
I'm following the demo in https://www.javatpoint.com/spring-mvc-tutorial. After running the demo on the tomcat server,I visited the url "http://localhost:8080/webTest1_war_exploded/",it seems the request is not handled by springmvc controller.
web.xml:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Here is the controller code:
#Controller
public class HelloController {
public HelloController() {
}
#RequestMapping({"/"})
public String display() {
System.out.println("yes");
return "index";
}
}
after I visited the url: "http://localhost:8080/webTest1_war_exploded/", the console does not print "yes".
Can someone explain it to me?
Just try to replace
#RequestMapping({"/"})
with
#RequestMapping("/")
I am learning how to use Restful Webservice, i dont really know if my approach is good or totally wrong, so bear with me
I got a project structure, which look like this :
I want to by calling the right URL, save the string accordingly in Datum.Json
Here is my Java Class of the WebService :
package Rest;
#Path("/calendar")
public class CalendarTest {
public List<Date> dates;
#GET
#Path("/dates/get/")
#Produces(MediaType.APPLICATION_XML)
public List<Date> getUsers(){
return dates;
}
#PUT
#Path("/dates/put/{param1}+{param2}")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public void updateDate(#PathParam("param1") String city, #PathParam("param2") String date) throws IOException {
JSONObject obj = new JSONObject();
obj.put("City", city);
obj.put("Date", date);
try (FileWriter file = new FileWriter("/RestTest/Datum.json")) {
file.write(obj.toJSONString());
System.out.println("Successfully Copied JSON Object to File...");
System.out.println("\nJSON Object: " + obj);
}
}
}
I tested the localhost, it works fine (i can open the form.html with my localhost)
My web.xml file :
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Restful Web Application</display-name>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>Rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<security-constraint>
</security-constraint>
</web-app>
But when i tried the URL http://localhost:8080/RestTest/rest/calendar/dates/put/Berlin+20-12-2019
It says the method not allowed.
Can anyone explain to me why ?
It's because when you are typing in a URL in your browser, it sends a HTTP GET request by default, so it throws an error because you do not have a GET request handler for that URL, you only have a handler for a PUT request.
You can't change the browser's default request type. What you have to do is send the request yourself using something like jQuery in your frontend / javascript.
How to send a PUT/DELETE request in jQuery?
You could use the ajax method:
$.ajax({
url: '/rest/calendar/dates/put/Berlin+20-12-2019',
type: 'PUT',
success: function(result) {
// Do something with the result
}
});
Is there any way to configure Jackson (ConfiguredObjectMapper) which is used for serializing servlet responses?
#Api(name = "rates",
version = "v1",
title = "Rates API")
public class RatesApi {
static Logger LOG = Logger.getLogger(RatesApi.class.getSimpleName());
#ApiMethod(name = "getLatestRates",
path = "latest",
httpMethod = HttpMethod.GET)
public RatesEnvelope getLatestRates(#Named("base") String base) throws BadRequestException,
InternalServerErrorException {
try {
RatesInfo ratesInfo = DatabaseUtils.getLatestRates(base);
return new RatesEnvelope(ratesInfo.getDate(), base, ratesInfo.getTimestamp(), ratesInfo.getRates());
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage());
} catch (com.googlecode.objectify.NotFoundException e) {
throw new InternalServerErrorException("no available rates");
}
}
}
My problem is RatesEnvelope class contains BigDecimal fields which should be configured with mapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN); to avoid E notation.
web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>CurrencyWebserviceServlet</servlet-name>
<servlet-class>PACKAGE_NAME.backend.servlet.OpenExchangeRatesWebserviceServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>PACKAGE_NAME.backend.spi.RatesApi</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>CurrencyWebserviceServlet</servlet-name>
<url-pattern>/cron/fetchlatest</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<security-constraint>
<web-resource-collection>
<web-resource-name>all</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
<!-- Next three lines are for request dispatcher actions -->
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
</web-app>
Create an instance of Jackson ObjectMapper. Configure as needed by enabling or disabling features you need. Modify your Spring configuration to use it instead of default one. Java configuration would look something like this:
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN);
converter.setObjectMapper(objectMapper);
converters.add(converter);
super.configureMessageConverters(converters);
}
It looks like you're using Cloud Endpoints Frameworks, which doesn't use Jackson annotations. In your case, you'd use an ApiTransformer to achieve what you want. As an example:
#ApiTransformer(RatesEnvelopeTransformer.class)
public class RatesEnvelope {
private BigDecimal someBigDecimalField;
// ...
}
public class RatesEnvelopeTransformer implements Transformer<BigDecimal, String> {
public String transformTo(BigDecimal in) {
return in.toPlainString();
}
public BigDecimal transformFrom(String in) {
return new BigDecimal(in);
}
}
I am using jersey 2.7
I want output as "{\"result\":1}"
I am getting output as {result:1}
I am using org.glassfish.jersey.media:jersey-media-moxy and have added in web.xml
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
<param-value>org.glassfish.jersey.moxy.json.MoxyFeature</param-value>
</init-param>
In rest controller
#POST
#Path("/start")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response start()
{
com.google.gson.JsonObject jsonObject=new JsonObject();
jsonObject.addProperty("result",1);
return Response.status(200).entity(jsonObject.toString()).build();
}
I am trying to create and Rest API with Spring MVC that consumes JSON:
Controller:
#RestController public class CrawlerController {
#RequestMapping(value = "/checkForMarfeelizableSite", method = RequestMethod.POST)
public ResponseR checkForMarfeelizableSites(#RequestBody List<Entry> list) {
// Response
ResponseR responseR = new ResponseR();
responseR.setOperationResult(OperationResult.OK);
for (Entry entry : list) {
System.out.println("Entry: " + entry);
}
return responseR;
} }
Entry.class
public class Entry {
String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}}
web.xml:
<web-app>
<display-name>Marfeel Marfeelizable Checker</display-name>
<!-- Spring Context -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/marfeel-context.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Servlet -->
<servlet>
<servlet-name>marfeel-crawler-api</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Mapping -->
<servlet-mapping>
<servlet-name>marfeel-crawler-api</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Welcome file List -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
I've added the Jackson lib (jackson-mapper-asl) in my pom.xml, but I'm receiving a HTTP 415 Error
This is a sample of json that I'm sending:
[{"url": "canda.com"},{"url": "toshiba.es"}]
could you check the followings?
Change
public ResponseR checkForMarfeelizableSites(#RequestBody List
list)
to
public ResponseR checkForMarfeelizableSites(#RequestBody
ArrayList list)
(since List is an interface and therefore cannot create an instance).
Entry.class: add #XmlRootElement above the class name,and an empty contractor (required for web exportable classes)